UPDATE II: Thank you to Steven Haines for the clear and concise Howto giude on the RestFixture.
I am currently involved in building a REST API. Our direct customer proxy (the architecture team) needs to "understand" how we implement the agreed acceptance criteria and it has also asked to document the API.
FitNesse is our tool of choice for writing functional Customer Acceptance Tests; we currently use it to implement this type of tests for other parts of the system we're building. So it came natural to start using it for documenting the API.
At first we implemented the tests using essentially ActionFixtures. The approach adopted consisted of "wrapping" the REST API in more descriptive metods that could be
After the first dozen of tests it was apparent that this approach was not ideal. Tests were not clear enough and maintaining the fixtures was hard and time consuming as the amount of code duplication was high for any standard. New tests required us writing more code and, in fact, we were testing just the behaviour of the backend without giving enough exposure to the API itself - consequently, our tests were not descriptive enough to work as live documentation.
So I decided to write a new "type" of fixture, inspired by the
ActionFixture, the RestFixture.
The core principles underpinning the decision to write a new fixture were the following:
- For documenting a REST API you need to show how the API looks like. For REST this means
- show what the resource URI looks like. For example
- show what HTTP operation is being executed on that resource. Specifically which one fo the main HTTP verbs where under test (
- have the ability to set headers and body in the request
- check expectations on the return code of the call in order to document the behaviour of the API
- check expectation on the HTTP headers and body in the response. Again, to document the behaviour
- I didn't want to maintain fixture code. If I could only write the tests...
- I wanted to be able to let the customer proxies to write the tests... And they understand Wiki syntax more than Java.
RestFixtureat a glance
ActionFixture, therefore all the
ActionFixturegoodies are available. On top of that it contains the following 7 methods:
header: to be able to set the headers for the next request (a CRLF separated list of
body: to allow request body input, essential for
let: to allow data from the response headers and body to be extracted and assigned to a label that can then be passed around. For example our API specifies that when you create a resource using
POST, the newly created resource URI is in the
Locationheader. This URI is necessary in order to perform further operations on that resource (for example,
DELETEit in a teardown).
DELETE, to execute requests.
Each test is a rown on a
RestFixturetable and it has the following format:
VERBis one of
DELETE(at the moment we're not supporting
uriis the resource URI
?retis the expected return code of the request. it can be expressed as a regular expression, that is you can write 2\d\d if you expect any code between 200 and 299.
?headersis the expected list of headers. In fact, the expectation is checked by verifying that *all* the headers in here are present in the response. Each header must go in a newline and both name and value can be expressed as regular expressions to match in order to verify inclusion.
?bodyit's the expected body in the response. This is expressed as a list of XPath expressions to allow greater flexibility.
The following pictures are snapshots taken from FitNesse with the aim of providing examples of usage of the
RestFixture. The notes before each test explain the details of the fixture itself.
It's worth noticing that, generally, expectations are not matched by string comparing the expected value with the actual value. Expectations on headers are verified by checking that the expected set of headers is included in the actual set of headers, similarly with the body where expectations are matched by checking existences of nodes for a given path.
RestFixtureallows to write FitNesse tests without having to write any Java code to back up the fixtures. Tests are clear and easy to read/write and this obviously improves their readability. Therefore it works well for documenting the API and the behaviour of the system under test. Looking it from another angle, the fixture, essentially, implements a REST DSL, that allows customers to write tests on their own.