340 likes | 723 Views
FitNesse.NET tips and tricks. Gojko Adzic http://gojko.net gojko@gojko.com http://twitter.com/gojkoazic. 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.
E N D
FitNesse.NET tips and tricks Gojko Adzic http://gojko.net gojko@gojko.com http://twitter.com/gojkoazic
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.
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); } }
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 public class WithSystemUnderTest : DoFixture { public Fixture DefineLinks() { return newLinkSetupFixture((ILinkRepository) this.mySystemUnderTest); } }
Naming SUTs • |name|foo|with|… with phrase| • |name|bar|with|… with phrase| • |use|foo| • … • |use|bar|
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; }
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 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
Example: Regex public 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)); } }
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>
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