(Some) Secrets of DoFixture revealed

Maarten Winkels

For automated acceptance testing we use the Fitnesse framework. Fitness is a Wiki page that enables testers to write executable tests as Wiki pages. Wiki pages are made up from text as comments and tables as tests. To integrate the tables with the application code, developers write Fixtures. Fixtures are a very thin layer of software that invoke application code and can be exposed on the wiki. The system is very easy to use.

There are a number of useful fixtures included in Fitnesse, but by far the most useful fixture comes from a separate library (FitLibrary): The DoFixture. A DoFixture exposes every public method as a row in a table. Every odd cell in the row is a part of the method name and every even cell is a parameter. This makes the table easy to read. The row

train 123 leaves Amsterdam station at 12:00 to Utrecht Centraal station

will thus invoke the method trainLeavesStationAtToStation(‘123’, ‘Amsterdam’, ’12:00’, ‘Utrecht Centraal’). As you see, the words in the odd cells are concatenated in camel case.

Unfortunately not all features of this fixture or the Fitnesse framework are well documented and easy to find. This blog will list a number of features that can improve the efficiency of using Fitnesse. The features shown are fixture loading, parse delegates and system under test. To enhance the usefulness of the last feature, we will also look at some improvements.

This blog is based upon the same version of fitnesse and fitlibrary as the "Fit for Developing Software" book.

FixtureLoading

Did you know that DoFixture will automatically look for a fixture in all known fixture packages if you start a new table? If you have a page that starts with a (fully qualified) fixture class in a table, like

!- com.xebia.fitnesse.SomeDoFixture -!

Every next table that starts with a (non qualified) fixture name will be run by that fixture in stead of the original fixture. Thus the table

meaningful name
some method some data

will be run by the com.xebia.fitnesse.MeaningfulNameFixture. Notice that "meaningful name" is transformed into MeaningfulNameFixture and is searched for in the same package as the original fixture was found.

ParseDelegate

Did you know that you can use ParseDelegates with FitLibrary fixtures like the DoFixture? A ParseDelegate is an object that is responsible for converting a string to a certain (complex) type of object and vice versa. To do this, the ParseDelegate needs only one methods: Type parse(String). A simple Example, that converts BigIntegers is shown below.

public class BigIntegerParseDelegate {
    
    public BigInteger parse(String value) {
        return new BigInteger(value);
    }

}

As you can see, the code is pretty straightforward. More complex conversions can be useful though. The ParseDelegate below converts LocalDate objects (JodaTime).

public class LocalDateConverter {

    public LocalDate parse(String date) {
        LocalDate result;
        if (date.startsWith("+") || date.startsWith("-")) {
            int days = Integer.parseInt(date.substring(1));
            Period period = Period.days(days);

            result = new LocalDate();
            if (date.startsWith("+")) {
                result = result.plus(period);
            } else {
                result = result.minus(period);
            }
        } else {
            result = new LocalDate(date);
        }
        return result;
    }
}

This parse delegate allows adding or substracting a specified number of days to the current date through using plus or minus signs in the cell.

ParseDelegates can be added to a static Map in the FitLibraryFixture class (a parent of DoFixture) throught the registerParseDelegate(Class, Object or Class) method. The delegate will be used to parse objects when an object of the first parameter type is needed as parameter type to a method.

SystemUnderTest

Did you know that the DoFixture has a ‘SystemUnderTest’? A SystemUnderTest is a simple java object that works as a delegate for the fixture. Whenever a method needs to be found while parsing a table, the fixture looks for the method in its own class and if none is found, it looks for the method in the class of the SystemUnderTest. The method is then invoked on the SystemUnderTest object. This allows fitnesse to work directly with application code, in stead of exposing all functionality through fixtures.

Another great feature of the DoFixture is that if the invoked method returns an instance of a complex (non primitive) class, the result is wrapped in a new DoFixture, so that fitness can also work with the result. To give an example, say that we have a class Container that has a property of type Contained, named 'contents' and this type has a property of type String named 'value'. The table structure below will query the value of the instance of Contained.

method that returns instance of container type
contents
check value expected

The starting point of this query is the methid 'methodThatReturnsInstanceOfContainerType', which is implemented on some fixture class. The value returned is a DoFixture, that contains the returned value as SystemUnderTest. The second row invokes the 'getContents' method on the SystemUnderTest, which returns the Contained instance, which is also wrapped. The third row checks the value property to be 'expected'.

This feature is great for checking values on a complex structure that you use in your application. You can also use it to set values, the 'set' keyword is not added to the property names, by the way.

Drawback of SystemUnderTest

One drawback of the SystemUnderTest feature is that there is no way to traverse back up the chain of domain objects (or rather, I haven't found it yet. It might be another of those secrets to be revealed...).

To be able to move up, all domain objects that have been traversed should be put in a Stack and a new 'pop' method should be added to move up the stack. Whenever a DoFixture would be returned, the current SystemUnderTest is pushed on the stack and the SystemUnderTest from the fixture is stored as the new SystemUnderTest. An implementation of this mechanism can be found in this attachment to this blog. There is also a small unittest that shows how the fixture can be used.

In addition to moving up the domain object chain, this implementation also allows traversing lists, through the same system as described above. By setting the list as SystemUnderTest, the 'get' method on the list gets exposed, which allows for checking the values in the list. Popping the items in the list and later the list itself allows moving back up the chain again.

While this implementation is useful when testing complex application data, it also violates the fit principle to make the test pages readable for humans. The fixture introduces the 'techy' words, like 'pop' and 'get | index', and it can lead to potentially very large test tables. My suggestion is to use it with care.

Comments (1)

  1. Lars Vonk - Reply

    July 9, 2008 at 8:21 am

    Thanks for this very useful information Maarten.

Add a Comment