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
Lisa Crispin about 2 hours later:
This sounds good. I just want to clarify, all our same tests will still work with adding a prefix to the fixture name, for example – our DoFixture tests will still work, we just have to add ‘ST’ in front of the fixture name?
unclebob 1 day later:
Lisa, there are some differences between the way the slim tables work and the way that fit tables work. For example, to use DecisionTables with a ColumnFixture you will have to add setXXX functions since Slim can only call functions and cannot load variables. The tables themselves will likely need little or no change.
Mike Stockdale 2 days later:
To avoid the funny table type prefix, send a request to the SUT asking it for the table type. In your division example above, you presumably send a command to instantiate eg.Division. Then send a command to execute getTableType on the instance.
Tim Andersen 11 days later:
I’ve been looking for a FitNesse/FitLibrary solution for Ruby and this sounds promising.
One thing that I would like to see (not sure if this can be Slim’s responsibility or not) is a way to tag tests like gmail or del.icio.us tagging works.
I’ll be looking forward to cutting some tests over to try out Slim when it’s ready.
Matt Wynne 16 days later:
@Tim – you might want to check out cucumber if you’re using ruby.
ludovic@norsar.no about 1 month later:
Hi, you write that you got it working for Java. So the next thing to do would be to port the Slim back-end into another language. You said that it should be done very quickly. Can you explain how to port it to C++? Thanks
cool.novoecijano@gmail.com 7 months later:
Hi I’m wondering if you guys tried to use the dt in a vertical format. Something like this,http://3.bp.blogspot.com/_KukQ8TlQMz8/Sa4VMujoG7I/AAAAAAAAAcw/KvCWqhjC29w/s1600-h/Picture+2.png
My object that I want to test has a big list of attributes and I want to create a scenarios based on those attributes but the table end up so wide. It would be nice if we can laid it out in a vertical format.
Any help or suggestion will be appreciated.
Thanks
pvshewale@gmail.com 11 months later:
Do we have SLIM port for perl available?
ed hardy 12 months later:
I’ll be looking forward to cutting some tests over to try out Slim when it’s ready…
ed hardy 12 months later:
I just want to clarify, all our same tests will still work with adding a prefix to the fixture name, for example – our tests will still work…
jimmy about 1 year later:
One thing that I would like to see (not sure if this can be Slim’s responsibility or not) is a way to tag tests like gmail or del.icio.us tagging works.