Recently I had a very interesting discussion with a colleague about why to test software at all. Doesn’t it make us slower? Isn’t it more important to get feedback from users quickly by drafting the software and then adding tests subsequently?
At first I was: What the hell? No tests?
But then my colleague actually got a point. Writing tests makes software development a lot slower than it could theoretically be. Writing tests takes time. Also creating a good test setup takes time. And - yes - maybe getting feedback from users quickly is a lot more important than creating tests for the sake of it.
So - does that mean no tests from now on?
As usual in software development we are dealing with probabilities of success and failure. Here’s my take on tests:
Respect the test pyramid
When you write tests make sure you write unit tests. Only use the real class under test and mock out everything else. There is a testing pyramid for a reason.
You can run projects without end to end tests. But I’ve never seen any project succeed without a suite of meaningful unit tests.
Testing is actually improving your own code
By writing a test and making the class under test “testable” in the first place you will improve your code. The tests will talk to you.
If something is hard to test this means it may not be very good code. Refactor until stuff is testable aka modular and go on.
Tests give you safety when refactoring
From time to time software needs some refactoring. Maybe a new feature has to be introduced where you need to rewrite substantial parts of the code. Or an external library has to be replaced by something else.
Tests give you the confidence that you can touch the code and that changes do not destroy parts of the application that you not even think about.
When working in a team you need tests
If you are alone you may not need tests. But if there are at least two developers you will from time to time run into merge conflicts. Some teams fear merge conflicts like hell and treat them as failure. It can’t be farther from the truth.
Merge conflicts are part of software development and will always be part of your work as engineer if you are working in a team and a project of reasonable size.
Treat merge conflicts as something positive. And you know what? Tests again help to resolve those conflicts - and they tremendously help to make sure software runs after a merge.
Tests are NOT a means to an end - and code coverage sucks
Writing tests just to write tests does NOT make sense. It does NOT make sense to just measure the code coverage of your tests and conclude what work your engineers are doing.
Code coverage does NOT measure whether your tests do test something meaningful. If you want me to increase the code coverage I can do it - I can even increase code coverage to 100% - by writing meaningless tests.
But this is not what you want. You want a working project.
And therefore you can of course trade off the amount of tests to write, or what tests to write with an early start of the project and eg early feedback of real users. It does of course not make sense to produce a very nicely tested software that nobody uses.
But I’d still say: Good modular unit tests are indispensable for a software of reasonable size written by a team of at least two. You may compromise on the amount of unit tests. You may well leave out any non-unit tests (medium tests and large tests in Google speech).
Stack Overflow eg boasts that they are not writing many tests - “because of their active community and heavy usage of static code”. Yes - you can do that of course if you offload testing to your community and clients.
A policy to follow: If there is a bug, fix it and write a test
That’s something that always makes sense: You can write only a few tests intentionally. But if you discover a bug - make it a practice to write a test against it - on the lowest possible level. And that means NOT writing an end to end test by default.
Update 2022-11-29 - Stack Overflow now proud of their tests
As mentioned above - Stack Overflow was very proud that they did not write (m)any tests. But that changed. In one of their latests blog posts they described their new approach.
They also clearly said that they simply cannot use paying customers to find bugs any more. Unit tests are a must - even in frontend code.
- Image on top from Chris Liverani at https://unsplash.com/photos/ViEBSoZH6M4