Bill Wake has posted an excellent introduction to
FIT. It's a challenge really, intended to give folks an opportunity to practice writing FIT test tables and fixtures. When all the tests pass, you've built the core of a spreadsheet application. It will still need a user interface of course, and that will require different types of tests. In the meantime, your FIT tests will give you confidence in the guts of the spreadsheet application. And in the process you'll have built a UI-independent testing interface to the "business logic".
With FitNesse -- FIT and a
Wiki rolled into one -- you don't have to run the tests from the command line. Rather, there's a button labeled Test on the HTML page that when pressed runs all the tests (tables) on that page. Here's the output of running Bill's tests. Notice that passing tests are indicated by green cells; failing tests by red cells showing the expected and actual values for each result. The challenge is to get all the cells to turn green using your own FIT test fixtures.
But before you get too focused on turning the cells green, take a few moments to imagine how you might have written these FIT tests yourself. Or, more appropriately, who you might ask to help you write effective acceptance tests using FIT. It seems to require two skill sets: Java programming and testing.
The test fixtures are written in Java. Each fixture is a Java class that has instance variables to capture the test inputs and methods to invoke actions and return expected results. As such, fixtures are simple adapters to the system under test. That is, they form the glue between the HTML table specifying the test and the API of the production code being tested. Though fixtures can be relatively trivial -- simply delegating all work to the system under test -- they do require someone who knows how to cut Java code. But how do you know what variables and methods a test fixture should have? In other words, what shape should any particular test fixture take in order to effectively test a feature of the application?
Without worrying about the API of the system under test, or writing any Java code whatsoever, you can start writing some FIT tables that specify acceptance tests. FitNesse allows us to edit any page using the browser. By virtue of being a Wiki, FitNesse also offers a convenient markup language for expressing HTML tables without having to actually venture into the nefarious world of angle brackets. We can even write some documentation associated with each test, right there along with the test inputs, actions, and expected outputs. Oh, the tests won't actually pass until you write the FIT test fixture and the production code it exercises. But that's a Java implementation detail. First things first: test then code.
Open the browser, create a new page for our tests... and now what? Well, you have to specify a test of course, but what's a good test? Ah, therein lies the difficult part. You're faced with defining a test that when green gives you (and your customer!) confidence that the feature you're building actually does the right things and does them right. That is, you have to figure out what the feature is supposed to do and how you'll know when it does those things. Later on you'll surely write unit and integration tests as you're implementing the feature to validate your design decisions and sanity check individual components. But right now you're confronted with having to define an acceptance test that tells you when the feature is done.
Take another look
at the tests in Bill's challenge. Would you have thought of all those tests? I'm quite sure I wouldn't have. I'd do my best, but I'd like some help. Specifically, I'm willing to bet that someone with more testing experience than I would have taught me a thing or two about what might go wrong. Moreover, they'd probably have different perspectives on what a test fixture for any particular feature should offer. Or perhaps this team member has spent more time with our customer learning how a feature will be used, and now they're speaking on that customer's behalf. Together we could design the test right here in the browser -- adding rows and columns -- before ever writing a line of Java code. And if later we paired while writing the test fixture, I might teach them a thing or two about programming in Java. We might both learn something valuable about software development.
Once we've defined the test fixture, driven by the variables and methods declared in the FIT table, then anyone is free to add new test cases without ever firing up a Java compiler. Want to test a new corner case that's been keeping you up at night? Simply add a new row to a existing table, press Test, and we'll see red or green. And if we see red, then the fact that we collaborated on defining the test using a tool we both understand inclines us to work together to fix the problem. It's our test.
Automating tests is the easy part. Computers do all that work for us. Writing good tests that can be automated to continuously tell us if we've built the right thing right, now that's the tough part. I want all the help I can get. I find pairing with someone with testing experience to write FIT tests to be quite efficient and enjoyable. I prefer to do that as a matter of course before I start investing time writing production code.
FIT won't be the only testing tool we use, but it is one way we can proactively take a step (or ten) toward each other. In doing so, we might actually deliver better software faster.