Wednesday, April 30, 2008

Thoughts on integration testing

Everybody (pretty much) knows what they mean by unit testing, and on the whole, I would expect most people to have a broadly speaking common understanding of what this means. Unit testing of course involves testing the behaviour of a particular unit of code (e.g. Java class) in isolation.

When it comes to integration testing, it's probably not quite as clear cut. For example, does a test need to cover an entire use case to be considered an integration test? What about a database test which only covers a single JDBC-based method? Is this an integration test?

For me, the key point of distinction is the realness of the test. An integration test is such because it embodies the real behaviour of the system. The more a test relies on simulating aspects of a system's behaviour, the less real it is, and further it moves away from being an integration test.

This brings me on to the question of what is an integration test in a Spring/Impala environment. Here, an integration test will typically always involve using a real Spring application context rather than constructing the fixtures programmatically. It will involve involve connecting to a real database, rather than an in-memory test database (e.g. HSQLDB). It will make limited if any use of mock objects. All in all, integration tests in a Spring environment are closer in behaviour to that exhibited by the real system.

Another question worth addressing is this: what is the relative value of integration tests versus unit tests? A working set of integration tests gives me much more confidence than a set of unit tests which are not backed by integration tests.

One difficulty with integration tests is that they are much less direct than testing using unit tests. It's harder to establish the precise link between the tests and what is actually getting tested. On the plus side, you can get a lot of test coverage with very little code through integration tests.

The other problem with integration tests is, of course, they can be painful to write. Specifying dependencies required for integration tests can be fiddly and time consuming. Also, integration tests can be slow to run. For these reasons, some developers shy away from integration tests, preferring to rely on unit tests plus manual testing of use cases using the deployed application. The big cost is that quality of the testing regime in these circumstances is much diminished, making it much easier for bugs to slip through.

With Impala, integration tests are so easy to write and quick to run, that there really are no excuses. Integration tests are easy to write because dependencies are expressed at a high level through composition of modules. They are quick to run because of the dynamic module loading support used by the interactive test runner, and the efficient way that suites of unit tests are managed within Eclipse. See this wiki page for more details.

No comments: