Test Driven Rest
First of all, let’s agree that not any set of HTTP endpoints can be called RESTful. There are many webapps which expose a few endpoints for rudimentary integrations and claim to have “RESTful web services”.
A set of HTTP methods is said to respect the REST paradigm only if they are navigable. I think that such a programatic interface should expose more or less the entire functionality that the user sees on the UI. It should be, if you like, the “backdoor” of your application, used by other apps in the same way a normal user would navigate from one page to another.
I also said here that, when surfing through your API from the browser, you should get the feeling that the page did not load properly and the styling is missing.
Since we want to make sure that both the front-end and the REST-end work fine and offer the same functionality, it only makes sense to use the same test code for both of them. It sounds strange, right? The code that tests the UI should also test the API. It is achievable, provided that the architect pays as much attention on the tests as he does on the app’s code (which, sadly, is not always the case).
I explained here how to encapsulate the WebDriver instance in order to have clear and maintainable UI tests. In short, a good Selenium test should look like this:
Notice that the test code does not care where the username comes from. It could come from the UI, from a file or from an HTTP endpoint.
We only have to change the Github
implementation in order to test its API:
Now, of course, you shouldn’t see two sets of tests just for that line of code. In a real scenario, I would dictate it via a system property, or a Maven build profile.
Github
and all the other interfaces (e.g. UserProfile
, MainDashboard
etc)
are fluently coupled, so tests using these abstractions will gurantee that the endpoints are
navigable. Needless to say, same as in the Selenium case, the only public class should be RestfulGithub
.
Here is how RestfulGithub
could look:
And here is RsUserProfile
:
In this example, the /users/{username} endpoint has been called with my Github username. I used the jcabi-http client because it is much simpler and productive than, for instance, Apache HttpClient.
Finally, if you follow this approach you will have to invest some time in designing the testing framework, but you will earn the following:
- A truly surfable API, which respects the HATEOAS principle
- A single, maintainable, suite of tests for both the UI and the API
- By the time the tests are written you have a client library which you can deliver to any third party that wants to integrate with your services
What do you think? How do you make sure your API respects the right paradigm?