Slim

Posted by Uncle Bob on 10/02/2008

Those of you who have been following me on Twitter have heard me talk about Slim. Slim is a new testing front-end and back-end that I’m adding to FitNesse. Here’s what it’s all about.

FitNesse is a very popular open-source acceptance testing tool that allows non-programmers to write and execute tests. FitNesse is an authoring and execution wrapper around the testing engine Fit. Fit interprets HTML and uses a set of programmer supplied fixtures to invoke the system under test.

The problem is that Fit is big. There’s a lot of stuff inside there. And it all has to be ported to the language (or platform) of the system under test (SUT). Unfortunately, since Fit is all open source it means that the various ports don’t agree with each other. It also means that a change made to one, does not match a change made to another. This is deeply frustrating.

To make matters worse, the effort required to maintain a fit port is relatively high. The folks who maintain these ports do so out of the goodness of their own hears, and have real jobs that often take effort away from Fit.

The end result is that the universe of Fit is uneven at best. Java programmers can use one set of features and fixtures, whereas C++ programmers must use a completely different set. The .NET version of the fixtures work in a very different way from the Java versions. New languages and platforms require a relatively large effort just to get started with Fit. etc.

Slim—The solution

Fit interprets HTML tables in order to make specific calls to the SUT. Fit does all this interpetation in the SUT. What if we moved all that table interpretation to FitNesse? FitNesse is written in Java and communicates with the SUT through a socket. Right now it passes all the HTML through that socket to Fit and accepts the colorized HTML back through the socket from Fit. But what if we changed the partitioning? What if we did all the table processing in FitNesse and then shipped a list of calls across the socket to the SUT?

That’s what Slim is. Slim is a very small module that runs in the SUT. It listens at a socket for very simple commands that instruct it to create instances of fixtures and to call methods on those instances. It passes the return values of those method calls back through the socket.

Slim is very small. Porting it is a matter of a few hours work. Once ported, there’s virtually no other maintenance required. It seems unlikely that new Slim features will be needed very often.

What this means is that all the table processing is done on the FitNesse side, and will work exactly the same regardless of the platform of the SUT. C++, Ruby, Java, Python, C#? It doesn’t matter, your tables will work in exactly the same way.

And who said we needed tables anyway? Since all the processing is done on the FitNesse side, we can write new kinds of testing languages. We can write story runners like RSpec or JBehave. They will all use Slim to communicate to the SUT, and will all work identically with any platform that has a Slim port.

Slim Tables

If you are familiar with Fit, you know that there are different fixture types. There are ColumnFixtures, RowFixtures, ActionFixtures, DoFixtures, etc. Each of these require a library to be written and executed on the SUT.

In Slim we replace these with processors on the FitNesse side. Instead of ColumnFixtures we have DecisionTables. Instead of RowFixtures we have QueryTables. Instead of DoFixtures we have ScriptTables. New kinds of tables can be added using a simple plug-in mechanism.

Slim Fixtures

Slim fixtures are very similar to Fit Fixtures except that they don’t inherit from anything! There is no library on the SUT that you have to include.

Interestingly enough, if you already have a Fit ColumnFixture written for your SUT, it will very likely work with a Slim DecisionTable. Existing RowFixtures will likely work nicely with a Slim QueryTable, etc.

Migrating to Slim

To replace Fit with Slim for a test page, all you need to do is set the variable TEST_SYSTEM to slim. This will invoke the Slim table processor rather than the old Fit test runner.

!define TEST_SYSTEM {slim}

There are some minor differences in the table format. The biggest is that the table type is no longer known by the fixture. Therefore FitNesse needs to know what kind of table you are writing. So a column fixture that used to look like this:

|eg.Division|

|numerator|denominator|quotient|

|10       |2          |5       |

Will now require a simple prefix as follows:

|DT:eg.Division|

|numerator|denominator|quotient|

|10       |2          |5       |

Did you see the DT:? That’s it. Otherwise the tables should be the same. And as you might guess there will be similar prefixes for QueryTable (QT), and ScriptTable (ST).

Indeed, this is the part of the Slim Tables that I like the least. If anybody has a better idea, or at least some better prefixes, I’m all ears (er. eyes).

((Update: For Decision Tables the “DT:” is not necessary but can be supplied. Or you can use the prefix “Decision:” (See FitNesse User Guide for more details). For Query tables the prefix is “Query:”, For Script tables the first cell is just the word “Script”))

What if you like processing tables in fixtures?

Some of you might use TableFixture, or just do your own table processing in your Fit fixtures. You can still do that with Slim. One of the table types I plan to implement is a raw Table (Table prefix). The whole table gets shipped over the socket to the fixtures as a List of Lists of Strings, and the fixture returns with a table with the same geometry, loaded with “pass”, “fail”, or “neutral” to provide colorization hints.

Current Status.

I currently have Slim working in Java, and Decision Tables being processed. What I don’t have so far are any of the other table types, suites, command line test runners, etc. So there’s plenty of work to be done.

Comments

Leave a response