FitNesse is an acceptance testing framework. It allows business users, testers and developers to collaborate on executable specifications (for example in BDD style and/or implementing Specification by Example), and allows for testing both the back-end and the front-end. Aside from partly automating acceptance testing and as a tool to help build a common understanding between developers and business users, a selection of the tests from a FitNesse test suite often doubles as a regression test suite.
In contrast to unit tests, FitNesse tests should usually be focused but still test a feature in an ‘end-to-end’ way. It is not uncommon for a FitNesse test to for example start mocked versions of external systems, start e.g. a Spring context and connect to a real test database rather than an in-memory one.
Running FitNesse during development
The downside of end-to-end testing is that setting up all this context makes running a single test locally relatively slow. This is part of the reason you should keep in mind the testing pyramid while writing tests, and write tests at the lowest possible level (though not lower).
Still, when used correctly, FitNesse tests can provide enormous value. Luckily, versions of FitNesse since 06-01-2014 make it relatively easy to significantly reduce this round-trip time.
A bit of background
Most modern FitNesse tests are written using the SLIM test system. When executing a test, a separate ‘service’ process is spun up to actually execute the code under test (‘fixtures’ and code-under-test). This has a couple of advantages: the classpath of the service process can be kept relatively clean – in fact, you can even use a service process written in an entirely different language, such as .Net or Ruby, as long as implements the SLIM protocol.
In the common case of using the Java SLIM service, however, this means spinning up a JVM, loading your classes into the classloader, and possibly additional tasks such as initializing part of your backend and mocking services. This can take a while, and slows down your development roundtrip, making FitNesse less pleasant to work with.
How to speed up your FitNesse round-trip times
One way to tremendously speed up test round-trip times is to, instead of initializing the complete context every time you run a test, start the SlimService manually and keep it running. When done from your IDE this allows you to take advantage of selective reloading of updated classes and easily setting breakpoints.
To locally use FitNesse in this way, put the FitNesse non-standalone jar on your classpath, and start the main method of fitnesse.slim.SlimService with parameters like ‘-d 8090’: ‘-d’ is to prevent the SlimService from shutting down after the first test disconnects, ‘8090’ specifies the port number on which to listen.
Example: java -cp <em>yourclasspath</em> fitnesse.slim.SlimService -d 8090
Now, when starting the FitNesse web UI, use the ‘slim.port’ to specify the port to connect to and set ‘slim.pool.size’ to ‘1’, and FitNesse will connect to the already-running SLIM service instead of spinning up a new process each time.
Example: java -Dslim.port=8090 -Dslim.pool.size=1 -jar fitnesse-standalone.jar -p 8000 -e 0
We’ve seen improvements in the time it takes to re-run one of our tests from a typical ~15 seconds to about 2-3 seconds. Not only a productivity improvement, but more importantly this makes it much more pleasant to use FitNesse tests where they make sense.