Julio Biason
6 years ago
3 changed files with 71 additions and 1 deletions
@ -0,0 +1,69 @@ |
|||||||
|
+++ |
||||||
|
title = "Things I Learnt The Hard Way - Unit Tests Are Good, Integration Tests Are Gooder" |
||||||
|
date = 2019-06-19 |
||||||
|
|
||||||
|
[taxonomies] |
||||||
|
tags = ["en-au", "book", "things i learnt", "unit tests", "integration tests"] |
||||||
|
+++ |
||||||
|
|
||||||
|
The view of the whole is greater than the sum of its parts. And that includes |
||||||
|
tests for the whole compared to tests of single things. |
||||||
|
|
||||||
|
<!-- more --> |
||||||
|
|
||||||
|
First, I just don't want to into a discussion about what's the "unit in a unit |
||||||
|
test"[^1], so let's take the point that a unit test is a test that tests a |
||||||
|
class/function, not the whole system, which would require data flowing through |
||||||
|
several classes/functions. |
||||||
|
|
||||||
|
There are several libraries/frameworks that actually split this in a way that |
||||||
|
you can't test the whole. |
||||||
|
[Spring](https://spring.io/)+[Mockito](https://site.mockito.org/) is one of |
||||||
|
those combinations -- and one that I worked with. Due the bean container of |
||||||
|
Java, the extensive use of Beans by Spring and the way Mockito interacts with |
||||||
|
the container, it's pretty easy to write tests that involve only one class: |
||||||
|
You can ask Mockito to mock every dependency injection in one class and mock |
||||||
|
every injected class, simply using annotations. |
||||||
|
|
||||||
|
And this is cool and all. But the fact that we are making sure each class does |
||||||
|
what it does, it doesn't give a proper view of the whole; you can't see if |
||||||
|
that collection of perfectly tested classes actually solve the problem the |
||||||
|
system is responsible for solving. |
||||||
|
|
||||||
|
Once, in C++, I wrote an alarm system |
||||||
|
[daemon](https://en.wikipedia.org/wiki/Daemon_(computing)) for switches. There |
||||||
|
were three different levels of things the alarm system should do: It could |
||||||
|
only log the message of the incoming error, it could log the error and send a |
||||||
|
SNMP message, or it could log the error, send a SNMP message and turn a LED in |
||||||
|
the front panel on. Because each piece had a well defined functionality, we |
||||||
|
broke the system in three different parts: One for the log, one for the SNMP |
||||||
|
and one for the LED. All tested, all pretty. But I still had a nagging |
||||||
|
feeling that something was missing. That's when I wrote a test that would |
||||||
|
bring the daemon up, send some alarms and see the results. |
||||||
|
|
||||||
|
And, although each module was well tested, we still got one things we were |
||||||
|
doing it wrong. If we never wrote an integration test, we would never catch |
||||||
|
that. |
||||||
|
|
||||||
|
Not only that, but because we wrote a test that interacted with the daemon, we |
||||||
|
could get a better picture of its functionality and the test actually _made |
||||||
|
sense_ -- as in, if you read the unit tests, they seemed disconnected from |
||||||
|
what the daemon was expected to do, but the integration tests actually read |
||||||
|
like "Here, let me show that we actually did what you asked". And yes, this |
||||||
|
was akin to [Gherkin](/books/things-i-learnt/gherkin) tests, although I didn't |
||||||
|
know Gherkin at the time. |
||||||
|
|
||||||
|
Personally, I think over time integration tests are more important that unit |
||||||
|
tests. The reason is that I still have the feeling that unit tests check if |
||||||
|
the classes/functions have _adherence_ to the underlying _design_ -- Does your |
||||||
|
view can actually work without the controller? Is the controller using |
||||||
|
something from the model or using things that should be in the view? -- but |
||||||
|
adherence to the design gets better over time -- developers start using the |
||||||
|
layout from previous examples, so they capture the design by osmosis, while |
||||||
|
the big picture starts to get more and more complex, with lots of moving |
||||||
|
parts. |
||||||
|
|
||||||
|
{{ chapters(prev_chapter_link="/books/things-i-learnt/gherkin", prev_chapter_title="Gherkin Is Your Friend to Understand Expectations") }} |
||||||
|
|
||||||
|
[^1]: There is no "unit" in "unit tests". "Unit test" means the test _is_ a |
||||||
|
unit, indivisible and dependent only on itself. |
Loading…
Reference in new issue