ScenarioLibrary, LibraryTables with Slim Scenarios : Avoid fixture method explosion !

Assuming: working knowledge of Fitnesse.

I've been recommending Slim Scenarios for a while (primarily because they are the Fitnesse equivalent of reusable blocks (methods/functions in your favourite programming language) i.e. tables that can be called from other tables. {Actually they are akin to macro expansion.. but that's nitpicking!)

However soon I ran into a problem, the scenario steps translate into method calls onto the backing fixture class.
e.g.



|scenario |play movie|pathToMovie|on home theatre|
|enter |HDMI1 |mode on tv |
|enter |DTV/CBL |mode on avr |
|set avr volume to|-25 |dB |
|navigate menu to |@pathToMovie |
|press |play |on media player |


Now whenever I call this scenario, the fixture methods 'enterModeOnTv', 'enterModeOnAvr', etc. need to be present on the fixture class. So if Fixtures A, B, c call this scenario, All of them need these methods on them. Bummer!

Now the initial response was to extract these methods onto a helper class. Still I'd need to write some delegating methods on each fixture to delegate to the extracted class. So I raise my hand, admit my ignorance and post to the fitnesse forums. The experts answer in a flash!

The magic answer is the Library Table

FrontPage.HomeTheatreTests.SetUp

|library |
|television |
|avr |
|media player|


The Library table specifies a list of class that should be checked in case the fixture does not contain the required method. So in this case, the order in which the classes would be checked would be [Fixture > MediaPlayer > Avr > Television]. If a matching method is found in any of these classes, the step is resolved.. No more delegating methods!

This allows me to have cohesive helper classes that contain related methods which can be mixed into any page.

Another notable mention is ScenarioLibrary pages - these are pages which are libraries of usable scenarios.

FrontPage.HomeTheatreTests.ScenarioLibrary


|scenario |play movie|pathToMovie|on home theatre|
|enter |HDMI1 |mode on tv |
|enter |DTV/CBL |mode on avr |
|set avr volume to|-25 |dB |
|navigate menu to |@pathToMovie |
|press |play |on media player |

|scenario|start home theatre|
|power |on |media player |
|power |on |avr |
|power |on |tv |
...



ScenarioLibrary pages are included if they are a brother/uncle of the current page. Also all ScenarioLibrary pages up the hierarchy are included (allowing the possibility of overriding)

All this leads to very small test pages and it all works!

FrontPage.HomeTheatreTests.CanWorkWhileWatchingMovie


# ScenarioLibrary page is included (helper slim scenario definitions)
# Next SetUp page is included (imports and library tables)

|script |me |
|start home theatre |
|play movie|File Manager\USB\C\2 Watch\Iron Man 2|on home theatre|
|start working |
|after |30 |mins |
|ensure |work is done |
|press |stop |on media player|
|shut down home theatre |



In this example, the fixture Me only needs to have methods that pertain to me working. All methods related to the TV, AVR and MediaPlayer are resolved by the corresponding classes in the Fixture.dll due to the Library table.

public class Me
{
private bool _workIsDone ...

public void startWorking() ...
public void afterMins(int timeInMinutes) ...
public bool workIsDone ...
}

Pretty cool!

What do I use for acceptance tests (ATDD) : NUnit vs Fitnesse ?

Lately I've had some teams in my getting-agile ecosystem debating on which tool to use for acceptance testing. Now my first response is always "It depends" (You really can't go wrong with that. :) ).

Notation: I'm gonna use
  • NUnit when I actually mean any member of the xUnit family of unit-testing frameworks. 
  • Fit/Fitnesse stands for itself and now Slim/Fitnesse.
  • Customer means the XP's Customer role or Scrum's Product Owner role.

Fit-Fitnesse was the de-facto tool for automated acceptance tests till sometime ago.. Around 2009, there were strong murmurs that Fitnesse isn't working that well (read as some teams weren't executing very well and Fitnesse was part of their toolkit ).

So what does it "depend" on ??