5 Avoiding Duplication with Scenario Tables - essenius/FitNesseFitSharpGameManagementDemo GitHub Wiki
The business rep came back and asked for a change in the test. “Hey” he said, “I’ve been thinking. I don’t think the single test for correct handling of duplicates was enough. Can we also add tests for persons with the two other levels?”
Technically it’s not that hard, so you agree. However, copy/paste is a bad practice, also if we are talking about test cases.
That is where scenario tables come in. Edit the DuplicateTest
page (http://localhost:8080/GameManagementSuite.DuplicateTest?edit) and enter the following code before the script table:
|scenario |reject duplicate on player|player |
|$players=|player count |
|reject |add player |@player|with skill|unknown|
|check |player count |$players |
You can see a scenario as a kind of macro. The first line is the interface definition. The name is right after the scenario keyword, and after that you see a parameter (player in this case). The following lines will be inserted into the script that you call the scenario from. Any occurrence of the parameter (indicated with an @) will be replaced by the value assigned to it in the call.
Change the script to:
|Script |player management driver |
|$players= |player count |
|reject duplicate on player|John |
|note |Make sure that all still works after the duplicate|
|ensure |add player |Tina |with skill |advanced |
|check |player count |>$players |
Here, the scenario is called in the second line, with parameter John
. Now, it is easy to add such a check for another player, without duplicating lines of test code. Just after the first call, add a second one:
|reject duplicate on player|Julie |
This is what the test result should look like:
Click the +
sign in the Scenario box to expand it, and see what tests were executed in there:
Note that it is possible to use symbols that were defined in the scenario in the script that called it. In this case you will see that the $players
symbol is used in the calling script. You should just see it as if the scenario table has been inserted into the script table.
You will notice that we removed the check if the skill remained unchanged. Let’s re-introduce that, but make it a bit more generic. Change the scenario to look like this:
|scenario |reject duplicate on player|player |
|$players=|player count |
|$skill= |player |@player|if skill |
|reject |add player |@player|with skill|unknown|
|check |player count |$players |
|check |player |@player|if skill |$skill |
We re-used the fixture call that returns the skill level for a certain player (PlayerIfSkill
) and assign that to the $skill
symbol. Then, after trying to add the duplicate user, we call the fixture method again and check if the value is still the same. The assignment call looks a bit strange semantically, since we now use it to assign instead of to check, but it works nonetheless. If the name bothers you, you can easily rename the fixture method. We will leave it as-is. This is what the result should look like:
Re-using Scenarios with Scenario Libraries
The scenarios are typically tables you would like to re-use across different test pages. That is why FitNesse supports the concept of a Scenario Library. Create a page called ScenarioLibrary
(http://localhost:8080/GameManagementSuite.ScenarioLibrary) and move the scenario in there (i.e. delete it from the DuplicateTest
page as well). Run the test again; note the reference to the ScenarioLibrary
. All tests should still pass, and you can now re-use the scenario across all the tests in the GameManagementSuite
hierarchy.
There is one often used table that we haven't covered yet, and that's the Decision Table, up next.