Introduction to FitNesse

August 2, 2011

one comment

No, I’m not going to tell you that fitness is very important to your health. I’ll leave it that your doctor. What I’m going to tell you about today is a tool called FitNesse (note the final ‘e’ which doesn’t exist in the word “fitness”. I don’t know what’s the reason they added this ‘e’ to the name, but it makes it somewhat easier to search for “FitNesse” in Google and get relevant results).

Anyway, last time I told you mostly everything you need to know about ATDD, but I also promised to tell you about FitNesse, which is the tool that will help you apply this methodology.

So what is FitNesse?

FitNesse is:

1. Open source, free-of-charge tool

2. Java-based, light-weight, standalone WIKI server

3. Software development collaboration tool

4. Testing framework (can execute C# code as well as Java)

5. Aimed mainly for non-developers

6. Sometime annoying, but currently the best available tool for the job…

Ah…now I understand… (In other words, now I’m REALY confused!)

Maybe an example would be more helpful. Recall the example from the previous post:

A Coke costs $2

A Sandwich costs $3

A Candy bar costs $4

The manager defines a campaign: Buy Sandwich and get Coke for $1

A customer buys the following items:

Sandwich

Coke

Candy bar

The total price should be $8

(We assume that most of the application is already implemented, and now we want to add support for campaigns)

Let’s see how this run-able scenario can be described using FitNesse:

clip_image002

Clicking on the “Edit” button (on the left) opens up a big text-box which reveals the raw text I wrote in order to create this scenario. The text you would see is:

The store manager should be able to define a campaign

|Prices         |
|Product  |Price|
|Coke     |2    |
|Sandwich |3    |
|Candy bar|4    |

|Campaigns        |
|Buy     |Get |For|
|Sandwich|Coke|1  |

!|script|Point of sale|
|Sell   |Sandwich     |
|Sell   |Coke         |
|Sell   |Candy bar    |
|Check  |Total   |8   |

As you can see, it is pretty straight-forward to read and write such scenarios without being a programmer.

Running the scenario

If we’ll click the “Test” button on the left-hand side, we’ll see errors (marked in yellow), because FitNesse can’t find the appropriate classes and/or methods to execute this scenario. It would look like the following:

clip_image004

In order to make the scenario run-able, we should write some pieces of code that act as adaptors between FitNesse and the production code we want to execute. These pieces of code are called “Fixtures” and are usually very simple to write.

Table types

The classes in the fixture should correspond to tables in the scenario. Any text that is not inside a table is only for documentation purposes and is not run-able.

There are quite a few table types that FitNesse support, each with different semantics and rules. From all of these types, there are 2 that are most common and useful: Decision Table and Script Table. (In fact, FitNesse supports two Test Systems, Fit and Slim, each support different table types. Here I’m talking only about Slim).

Decision table

In our example, the first 2 tables (Prices and Campaigns) are decision tables. In a decision table, the table name corresponds to a class; each row corresponds to an instance of the class, and each column corresponds to a property. In addition, the class can have an optional void Execute() method that is called after all the values in the rows are assigned to their corresponding properties. The fixture of the Price table looks like this:

public class Prices
{
    public string Product { get; set; }
    public decimal Price { get; set; }

    public void Execute()
    {
        // insert a row to the Prices table in the 
database...
} }

If you put a ‘?’ at the end of a column name, instead of setting the value of the corresponding property (by calling the set of the property), FitNesse compares the value in the cell with the value of the property (by calling the get of the property). If the values do not match, FitNesse marks the cell in red and the test (scenario) as failed.

Script table

The 3rd table in our example (“Point of sale”) is a script table. The preceding ‘!’ and the word “script” in the table header tells FitNesse that this is a script table. In a script table, each row corresponds to a method call. Arguments to the call can be supplied in additional columns (different rows in a script table can have different number of columns).

The reserved word “Check” in the last row of our example tells FitNesse to compare the return value of the method call with the value in the last cell. If these values do not match, FitNesse marks this value in red and the test as failed.

The code for the fixture for the “Point of sale” script table looks like this:

public class PointOfSale
{
    public void Sell(string product)
    {
        // call the production code that performs the 
selling of the product
} public decimal Total() {
// call the production code that retrieves the
current total of the current sale. return 0; } }

If you’re using FitNesse for working in ATDD style, at this point you would run the test to see that it fails, like this:

clip_image006

clip_image008

You can see that the scenario fails because the total of the sale was $9 and not $8, because we still didn’t implement the Campaign feature. Now it’s the time to implement this feature in our application. Once we’re done we should run the scenario again to verify it passes:

clip_image010

clip_image012

What’s more?

FitNesse has a pretty rich markup language which allows you to specify the graphical characteristics of the text, and also create hyperlinks between pages or to external sites. This is what makes FitNesse a kind of Wiki server.

Beside of having other table types, FitNesse has a pretty rich markup language. For example you can specify the size, font, alignment, etc of text; create links between pages and links to external sites; include one page in another; define and use variables and more.

In addition you can easily manage your scenarios in nested groups (much like file-system folders).

Getting started

At this post I only showed you an introduction so that you’ll get the idea of how it looks like to use FitNesse. In a future post I’ll explain how to get started to use this tool. For the mean-time you may download it from here, read the user guide and try it yourself. Or you can wait for my future post (I don’t promise it will be my next post).

If you can’t wait, feel free to drop me a line and I’ll help you get started personally.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. FabioFebruary 13, 2013 ב 12:52

    Thank you for exposing the differences between Decision tables and Script tables. I just got started today and your post got me over the ledge. All other examples I saw were on Decision Tables, but of course no one explicitly mentioned it, and it drove me crazy that no one mentioned the fact that their methods were parameterless, like if that was the most normal thing in the world. I can now test my methods with parameters! Thank you, again!

    Reply