Open Testware Reviews
FitNesse
Copyright 2004 by Tejas Software
Consulting - All rights reserved.
Contents
Overview -- Maturity
-- Project activity -- Platforms -- Support -- Documentation -- Installation
-- Implementation -- Performance -- Similar
tools -- Limitations -- Observations -- User
experiences -- Appendix A: FooTest page -- Appendix B: ClassPath page -- Appendix C:
Examples/myFixtures/foo.java fixture
Overview
Reviewed: 2004-February-16
Version reviewed: 20040119,
2004-January-18
Maintainer: Micah Martin
URL: http://fitnesse.org/
Testingfaqs.org category: Test Drivers and Test
Suite Management Tools
License: GPL v2
User interface: web,
command-line
FitNesse is a fascinating test tool. To a black box tester, it looks
like an elaborate unit test tool. To an agile developer, it's an
acceptance test tool, which may be the only level of testing performed
other than unit testing on an agile development project. FitNesse
integrates a web server, wiki software, and the FIT engine
(Framework for Integrated Test).
Starting it is quite simple,
and no configuration is required at all.
I originally set out to review FIT itself, but I just
couldn't make much sense of it from the web page. Then I heard about
FitNesse, which is not without its frustrations, but was much easier to
grasp.
I thank Michael Silverstein of SilverMark Incorporated for concerted
efforts in providing feedback on this review. Also, thanks go to my
other reviewers: J. B. Rainsberger of Diaspar Software Services, Micah
Martin
of Object Mentor, Inc., and Ward Cunningham of Cunningham &
Cunningham,
Inc.

Maturity
3 - Alpha (on a scale of 1-5)
The previous release likely merits a beta rating, but the most recent
release is a step back in reliability and in the accuracy of the
documentation. I don't agree with the production rating on SourceForge.
Project activity
5 - Very Active (on a scale
of 1-5)
Nine releases on SourceForge since March 2003. However, there
was a big gap
between July 27, 2003 and the most recent release on January 19, 2004.
The
pace of releases may be slowing down considerably. The mailing list is
active, though practically all of my questions were answered on the
list only by the tool's maintainer.
Platforms
FitNesse is designed for Java 1.4.0 or newer. It's likely to run on any
platform supported by Java. You'll need the SDK so you can compile the
test fixtures that you develop.
I tried the tool with similar results on Windows XP with IE 6 and
Netscape 7.1, Red Hat Linux 9 with Mozilla 1.4, and MacOS 10.3 with
Safari 1.1.1. I used Java 1.4.1 and 1.4.2. FitNesse seems to be
supported better on Windows, however. The script that runs the tool on
Linux and MacOS had a simple but fatal error, and one of the acceptance
tests for the tool failed on both of these platforms. I couldn't get
the Alt-key shortcuts for running tests, editing, saving, etc. to work
with Safari.
Support
There is a Yahoo Groups mailing list for
FitNesse that has a healthy amount of traffic, including
contributions from the tool's authors. I had to work harder than usual
to get a few of my questions answered there, but others seemed to be
getting
good support from the list. Strangely enough, people sometimes also ask
questions on the Comments Page,
and occasionally
answers are posted there as well. Micah Martin was helpful when I
contacted him directly.
FitNesse is distributed through SourceForge, but the project does not
seem to be utilizing many of SourceForge's services, like the bug
tracking database. It may be best to report bugs to the mailing list.
After I reported a problem on the mailing list and got a quick
response, another reader complained that he had reported the same issue
in the bug database several days earlier and got no response. Because
the current version of the documentation is kept in a wiki
running on fitnesse.org, I actually found it easier to fix minor
documentation problems myself than to bother to report them.
Release notes are spotty, though you can find decent notes for the most
recent release. The source code is available from the CVS server on
SourceForge. Log messages for checkins are minimal. I was not able to
determine which version of FitNesse was installed after the
installation was complete. A problem was fixed shortly after the last
release, which was fixed without changing the release number--this
practice can lead to confusion about what is installed.
Object Mentor, Inc., the
primary sponsor for the development of FitNesse, offers an "Acceptance
Testing" course that includes coverage of FitNesse.
SilverMark, Inc. offers the Agile
Testing for Java Developers course covering FitNesse and many other
tools. ObjectWind Software is
developing an Acceptance Testing
course that covers
FitNesse and other tools. Clarkware
Consulting includes a bit of information about FitNesse in the
"Test-Driven Development With JUnit" course. All of these companies
also offer consulting services. There
are likely other offerings besides those I list here.
Documentation
FitNesse includes with a User Guide within the wiki interface. It's
fairly terse, but has decent breadth. The User Guide includes a
tutorial in the Getting Started section. If you encounter problems with
the documentation, check the latest version of the User Guide on
fitnesse.org to see if the problem has already been resolved.
I found numerous problems in the documentation, some cosmetic and some
substantive. Not enough attention was put toward updating the
documentation for the latest release. Some of these problems are
mentioned in the Limitations section below. I also had trouble on some
platforms copying and pasting blocks of text from the tutorial into the
wiki edit forms--the bullets would be copied into the form and I had to
delete them manually.
There's an interesting slide
set on the ObjectWind Software web page that gives an overview of
FitNesse. You must use Internet Explorer to view it. Other external
write-ups are listed on the FitNesse Buzz page.
FIT is the engine behind FitNesse. Its basic test fixtures are covered
in the FitNesse User Guide. In addition, the main FIT documentation is
on a twisty maze of wiki pages. A
reviewer (J. B.) who has no complaints about the FIT web site asked me
to elaborate on my criticism of it, so here goes. The name of the tool
doesn't appear anywhere on the front page. It's hard to find a clear
explanation of what the tool does and to separate the function of the
tool from the description of the processes that it enables. I don't see
a way to learn about the tool in a top-down fashion, and I didn't have
the patience to try to synthesize the big picture from the information
I found. I find many wikis similarly confusing, but sites like the Wikipedia prove that it's possible to
design an easy-to-use wiki.
Installation
FitNesse installs from a 550 Kb zip file. It's not clear which files
you need to download and install. I installed fitnesse20040119.zip. It
looks like you can just grab fitnesse.jar if you only want to update
the Java jar file. There is another zip file for
the source code that's about 660 Kb.
The run.sh file that you use to start FitNesse on Unix-like systems
doesn't have execute permissions. I believe this is a general
limitation of zip files. It's easy to fix this using chmod. Also,
FitNesse gives a fatal error when using run.sh (but not the Windows
version run.bat) because of a problem with the capitalization of a
class name. A workaround is to change "fitnesse.FitNesse" to
"fitnesse.Fitnesse" in run.sh. On the previous release, there were also
problems with DOS line endings in run.sh confusing Unix shells, but
that problem doesn't affect the 20040119 release.
Once you've unpacked the zip file and have a run.sh or run.bat script
that works, running FitNesse is often as simple as running the proper
"run" script for your system. The most common glitch is when your
system is already running a web server on port 80. If this is the case,
you can specify a different port, e.g., "run -p8080".
Implementation
FitNesse is implemented in 21,000 non-comment Java source lines. I
count 4000 lines of comments. This includes a copy of the FIT source--I
can't tell easily which version of FIT it is. Of this code, 9300
non-comment source statements appear in 151 files with
"Test" in the name that appear to be JUnit-based unit tests. In
addition, there are 45 test pages in the FitNesse acceptance test suite
in FitNesse's wiki format, with 257 total assertions. One assertion on
one test page failed when I ran the tests
(SuiteResponderTests.SuiteRunResponder.TestLinearClassPath); this test
is disabled in the latest version of the test suite on
fitnesse.org.
There are .NET and C++ implementations of FitNesse, but they haven't
kept pace with the current release of the Java version.
There are a few directories in the source that include spaces in the
names, which can cause confusion for command-line users.
Performance
FitNesse does not introduce much overhead. I constructed 500 very
simple assertions one a single test page, and it runs in less than a
second a 1.4 GHz Centrino. A test on a slower machine with almost 1000
assertions ran in
about 5 seconds. FitNesse's own acceptance test suite runs 257
assertions spread across 45 test files in just a few seconds.
We owe this speed to the fact that the tests were set up using a unit
test-style fixture. If I had used a more traditional black box testing
approach, bringing a complete application to a known state before each
test, it could have taken orders of magnitude more time to run the
tests.
I did have trouble with a stack overflow when saving and running tests
that contained hundreds of assertions. The symptom was a stalled
browser and an error message on FitNesse's standard output. On my Linux
machine I couldn't run more than about 1000 assertions on a single
page, even after removing the limits on stack size. I had to edit the
test using a text editor to recover the file. On the Windows machine, I
could avoid the problem by telling the Java run-time to use a larger
stack, which I had to do even for the 500-assertion test.
Similar tools
FIT, which was available by itself
before FitNesse was written, is still commonly used without FitNesse.
FitNesse provides a browser-based user interface on top of FIT. The FIT
web site is also a wiki, but you can only run FIT from the web site
via a CGI script that seems to be set up to run a few examples. I'm
not sure how general-purpose the CGI script is or whether it ships as
part of FIT.
Though FitNesse uses a web interface, it doesn't have any special
capabilities to test web applications. Users have integrated web
testing tools with FitNesse. An example is jwebfit, which seems to
integrate FitNesse with jWebUnit,
though only sketchy information is available about it.
FitNesse enables keyword-driven testing, so it's interesting to compare
it to other keyword-driven tools, as discussed in the GUI Test Driver Survey.
FitNesse isn't focused on testing through a GUI interface, though, and
I'm not sure anyone has tried to integrate it with a GUI test tool. The
other keyword-based tools don't necessarily have to be used for GUI
testing, though people probably associate them strongly with GUI
testing anyway. FitNesse may be a factor in encouraging keyword-driven
testing outside of the realm of GUI testing.
Otherwise, FitNesse can be compared to other test management tools (see
the Black Box Test Driver Survey)
and perhaps requirements management tools.
Limitations
- The run.sh script has a fatal error. To work around it, change
"fitnesse.FitNesse"
to "fitnesse.Fitnesse" in the script.
- Creating large test pages caused an exception and no response
from the browser (as mentioned earlier)
- I couldn't get the virtual wiki feature to work using the
instructions provided.
- As I've seen with other Java programs, faulty input is reported
with Java exceptions and stack traces rather than a more user friendly
error (I was told that this is a limitation of the FIT engine). For
example, a test using the column fixture that's missing the header line
yields a NullPointerException, and using alpha cell data when numeric
data is expected yields a NumberFormatException.
- I couldn't create a with a name that has a number on the end
because it's not recognized as a
wiki word.
- Tests are silent if no expected result is indicated. It might be
more robust to flag this when it happens.
- I saw a few mysterious bumps in the night. One was clearly my
fault--I copied a fit.jar file from a previous release in trying to
work around a problem, which caused FitNesse to misbehave. In another
case, I found that my fitnesse.jar file didn't match the fitnesse.jar
file from the original zip file, and the symptom was a single page of
the documentation that wouldn't load. I haven't figured out what caused
that yet.
Most of the documentation problems I saw have been fixed in the
fitnesse.org version of the User Guide (and thus presumably the next
release). But I'm concerned that similar problems will appear in the
next release. There were numerous spelling mistakes. There are two
links to acceptance test patterns that have no content. Running the
test in the UserGuide at FitNesse.RunningAcceptanceTests
and FitNesse.ColumnFixture yields a java.lang.ClassNotFoundException
message.
In the Getting Started section, the Example directory it refers to
doesn't exist yet, which is confusing, and in another place it refers
to it as Examples instead, causing the test to fail to run. There's an
ambiguous reference to a FrontPage that isn't actually on the front
page because a "." is missing from the name. The new page expiration
message was not added to the sample output listing. There's a reference
to a nonexistent fit.jar file in the classpath.
Observations
FitNesse is built upon a wiki
wiki web, or "wiki" for short. You can include acceptance tests
intermixed with product specifications on a set of web pages. This way,
you can use the tests as part of the specification, and not have to
repeat the information imparted by the tests themselves. The tool does
not impose any format to the specifications. You follow a specific
syntax for the tests (each subtest generally occupying one line in a
table), and put anything else on the page that you want to.
If you've never used a wiki before, it may take you a while to get used
to the concept. Each web page has an edit link on it that anyone can
use to edit the page. You use a simplified markup language to define
the page and the tests within it. FitNesee extends the wiki paradigm by
allowing you identify a page as a test or a suite pointing to other
suites and tests. By clicking the "test" or "suite" link, the tests are
run and the current page is annotated to show the results. Another
innovation is the fact that the wiki is hierarchical. Most wikis use a
flat namespace for all the pages on the site. To allow more than one
test project to exist on one FitNesse instance, the server uses a
hierarchy to minimize the possibility of clashes in page names.
While I've spent some time using wikis before, I haven't quite gotten
used to FitNesse. The test result pages look similar to the test pages,
but they don't have the links available that the test pages do, so I
found myself using the browser's Back button frequently. (Using Alt-key
combinations sped up navigation - try Alt-Left Arrow to go back.) After
editing
a page, I get bounced back to that page, but the edit session still
clutters the browser history. It's also not easy to browse the
hierarchical wiki without frequent use of the Back button. One more
annoyance was when I stopped the FitNesse server, Netscape had a
tendency to bounce me to a search engine looking for "localhost."
A prerequisite to developing FitNesse is having a fixture that
interprets the tables on a test page and does the dirty work of running
the test. FitNesse includes some stock fixtures to inherit from that
make it easy to get started, including ColumnFixture, RowFixture, and
ActionFixture. The first two are geared toward data-driven testing,
though I can't quite grasp the logic of how they were named.
ActionFixture enables keyword-driven testing. While I felt that the
ActionFixture was the most evolved of the three, reviewer Michael
Silverstein feels differently. He said:
I thought action
fixtures were pretty simple compared to row and column fixtures,
probably because I was already familiar with keyword-driven testing.
RowFixture was hard to get at first because of the matching aspect. I
had to try it on a few cases to make sure I understood it completely.
ColumnFixture wasn't really confusing but it is a bit of a switch from
keyword-driven testing because each row is a discrete interaction and
verification in itself.
The most confusing part about sorting out fixtures is of the subtle
difference between the way fields and methods are treated, and the way
objects under test are instantiated.
I think the most interesting and possibly confusing part of the
different fixtures is that although the tests (tables) themselves look
very similar, the fixtures for them embody quite different semantics
and do very different things under the covers when they execute.
To create a fixture for
an application, a toolsmith would write a Java class that extends one
of these fixtures (it's possible to use other languages with a little
more work). Then the test designer, perhaps a testing specialist or a
customer representative,
can write and run acceptance tests from the wiki interface using the
fixture. While non-technical contributors are able to do the lion's
share of the work, and they can create the tests before the fixture and
the application are completed, they still rely on a programmer to put
the fixtures in place before the tests will run.
Tests usually run on the machine that's running the FitNesse server,
even if you initiate the tests from a browser on another machine. There
is a "virtual wiki" feature that allows you to keep the tests on a
server and execute the tests on a different machine that's also running
FitNesse. This latter model seems to be the best, allowing programmers
to test their code in a sandbox on their own machine, but also using a
shared repository for the tests. There are still some concurrency
issues that would need to be resolved, e.g., someone modifying a test
on the server while someone else is running it, and someone adding a
test for a feature that isn't checked in yet.
Note that there is also a simple command-line interface that
facilitates running the tests automatically as part of a nightly build.
I didn't see sufficient documentation on the filesystem structure to
facilitate creating the tests from the command line.
Appendix A contains the content of a sample test case that I wrote, and
Appendix B shows the ClassPath page that shows Java where to find its
code. Appendix C is the fixture that I wrote. It's a unit test-style
fixture because it's adapted from the example in the FitNesse
documentation. A black-box example would be better.
FitNesse is a one-of a-kind tool. The wiki interface is a powerful
concept, though the novelty of it may confuse novices. If more
attention can be paid to quality, FitNesse likely to continue to rise
in popularity.
User experiences
Two experienced FitNesse users offer their "beyond the learning curve"
perspective.
I have had the
opportunity to use the 7/28/2003 FitNesse build on a couple of projects
now and the early
returns have been favorable. The first I heard about FIT was at a
workshop on Customer Testing at XP/Agile Universe 2002. Ward
Cunningham shared his experience with building tests based on tables
whose
cells would change color to indicate success or failure. He mentioned
that he could see some interesting patterns just by looking at the
colors, differentiating sporadic failures from systematic ones. I was
intrigued by the idea even then, but it wasn't until early 2003 that
I began using FIT and its cousin, FitNesse.
After seeing the power of FIT tests and
having been a long-time wiki user, FitNesse seemed to be an ideal
tool for managing an agile project with a mobile customer. This
frequent traveler commented how convenient the tool was for him: he
could check the site daily for new tests, stories and any questions
we had for him. He could answer them directly, add a few tests and
let me know when something failed. FitNesse did an excellent job of
compensating for the fact that the customer couldn't be in the room
with the rest of the team.
I have seen other projects try to
implement end-to-end tests using Mercury Interactive's WinRunner and
other home-grown scripting tools, mostly failing under the mounting
maintenance costs. The best customer testing solution I'd used before
FIT was HTMLUnit, an open source web application testing tool. Now I
use FitNesse and HTMLUnit in tandem: my FitNesse tests verify
application logic without worrying about the gory details of the web
interface, while my HTMLUnit tests verify the web interface in
isolation. Using the two together has been more effective (and
time-saving) compared to writing large numbers of customer tests
using HTMLUnit alone. That, and my customers don't usually speak
Java.
As with any tool, there are a few
problems to deal with. Creating a new wiki with FitNesse seems to
require manually extracting the starter wiki document set, something
I would expect it to do automatically. My one complaint with FIT is
the need to use global data to communicate between fixtures. Having
written articles condemning the Singleton, it is difficult to allow
myself to indulge in building them. On the other hand, using FIT has
given me the chance to revisit my opinions, which has helped keep
them from going stale. FitNesse's strengths vastly outweigh any of
its weaknesses – at least so far.
Still, as Ward's FIT site states: FIT is
about tests that people can read.
Do not underestimate the power of this approach. Our customers are
writing their own tests! It's fantastic – and FitNesse integrates
two of the most powerful additions to the Agile project developer's
toolkit: FIT and wiki. I could not imagine embarking on another
project without FitNesse.
A client of mine liked FitNesse
because "it makes the logic visible."
This might not seem earth shaking for programmers, but users are very
happy to have a window into the otherwise invisible world of the
program. Test-first development with FitNesse also makes the project
progress visible for project
managers.
Early
on, I started using FitNesse on an Open-Source project, Ecal, that I'm organizing for the XP-Cincinnati users group. The group meets monthly to program.
FitNesse is excellent for communicating stories during the gap between
meetings. The latest FitNesse version and all test pages are kept in
CVS with the project code. The test pages are then implemented during
the meetings.
Install and set up of FitNesse is simple. So the xp-cinci group decided
to use the FitNesse framework as the basis for our own web development.
Take a look at the source code of FitNesse and especially FIT. The code
is clean and illustrates lots of good testing techniques.
For my clients, I've added FitNesse "smoke tests" as part of the
automated build cycle of legacy applications. After build and deploy,
FitNesse runs to check logon and logoff. A test like this checks
configuration settings and database availability. After that, more
tests can be incrementally added.
While
FitNesse is fine for web user interface testing, it really shines at
testing domain logic. Its excellent at testing a plain Java domain
layer. That's where it makes the “logic visible.”
In the past, my teams have built customized acceptance test frameworks,
either from the ground-up or based on JUnit. FIT now provides a
generalized approach. Tests can be written for a wide variety of
technologies by adding our own fixtures.
FitNesse combines a wiki for free-form project notes and a testing
framework so that the communication can be precise. FitNesse opens up
testing review to a wide audience. Managers, programmers, and the
customer can review the deliverables early in the cycle. Other testing
tools are limited to use and review only by testers.
FitNesse tests can be written before the code, and can be used to track
progress as the iteration progresses. Other testing tools are limited
to testing at the end.
FitNesse has great support for iterative development. You can point
FitNesse at your class files, then change the tests in one window and
change your code in your IDE, hopping back and forth in little steps.
There is a still a divide between writing tests in table formats and
writing new fixtures in Java code. Testers are able to write test
pages, but programmers are needed to write the fixtures.
FIT and FitNesse provide a standard open-source approach to testing. It
will do for acceptance testing what JUnit has done for unit testing. I
expect it to become the standard approach over the next few years.
Appendix
A: FooTest page
The foo function checks to see if its two floating point arguments (a and x) are equal.
|myFixtures.foo|
|a|x|foo()|
|1|1|true|
|1|0|false|
|1|1.00001|false|
|1|0.99999999999999999|true|
----
ClassPath
Appendix B: ClassPath page
!path fitnesse.jar
!path Examples
Appendix
C: Examples/myFixtures/foo.java fixture
package myFixtures;
import fit.ColumnFixture;
public class foo extends ColumnFixture
{
public double a;
public double x;
public boolean foo()
{
return (a == x);
}
}