mardi 14 octobre 2014

Testing with web services

When you want to create automated tests for your application or to do TDD, your tests should fulfill these conditions:

  • cover the overall application,
  • run as fast as possible.

The former condition relies on the latter since if your tests are slow, you won't run them often and inevitably introduce regressions.

Debate about system testing, integration testing and unit testing is not that important. The important thing is to have the tests run fast, in order to run them often without losing focus while you TDD.

This can be hard to achieve when you call web services since:

  • using network is slow,
  • your WS provider may be used by several people or teams (that's my situation nowadays)
  • you can have limited access, for instance in case of a non-free service.

It is then necessary for you to decouple things. Your job is to test your own code, not the network infrastructure nor the third party service provider. To do so, consider studying the concept of hexagonal architecture. External services should be considered as plug-ins belonging to a distinct context from the core of your application.

Your goal is to make your application call methods on interfaces instead of directly call instances of service proxies. The proxies should be injected by an external system to your application. Think Spring IoC, a main or a test method. This way, you can mock all your service proxies, make them check what you pass to them and control the responses.

Mocks should implement contract verification. For instance, control are the mandatory parameters to send to the service method in order to make it work normally. If you call the right method, following its contract, there's no reason for the thing to go wrong, isn't it?

It's easier to write than do it in real life. Time spent to mock all the external can be quite long. In some case, service contract is not documented so you have to explore to discover it by yourself.

Moreover, the principle can be hard to understand by junior developers or your manager. How can you be sure that the whole thing work if you're not testing end to end? Why not just calling the service, even if testing can take a minute?

In my case, results speak by themselves. The development platform response time is increasing over time and we have no control of it. Some days, the server is down for minutes or hours. Some of our integration tests take more than one minute to run. That's not acceptable in development phase. Isolation tests run in a fraction of second. I have between 20 and 30 webservices to mock, its a true pain, but take one or to hours to write mocks realy worth it. It allows me to write more tests and run them often. To make it short, it allows me to TDD in a decent way.

Further watching: