Automated system testing with FitNesse


Everyone knows Unit Tests should be completed with system tests (also called functional tests or acceptance tests). There is a pretty famous framework out there to help you writing and running your system tests: FitNesse (note the ending E). It's a mini Wiki server running FIT tests. We'll see the advantages of FitNesse compared to a Unit Tests framework, and also some of its features implemention details. We'll assume you're already familiar with Unit Tests.

Introduction

System tests are tests that check the end user features, taking your application as a whole (it's black box testing). It's phylosophically very different from Unit Tests which check a class knowing its implementation to verify the implementation correctness (it's white box testing).

Installing FitNesse is pretty easy:

  1. Download fitnesse.jar
  2. Run the command java -jar fitnesse.jar (on Windows you'll have to use the full path to java.exe)
  3. Open http://127.0.0.1

By default you'll have to write your tests wrappers (called Fixtures by FitNesse) in Java. You'll have some more steps to use C#, Python or other languages.

Architecture analogy with Unit Test frameworks

Technical differences between FitNesse and a Unit Test framework are mostly that FitNesse tests have a readable description of the system functions:

  • FitNesse is centered around a Wiki user documentation with a small code (Fixtures) linking that documentation to run the tests.
  • Unit Tests are centered around test code which can sometimes be used to generate some user documentation (like Agile documentation).
Unit Test Framework FitNesse
Unit Test class (possibly deriving from a base class) FitNesse Wiki page (possibly using one or more Fixtures)
Your Unit Test code using assertions Your FitNesse Fixture (Java/C#/Python... code linking Wiki tables to your application tests)
Test A Class Test An Application

This means that the main advantages of using FitNesse to make your tests, compared to a Unit Test framework, are:

  • Acceptance criteria and tests descriptions are visible and easily understandable by humans (even non-tech people)
  • Acceptance criteries and tests can be modified by the business people
  • FitNesse has features adapted to system tests, like:
    1. CommandLineFixture executing command-lines
    2. DoFixture executing some methods in order

How it works

You write the Wiki page in business words.

Only tables will define the acceptance tests. For example to test an addition you may first write a table like follow:

eg.Addition
A B C?
0 1 1
1 1 2
-1 1 0

Create a FitNesse Fixture and link it to your page.

You'll have to add special code to tell where to find the Fixture as the first table row (e.g., |eg.Addition| would look for the class named Addition in the package eg).

Then supposing you wrote the FitNesse Fixture code:

class Addition
{
    public int A;
    public int B;

    public int C()
    {
        return A + B;
    }
}

Clicking FitNesse TEST button would execute this code for the first line:

Addition fix = new Addition();
fix.A = 1;
fix.B = 1;
Assert.AreEqual(fix.C(), 2);

FitNesse Fixtures

Fixtures is a small code you write (or reuse) that'll take as input the tables on the Wiki test page(s) (called decision tables) and that'll link the to your test conditions. Fixtures which can inherit from base fixtures to simplify common tasks. Some important Fixtures below:

ColumnFixture
Maps table input columns directly to properties, and table expected output columns to methods of the fixture class.
RowFixture
Compares the Wiki table with a 2D array returned by your fixture
DoFixture
The first row of the table lists the fixture class name. All rows after that are used to execute verifications or perform actions by executing methods of the fixture class. It's similar to the ActionFixture: The tables describes methods called in order and possibly checks returned value.

Going Further

FitNesses uses Slim and FIT which has many fixtures already on the web, like functional web testing fixtures.

FitNesses has also a Hudson plugin to run FitNesse automatically as part of your continuous integration.

References

— Werner BEROUX, Updated on August 24, 2010