Stubble: Stub Testing for HTTP 23 Jul 2012

I’m pleased to introduce the first release of a new testing library called Stubble. Stubble was created to help developers test their applications’ communication with other applications over HTTP. It provides an easy way to set up an embeddable test server that will respond to requests you specify with associated responses. Stubble was written in Scala and runs on the JVM. Adding a request/response interaction looks like this:

val response = Response(HttpResponseStatus.OK, Some("content"))
server.addInteraction(Interaction(List(PathCondition("/")), response))

Background

To understand Stubble a little better, let’s rewind a bit. Why is this useful? Many of the applications I’ve come across communicate with other processes via HTTP. They may need to call external web services to integrate data from other systems, or they may need to make HTTP requests to initiate actions such as sending emails on the application’s behalf. At Cyrus Innovation we tend to have a culture of testing everything, but testing this part of our applications has always been difficult. In order to make sure our software correctly handles different conditions that arise in these interactions, we are faced with a couple of undesirable options.

The first, perhaps most obvious way to approach this is to set up an instance of the external system (for the purpose of this article, let’s call the system under test “internal” and anything outside it, particularly the HTTP server(s) with which it needs to interact “external”) with test data suitable to reproduce some important interactions. Depending on the degree of control you have over the other software, this may or may not be possible, but there are two big problems with this. Taking the external system through the states necessary to cover important cases may require driving through a user interface, or it may not be possible at all. At best, this is likely to be slow and complicated to set up. Worst of all, this creates an external dependency in your software’s build. If the server goes down, is reconfigured, or its version doesn’t match that expected by your software revision, your build fails and you’re left to figure out what happened. Was it a new bug in your software, or just a glitch in the other system? The main upside to this approach is that it can be used to provide fairly high fidelity to production use. Because you are using an actual instance of the external software, communicating between machines over an actual network, this test system is likely to be bug-for-bug compatible with the production system.

Another approach is to write a custom test system to simulate the external system. This often involves setting up an HTTP server and programming it to respond as the external system would. This provides a high level of flexibility, as you can tailor the test server exactly to match the needs of the tests you are writing, but can be tedious to integrate with your build and involves a lot of low level detail in managing HTTP interaction. After trying variations on this theme for several systems, I asked myself, “Why doesn’t something already exist that just lets me tell it what response to return when the request looks a certain way?” As it sometimes turns out in cases like this, my solution was to create that thing I was looking for myself.

Stubble takes care of the repeated, low-level details of this approach by providing a simple API for setting up HTTP responses that will be returned when HTTP requests are made that meet specified conditions. If you’ve ever used a stub or mock library such as Mockito for specifying interactions between objects, using Stubble to specify interactions with an HTTP server should be familiar.

The Stubble Approach

An interaction in Stubble is a list of request conditions and a response. When Stubble receives an incoming request, it runs through the interactions you’ve registered with it and returns the response of the first matching interaction. Stubble also comes with Maven integration to make it easy to run during integration testing in your build. Using Stubble can be as simple as starting the server in your test and adding an interaction to it, but the build integration provides a way to start up Stubble before your application starts for integration testing, so that any requests made throughout your application’s lifecycle can be handled by Stubble. A common example of this is data that’s loaded at startup. Using Stubble, you can provide enough boilerplate data to get the system running, then make calls to refresh or change data when you’ve set up new interactions inside a test.

A great way to get started with Stubble is to read the introductory material at the project page on GitHub. I hope you’ll check it out, and feel free to help out by logging any issues you have or submitting pull requests (though I invite you to send a note or open an issue before writing too much code).

comments powered by Disqus