34
FitNesse.NET tips and tricks Gojko Adzic http://gojko.net [email protected] http://twitter.com/ gojkoazic

FitNesse.NET tips and tricks Gojko Adzic [email protected]

Embed Size (px)

Citation preview

Page 1: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

FitNesse.NET tips and tricks

Gojko Adzichttp://gojko.net

[email protected]://twitter.com/gojkoazic

Page 2: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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.

Page 3: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

Simple Sample Domain

Page 4: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 5: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.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>

Page 6: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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(); } }

Page 7: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 8: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

System under test public class FlowSystemUnderTest : DoFixture { private ILinkRepository repo = new MemoryLinkRepository(); public FlowSystemUnderTest() { SetSystemUnderTest(repo); } public Fixture DefineLinks() { return new LinkSetupFixture(repo); }}

Page 9: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 10: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.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

Page 11: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 12: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

With Keyword

public class WithSystemUnderTest : DoFixture { public Fixture DefineLinks() { return new LinkSetupFixture((ILinkRepository) this.mySystemUnderTest); } }

Page 13: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

Naming SUTs

• |name|foo|with|… with phrase|

• |name|bar|with|… with phrase|

• |use|foo|

• …

• |use|bar|

Page 14: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 15: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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!

Page 16: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

Column fixture SUT

public class LinkValidityCheck:fit.ColumnFixture

{

public LinkValidityCheck()

{

SetSystemUnderTest(new Link());

}

public String comment;

}

Page 17: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 18: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 19: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 20: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.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));} }}

Page 21: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 22: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 23: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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()); } }

Page 24: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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!

Page 25: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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)); } }

Page 26: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 27: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 28: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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>

Page 29: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 30: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

We can write tests with no fixture code!

But “can” is not the same as “should”!

Page 31: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

FitNesse Pages tell us “what”

Fixtures tell us “how”

Page 32: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

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

Page 33: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

Upcoming events

• Games in the cloud: March 5th

• Next .NET event: March 23rd

• Web Tech Exchange: May 11-15

Page 34: FitNesse.NET tips and tricks Gojko Adzic  gojko@gojko.com

Where next?

• http://gojko.net

• http://www.syterra.com

• http://www.fitnesse.info