Practical test doubles: adding stubs to TestLink Java API

"Test Double is a generic term for any case where you replace a production object for testing purposes" [1]. There are different types of Test Doubles: Dummy, Fake, Stubs, Spies and Mocks. In this post we will see a practical example of adding stubs to TestLink Java API.

Stubs are objects that return canned answers to calls during tests [1]. This is useful specially when you have a system that communicates with different resources such as databases, web services, XML-RPC services and so on.

TestLink Java API is a small Java project created to act as an interface between TestLink XML-RPC API and a client program written in Java.

Starting on the wrong foot

You know when sometimes you start a project just to suppress certain necessity and then write down a long TODO list? Well, sooner or later you will have to start working on those items. When I wrote the first version of the API I was writing Jenkins TestLink Plug-in, and had a priority project that depended on both tools to be deployed to a customer's site. Due to the deadlines and priorities, the tests in TestLink Java API were made to run directly against a test instance of TestLink.

After that the code was open sourced and, as was expected, bugs, features and enhancements started to be requested by users. You can imagine many drawbacks in this approach, such as newcomers to the project would need to install a test instance of TestLink with equal set up parameters, and to not mention how hard it would be to have Continuous Integration in a service provider like CloudBees, where I wouldn't have TestLink installed.

On the right foot now...

So the main issue regarding the project build was the direct access to the TestLink XML-RPC API. A neat solution for it was to use Stubs during tests. The idea was to create a stubs capable of, given a call to TestLink XML-RPC, it would then answer with a canned XML.

I thought I would have to dig into Jetty, Winstone or some small web server by myself and include it to the project, but fortunately somebody else [2] has passed by it and blogged about his experience with some sample code.

The approach used in TestLink Java API was quite similar to the one described in [2]. I used WireShark to save the XML returned by TestLink XML-RPC API and when I create an instance of the web server, it knows which XML it must return to the caller object. Below you can see BaseTest, a class used as base for new tests.

Now anybody can simply execute mvn clean test to build the project. It won't connect to any instance of TestLink, and all the tests will be executed in less then one minute. When there is a new release of TestLink, I will need to update my XML files generated with Wireshark (I will automate it with Python or Perl) and then test and work on the differences.

This approach can be used to test web services, XML-RPC servers and any similar environment. Hope it helps somebody else too. Cheers! :D

[1] http://martinfowler.com/bliki/TestDouble.html

[2] http://olafsblog.sysbsb.de/lightweight-testing-of-webservice-http-clients-with-junit-and-jetty