FitNesse.NET tips and tricks

Download Report

Transcript FitNesse.NET tips and tricks

FitNesse.NET tips and tricks
Gojko Adzic
http://gojko.net
[email protected]
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
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
name not set
http://www.google.com false
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: 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));
}
}
We can now use it like this!
info.fitnesse.MemoryLinkRepository
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
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