So far, we have built five or six test pages with quite a few things in common. All the test pages start with the same three lines that define the .NET2 runner and the project DLLs. The test pages in the two previous chapters all include a “Set Up Test Environment” table and some of them also have a common player registration. Repeating the same content in several places is one of the first test smells[18] you should watch out for. We need to remove this duplication and make test pages simpler. This enables us to work faster in several ways:
If we can avoid repeating boilerplate code, we do not have to worry about getting it right every time.
Duplicated content may slow us down when we need to change code or adjust tests.
If the common content is in one place then we can easily change it.
In this chapter, we do not implement a new user story, but take a step back and find out how to organise our tests better.
So, let's remove the unnecessary duplication. In FitNesse, subwikis are the equivalent of web folders or C# namespaces. They can be used to manage related pages more easily as a group. Instead of a slash (/), which is the separator in a web folder name, the dot symbol (.) is used to separate levels of hierarchy in FitNesse.
For example, URL PurchaseTicketSuite.NotEnoughFunds leads to the NotEnoughFunds page in the PurchaseTicketSuite subwiki. Just as a page can be turned into a test with page properties, a subwiki can be turned into a test suite. A test suite is a group of related tests that allows us to control their common properties from one place. So, let's create a new test suite with the pages in this chapter.
First, create the PurchaseTicketSuite page, just as you would create any
other normal page. You can put the definition of the .NET test runner
and your project DLL path there. Instead of defining any test tables,
just enter
!contents -R
as the page content. This automatically builds and shows a table of
contents for the subwiki.
1 !define COMMAND_PATTERN {%m -r fitnesse.fitserver.FitServer,dotnet2\fit.dll %p}
2 !define TEST_RUNNER {dotnet2\Runner.exe}
3 !path D:\work\fitnesse\Tristan\bin\Release\Tristan.dll
4
5 !contents -R
There are no subpages yet so the table of contents is blank, but not for long. Go to page properties, but instead of Test, mark this page as a Suite.
Copy the common code (namespace import, test environment set-up and the player registration) and paste it into the contents of a new page called PurchaseTicketSuite.SetUp. SetUp is a special page, and is included automatically at the beginning of all test pages in the test suite. Do not mark this page as a test.
1 !|import| 2 |Tristan.Test.PurchaseTicket| 3 4 |Set Up Test Environment| 5 |Create Draw| 6 |01/01/2008| 7 8 |Player Registers| 9 |username|password|name|address|city|postcode|country|player id?| 10 |john|test123|John Smith|44 Ranelagh Way|London|NN1EE1|UK|>>player|
Then take the rest of the test pages, which describe actual business rules, from Writing the story in a test table and Use DoFixture keywords for better control and put them in separate pages below PurchaseTicketSuite. Call the first something like BasicCase, and the second NotEnoughMoney. Mark them both as tests. Once the pages are marked as tests, SetUp is automatically included into them (Figure 7.1, “SetUp is automatically included in all tests in a test suite ”).
When you look at the PurchaseTicketSuite page now, it should list three child pages and have a Suite button on the left. Click Suite to run all the tests in the suite. The page starts with a test summary, followed by individual test reports (Figure 7.2, “Fitnesse shows a summary at the beginning of the test suite report”).
![]() | In what order are suite pages executed? |
|---|---|
The order of pages is not guaranteed, so do not depend on it. Extract all common functionality into the SetUp page so that the order is not important. |
While refactoring your test pages to extract common things to a SetUp page, be careful not to lose the expressiveness of the page. The important thing is that everyone has the same understanding of what the test page describes — so do not make the page too technical.
![]() | Stuff to remember |
|---|---|
|
[18] Code smells are symptoms of problems rotting in code, which should be tended to and refactored (See http://c2.com/xp/CodeSmell.html). Martin Fowler attributes the idea of Code Smells to Kent Beck in Refactoring[7]. I use the term “test smells” for similar problems in test pages. See Appendix B, Test smells for a list of all test smells mentioned in this book.



![[Tip]](../images/resources/tip.png)
![[Note]](../images/resources/note.png)


