Upload
phillip-rich
View
223
Download
3
Tags:
Embed Size (px)
Citation preview
FitNesse.NET allows you to save lots of time by writing
fixture code efficiently and by not writing fixture code when
you don’t really need it.
Simple Sample Domain
Example: define + list links
Define Links
Name Url
Google http://www.google.com
Yahoo http://www.yahoo.com
List Links
Name Url
Google http://www.google.com
Yahoo http://www.yahoo.com
Automatic collection wrapping
• Instead of creating your own row/array fixtures, use a flow fixture and just return an array out from a method - it gets mapped to array fixture
• Works in do/sequence flow mode
• Works on IEnumerable<T>
Automatic collection wrapping public class FlowCollections: DoFixture { private ILinkRepository repo = new MemoryLinkRepository(); public Fixture DefineLinks() { return new LinkSetupFixture(repo); } public IEnumerable<Link> ListLinks() { return repo.FindAll(); } }
System under test
• If the call does not map to anything in the fixture, flow fixtures check a “system under test”
• Set the system under test and map domain service/repository/factory calls directly to tables
• Perhaps best on Sequence fixtures
System under test public class FlowSystemUnderTest : DoFixture { private ILinkRepository repo = new MemoryLinkRepository(); public FlowSystemUnderTest() { SetSystemUnderTest(repo); } public Fixture DefineLinks() { return new LinkSetupFixture(repo); }}
System under test
info.fitnesse.FlowSystemUnderTest
Define Links
Name Url
Google http://www.google.com
Yahoo http://www.yahoo.com
Find All
Name Url
Google http://www.google.com
Yahoo http://www.yahoo.com
With keyword
• Set the system under test from the test page
• |with|method call|
• |with|new|class name|
• |with|new|class name|constr arg1|arg2|…|
• Use this to switch between systems under test dynamically
With Keyword
info.fitnesse.WithSystemUnderTest
with new info.fitnesse.MemoryLinkRepository
Define Links
Name Url
Google http://www.google.com
Yahoo http://www.yahoo.com
Find All
Name Url
Google http://www.google.com
Yahoo http://www.yahoo.com
With Keyword
public class WithSystemUnderTest : DoFixture { public Fixture DefineLinks() { return new LinkSetupFixture((ILinkRepository) this.mySystemUnderTest); } }
Naming SUTs
• |name|foo|with|… with phrase|
• |name|bar|with|… with phrase|
• |use|foo|
• …
• |use|bar|
Naming SUTs
name google with new Link Google http://www.google.com
name yahoo with new Link Yahoo http://www.yahoo.com
use google
check valid true
use yahoo
check valid true
System under test in other fixtures
• From recently, you can use system under test for other fixtures as well!
• Eg for a column fixture as a much more flexible target object!
• Allows you to define only test-specific methods in fixtures!
Column fixture SUT
public class LinkValidityCheck:fit.ColumnFixture
{
public LinkValidityCheck()
{
SetSystemUnderTest(new Link());
}
public String comment;
}
Column fixture SUT
Link validity check
name url valid? comment
google http://www.google.com true both set, correct
blank http://www.google.com false name not set
google blank false url not set
google www.google.com false url not in correct format
Alternating system under test
• Switch SUT in runtime to load up other objects
• Use Reset() to clean up before new row
• This is a very efficient way to implement a subset fixture for huge data sets
Alternating SUT
Define Links
Name Url Id?
Google http://www.google.com >>google
Yahoo http://www.yahoo.com >>yahoo
Microsoft http://www.microsoft.com >>msft
Check Links
Id Name? Url?
<<google Google http://www.google.com
Alternating SUT
public class LinkCheckFixture : ColumnFixture{ private ILinkRepository repo; public LinkCheckFixture(ILinkRepository repo) { this.repo = repo; } public int Id { set { SetSystemUnderTest(repo.FindById(value));} }}
Automatic domain object wrapping
• Don’t use a fixture – use your domain class in the table header
• FitNesse.NET automatically creates a DoFixture and sets the system under test to a new instance of your class
Cell Handlers
• Tell FitNesse how to interpret a set of cells– Match by cell content– Match by object type
• Extend AbstractCellHandler• Load by using
Cell Handler Loader
load SavedFixtureHandler FitLibrary
load SavedFixtureHandler Fit
Example: Regexpublic class RegExHandler: AbstractCellHandler { public override bool Match(string searchString, System.Type type) { return searchString.StartsWith("/") && searchString.EndsWith("/") && typeof(string).Equals(type); } public override bool HandleEvaluate(Fixture fixture, Parse cell, Accessor accessor) { object actualValue=accessor.Get(fixture); if (actualValue == null) return false; Regex expected =new Regex(cell.Text.Substring(1,cell.Text.Length-2)); return expected.IsMatch(actualValue.ToString()); } }
Regex to the rescue
• Named SUTs can’t be used as parameters– This isn’t possible:– |name|google|with|new|…|– |save|google|
• But that would be really cool!
• So let’s implement it using a cell handler!
Saved fixture handler public class SavedFixtureHandler:AbstractCellHandler { public override bool Match(string searchString, System.Type type) { return searchString.StartsWith("\"") && searchString.EndsWith("\""); } public override void HandleInput(Fixture fixture, Parse cell, Accessor
accessor) { String innerText=cell.Text.Substring(1, cell.Text.Length-2); accessor.Set(fixture,
((FlowFixtureBase) fixture).NamedFixture(innerText)); } }
We can now use it like this!
name google with new Link Google http://www.google.com
name yahoo with new Link Yahoo http://www.yahoo.com
save "google"
save "yahoo"
find all
name url
Google http://www.google.com
Yahoo http://www.yahoo.com
info.fitnesse.MemoryLinkRepository
Suite config files
• Extract all technical information into a file
• Keep test pages nice and tidy, easily readable
• Set up with !define COMMAND_PATTERN=%m –c mySuite.config %p
• See all options on http://syterra.com/FitnesseDotNet/SuiteConfigurationFile.html
Suite config files<suiteConfig> <fit.Assemblies> <add>D:\work\netfit2\fixtures\fixtures\bin\debug\fixtures.dll</add> </fit.Assemblies> <fit.Namespaces> <add>info.fitnesse</add> </fit.Namespaces> <fit.CellHandlers> <add>info.fitnesse.SavedFixtureHandler</add> </fit.CellHandlers> <fitlibrary.CellHandlers> <add>info.fitnesse.SavedFixtureHandler</add> </fitlibrary.CellHandlers></suiteConfig>
Now we can do this!
Memory Link Repository
name google with new Link Google http://www.google.com
name yahoo with new Link Yahoo http://www.yahoo.com
save "google"
save "yahoo"
find all
name url
Google http://www.google.com
Yahoo http://www.yahoo.com
We can write tests with no fixture code!
But “can” is not the same as “should”!
FitNesse Pages tell us “what”
Fixtures tell us “how”
Bridging the Communication Gap
• learn how to improve communication between business people and software implementation teams
• find out how to build a shared and consistent understanding of the domain in your team
• learn how to apply agile acceptance testing to produce software genuinely fit for purpose
• discover how agile acceptance testing affects your work whether you are a programmer, business analyst or a tester
• learn how to build in quality into software projects from the start, rather than control it later
http://www.acceptancetesting.info
Upcoming events
• Games in the cloud: March 5th
• Next .NET event: March 23rd
• Web Tech Exchange: May 11-15
Where next?
• http://gojko.net
• http://www.syterra.com
• http://www.fitnesse.info