Preface to the second edition
What's new in this version?
Training and consultancy
Acknowledgements
About the author
I. Getting started
1. Introduction
Who should read this book?
Why bother with TDD?
Quality from the start
Early interface validation
Divide and conquer
Safety net for the code
Confidence = Productivity
Light at the end of the tunnel
Beyond unit tests
Getting FIT
How does FitNesse help?
FitNesse or NUnit?
Quick basic tests: use NUnit
Manageable larger tests: use FitNesse
Not a silver bullet
The next step
2. Installing FitNesse
Setting up FitNesse
A quick test
How FitNesse connects to .NET classes
Don't forget the test
FitNesse is very strict about the page names
Playtime
II. FitNesse and TDD in practice
3. Our Project
Lottery rules
Selected user stories
Applying TDD to our project
Guiding the development
Automated acceptance testing
Testing to prevent defects, not to find them
The next step
4. Writing basic tests
ColumnFixture — the Swiss Army knife of FitNesse
Testing in plain English
Use names that are easy to read – FitNesse will find the correct .NET equivalent
Import namespaces and clean up table headers
Replace repetitive values with arguments
Talk to the customer
Use comments to describe tables
Use .NET formatting to make values easier to read
Customer-friendly table
Playtime
5. Writing simple test scripts
Passing values between tables
Use setup fixtures to store static context
Use symbols to pass dynamic information
Writing a simple test script
Use data-transfer objects directly
Using symbols to check dynamic values
Checking for errors
Playtime
6. Writing efficient test scripts
Better test scripts with DoFixture
Writing the story in a test table
Use DoFixture keywords for better control
Keep ActionFixture in mind
Playtime
7. Removing duplication
Group related tests into test suites
Include pages and use them as components
Links within a subwiki
Reuse entire suites with symbolic links
Use markup variables to parameterise test pages
Defining common actions
Remove irrelevant information
Acceptance tests should focus on business rules
Hide parts of the page
Playtime
8. Coordinating fixtures
Embed fixtures for best results
Settlement tests in flow mode
Use SetUpFixture to prepare the stage for tests
Create test suites in flow mode
Wrapping business objects with DoFixture
Playtime
9. Working with collections
Testing lists of objects
Checking for empty collections
Beware of test extensions
Use RowFixture for better precision
Playtime
III. Advanced FitNesse usage
10. Working in a team
Options for team setup
Using a single central server
Importing tests from a remote wiki
Storing tests in a version control system
Organising the files
Don't mix quick and slow tests
Separate code-oriented and customer-oriented tests
Start with a fresh wiki
Configure FitNesse to run .NET tests by default
Integrating with automated build tools
Using TestRunner
Running tests with NAnt
Integrating FitNesse with CruiseControl.NET
Scheduling tests and alerts
11. Testing web interfaces
Choosing the right thing to test
Workflow and session control
Face-saving tests
Test a key business workflow
Introducing Selenium
Setting up Selenium and Remote Control
A quick Selenium example
Using ISelenium
Connecting from FitNesse
Starting and stopping the browser
Simulating client interaction
Inspecting results
Completing the test
Running tests on a remote server
More Selenium tests
12. Testing database code
Connecting to the database
Connecting in flow mode
Connecting in standalone mode
Transaction management
Working with stored procedures
Preparing test data
Executing statements
Verifying query results
Other DbFit features
13. Testing legacy code
Covering legacy code with tests
Use blank cells to print out results
Use show and check with FitLibrary
Wrap existing objects for tests
Use ArrayFixture and RowFixture to capture data batches
Using existing forms for regression tables
14. Using business domain objects directly
System under test with ColumnFixtures
Changing the system under test
Using collections directly
Setting the system under test from FitNesse
Using named fixtures
Don't go too far
15. Tips and tricks
What really happens during a test?
The parse tree
Executing tables
Binding columns to class members
Cell operators
Handling data types
Attaching the Visual Studio debugger
When in doubt, just print to the console
Load non-standard cell operators for simpler comparisons
Simplify verifications with a custom cell operator
Avoid conversions by supporting custom data types
Implement domain-specific tests using custom fixtures
IV. Appendices
A. Formatting text
B. Test smells
C. Resources
Books
Web sites
Main FitNesse site
FitSharp
FitSharp GIT repository
FitNesse Yahoo group
FitNesse.Info community site
UK Agile testing community
Acceptance Testing Info portal
Examples from Fit for Developing Software [3] ported to .NET
FitLibrary homepage
FIT web site
Blogs with good articles on FitNesse and FitSharp
The Quest For Software++
Cory Foy
The Shade Tree Developer
Ruslan Trifonov
Google testing blog
Test-obsessed
Successful Software
Articles
Martin Fowler: Continous Integration
James Carr: TDD Anti-Patterns
Michael Feathers: A Set of Unit Testing Rules
Michael Feathers: Working Effectively With Legacy Code
John R. Grout, and Brian T. Downs: A Brief Tutorial on Mistake-proofing, Poka-Yoke, and ZQC
Robert C. Martin: Three rules of TDD
Michael Feathers: Pitching a FIT
Sean Shubin: Test First Guidelines
Dan North: Introducing Behavour-Driven Development
James Shore: A vision for FIT
James Shore: How I use FIT
Steve Donie, Using version control with FitNesse, revisited
Video presentations and slides
Mary Poppendieck, Competing on the basis of Speed
Rick Mugridge, Doubling the value of automated tests
Valtech: FIT/FitNesse - an agile journey
Elliotte Rusty Harold, Test driven web applications with FitNesse
J.B.Rasinberger: Customer Friendly Testing
D. Source code
C# Classes
HelloWorld/HelloWorld.cs
SeleniumTest/Console.cs
Tristan/src/IDraw.cs
Tristan/src/IDrawManager.cs
Tristan/src/IPlayerInfo.cs
Tristan/src/IPlayerManager.cs
Tristan/src/IPlayerRegistrationInfo.cs
Tristan/src/ITicket.cs
Tristan/src/InitialWinningsCalculator.cs
Tristan/src/WinningsCalculator.cs
Tristan/src/inproc/Draw.cs
Tristan/src/inproc/DrawManager.cs
Tristan/src/inproc/PlayerInfo.cs
Tristan/src/inproc/PlayerManager.cs
Tristan/src/inproc/PlayerRegistrationInfo.cs
Tristan/src/inproc/Ticket.cs
Tristan/test/PayoutTable.cs
Tristan/test/PlayerRegistration.cs
Tristan/test/PurchaseTicket.cs
Tristan/test/ReviewTickets.cs
Tristan/test/SetUpTestEnvironment.cs
Tristan/test/Settlement.cs
Tristan/test/TotalPoolValue.cs
domain/AlternatingSUT.cs
domain/AutomaticDomainObjectWrapping.cs
domain/Domain.cs
domain/FlowCollections.cs
domain/SystemUnderTestColumnFixture.cs
domain/TargetObject.cs
extended/CurrencyParser.cs
extended/Invoice.cs
extended/RegExHandler.cs
webfixture/WebTest.cs
FitNesse Tests
CustomParsing
DomainWrapper.AlternatingSystemUnderTest
DomainWrapper.FlowCollections
DomainWrapper.FrontPage
DomainWrapper.NamingSystemUnderTests
DomainWrapper.SystemUnderTest
DomainWrapper.SystemUnderTestColumnFixture
DomainWrapper.TargetObject
DomainWrapper.WithSystemUnderTest
DomainWrapper
FrontPage
HelloWorld
InvoiceTable
LoginTest
NicerPrizeCalculation
PlayerRegistrationFirstTry
PlayerRegistrationSecondTry
PlayerRegistrationThirdTry
PrizeCalculation
PrizeCalculationFirstTry
PurchaseTicketFirstTry
PurchaseTicketNotEnoughMoney
PurchaseTicketSecondTry
PurchaseTicketSuite.BasicCase
PurchaseTicketSuite.NotEnoughMoney
PurchaseTicketSuite.SetUp
PurchaseTicketSuite
PurchaseTicketWithVariable
SettlementTests.OneWinnerSixBallsFirstTry
SettlementTests.SetUp
SettlementTests.TwoWinnersFourBalls
SettlementTests
TicketReviewTests.SetUp
TicketReviewTests.SeveralTicketsOneDraw
TicketReviewTests.SeveralTicketsTwoDraws
TicketReviewTests.TwoAccountsOneDraw
TicketReviewTests.WinningsRecordedCorrectly
TicketReviewTests
TicketReviewTestsWithRowFixture
fitnesse/FitNesseRoot/content.txt
Build scripts
scripts/runfitnesse.build
scripts/ccnet.config
Web code
code/testsite/loginform.html
code/testsite/login.aspx
Index