Integration Tests are a Scam
If you still not using it, read this article and we will go through the process.
I gave a talk few weeks ago about this topic on a conference and understood that still a lot of people have not known about such kind of tests. So I will help you out to understand the problem and what we could do with that.
Understanding the problem
The larger application we have more time we need to run our test suite. I hope a lot of us wrote integration tests, where your test tool click around application and check business process and UI. But the larger application we have – more objects will be involved in this process, so when we go up to 10k LOC each and every integration test involves big amount of logic and spends a lot of time to pass through. Also when test is failing who could say which exactly piece of code is broken? But don’t get me wrong I still think that we need to write integration tests, but I think it will be better to run them only on CI for master branch in a background.
Lets look on a problem from different perspectives.
Purpose of Unit tests
When we write unit tests we always keep in mind object under test, this means:
These means that we mocking or stubbing all dependencies that we have in a code. If Unit tests intend to test only one object, and integration tests does not provide great feedback what could we do?
I’m not a good painter but I think its pretty easy to understand.
This pyramid was popularized by Martin Fowler. It shows how your test suite should looks like in terms of coverage. But here we are missing contract tests. So here is updated version.
So contracts test is a layer between integration tests and unit.
What the hack?
Basically contract is a communication between two objects in application.
And testing this contract implies checking dependency between this objects.
Practice! Finally! :)
For example we have two objects:
1 2 3 4 5 6 7 8 9 10 11
And we have tests for this objects
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
What will be if we do a refactoring for
Honda class. Because we think that method
speed not descriptive enough.
1 2 3 4 5
Also we change the test suite for this class
1 2 3 4 5 6 7 8 9
But take a look on our test for tracker class. Since we expecting method
speed. Class Honda will be not applicable for Tracker. But our test suite will be still passing.
1 2 3 4
Here is where contract test will be useful.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
In this way we will test communication between objects. We don’t need to know how this methods will be implementing but we expecting that this method will have such methods in their public interface.
You can always write such simple and easy tests by your own, but if you want to go beyond of that I recommend you to read about bogus. And watch this talks: J. B. (Joe) Rainsberger – Integration Tests Are a Scam, Ruby Conf 12 – Boundaries by Gary Bernhardt.