nit testing is a well-known practice that helps developers validate the functionality of components and identify bugs early when they are easy to fix. By leveraging frameworks like JUnit, unit tests are very easy to write and execute, and therefore provide you with very rapid feedback about the status of the system. The problem with unit tests by themselves is that they test such fine-grained pieces of functionality that it is easy to end up with gaps in coverage for the system overall. And, because unit tests are strictly a developer tool, any miscommunication or misunderstanding about requirements cannot be caught, and the business users have no visibility into these tests.
Acceptance tests, on the other hand, test coarse-grained services within the application, which complements the coverage gained by unit tests. The same people who write acceptance tests also generally write and maintain the requirements; therefore, the tests usually reflect the requirements more accurately.
Creating automated acceptance tests as a part of requirements definition has significant benefits. First, regression testing becomes much easier when all the requirements for the system are backed by automated tests, which makes finding and fixing defects much less costly. In addition, developers have a much easier time implementing features when there is a tangible example that demonstrates how the system should function. Writing programmatic tests at the service level can improve the architecture of the application being developed. Generally speaking, an application that is easy to test is also well designed. If it's difficult to write tests at the service level, it could indicate that the system is too tightly coupled or that the services being tested are not well encapsulated.
Despite the benefits of writing and running acceptance tests early, this type of testing is rarely done until late in the project's life cycle. Why? The problem with these tests is that they are generally very expensive to write and automate. The people defining the acceptance criteria, the customers or business analysts as their proxies, usually aren't programmers and don't have the skills or time necessary to write effective automated test scripts.
The Framework for Integrated Test (Fit) and FitNesse address these issues. Fit is an open source acceptance testing framework, and FitNesse is a wiki-based test execution engine that allows users to write, edit, and run Fit tests over the web. Together these tools enable developers and users to express acceptance tests in a tabular format and execute them from a simple web interface. Using Fit and FitNesse, teams can reduce drastically the effort required to create automated acceptance tests, all while increasing the accessibility of the tests and their results.
A FitNesse test is composed of three basic elements: the test page, the test fixture, and the execution engine. The first component, the test page, is simply a wiki page that contains one or more test tables in addition to any nonexecutable tables or text that describe the test or requirements in more detail. When FitNesse executes a test page, the test tables are run sequentially, which means that not only can you put multiple test tables on a given page but you can also have subsequent test tables rely on the state that was set up by previous tables.
The second component, the test fixture, is a class that interprets the information provided in a table and uses it to exercise the application. The examples discussed here demonstrate using Java to write the fixture code; however, there is also a version of FitNesse included in the main distribution that runs on the .NET framework, and it would be relatively trivial to port any of these examples to C# or VB.Net.
All fixture classes ultimately extend the base Fixture class provided in the FitNesse libraries. In addition to the base Fixture class there are a number of fixture subclasses that can be used as extension points that provide additional functionality and make writing the fixtures for common types of test tables very easy. The vast majority of test fixtures that the average team must write will extend from one of these subclasses.
The execution engine is the third component that is provided by the FitNesse libraries and is completely abstracted away from the users of the tool.