I need to stop saying "Unit Tests"
Tags: testing, discuss
Published: 2019-10-02 18:50:48

In my head there are two types of automated tests worth (in 99% of cases) talking about and I've usually called them:

 - Unit Tests
 - Integration Tests

Recently I've realised that using those names comes with so much baggage that I need a better name for them. When I'm talking about unit tests I mean any test that starts at some public entry point of the code, goes all the way through and ends at some boundary with an external system. This is either a mocked dependency or is the response of the function/method called initially. This response or call to an external system then has some expected properties asserted to be true. The unit test says nothing about how many functions/methods are called, how many classes might be involved - nothing. The only restriction is that you don't go into some external system such as a database, a Web API, a filesystem etc.

Is this not what everyone else thinks a unit test is?

An integration test, then, is a test to ensure your system can connect and integrate with the external systems we mocked out in the unit tests. We're not testing the external systems, only that we integrate successfully with them. If they're under your control you test them using unit tests inside that system.

Maybe I have the wrong idea and what I describe aren't unit tests and integration tests. Maybe there's a different name I should be using? I ask because I recently discussed unit tests with several people and got responses similar to:

> Oh, I don't bother with unit tests, they're a waste of time. I don't like testing one method/function/class at a time

or

>Unit testing? No, I prefer to test in the way the user will interact with the system

Both of these objections seem completely crazy to me. Why on Earth would I write a test that does one method at a time? And why would I test something in a way the user wouldn't use it?

One person I was talking to was actually complaining about how, in C#, interfaces couldn't have static functions defined on them (put aside how that would actually work in practise; the only thing I can think is making the class generic for that interface type or something) and this was a problem due to a "rule" their company had that said _every class should be mocked out for a unit test except the class under test_! This meant that any "Helper" class or "Calculation" class had to be mocked out, which meant it had to adhere to an interface, and therefore had to have instance methods even if it was more suited to being a static class. It also meant that internal classes (and private classes) were not able to be used, because you wouldn't be able to test them and would therefore have holes in your testing.

This is I do not understand.

Why do companies make rules like this? The tests shouldn't drive the architecture. If the class you're testing does everything in one big method or calls 50 other internal classes it _shouldn't change your tests_! Test _that_ class. Whatever it's up to, test it; and test it in the way a user would use your system. If a user shouldn't use some class because it is for code only inside your library then make it internal and don't test it directly. Please, don't make everything public _just_ for the tests.

So that's my rant. If people think I mean tests testing every method in the code individually when I say unit test then I need a better name for it. I'm open to suggestions. Spec test? BDD test? Behaviour test? All these seem to mean different things to different people.

---

Is this the meaning you ascribe to "unit test"? Do you have a better name for what I describe? Does your company have an rules similar to the the rule I described above? Do you agree with the rule above? Let me know - I really want to know if I'm just missing something obvious or if we do need a better name for these things free of the baggage.