I’m still used to hearing from software developers that unit tests are a waste of time. Actually, I think this way of thinking is caused by a superficial understanding about unit tests (or even about OOP) and the fact that they don’t want to add a new step on their process of software development to write tests, for something that they can’t understand its benefits.
Here is the stuff I’m used to hearing about unit testing of people who aren’t used to writing them:
- “Takes too much time to write a new piece of code”
- “Needs to code “twice”“
- “Won’t prevent all bugs”
- “Refactoring takes longer time because needs to fix broken tests”
- “Good developers don’t need to test” (this one is my preferred – NOT)
Actually, some of those disadvantages are true in some cases, but people who don’t like change, normally use them as a excuse to don’t change, in other words, they will negate the effectiveness of something in all cases by creating a conception about something based on its exceptions (or disadvantages).
People must understand that every change has its trade-off and before you say that something doesn’t work, you should analyze the pros and cons of that change and see if this change applies to your problem. And remember, any change is painful on beginning, but sometimes are necessary for evolution, in other words, the bad feeling about writing unit tests is only at the beginning, because if you are not used to coding with some good design practices, you will receive constant feedback about that. When you get used to it, you will design your code better, will start to see their advantages and will get more comfortable to write unit tests.
Let’s try to analyze some pros and cons of unit testing, based on what people usually say.
Quick and constant feedback about design of code (and even about some bugs)
This is the major benefit from unit tests. When you start writing unit tests you will receive quickly feedback about the design of you code. Normally, this is the preferable reason for most people to giving up with unit tests.
When is getting too hard to write a unit tests for a single method on a class, maybe it is because the design of the code is not good (maybe you are violating some of the SOLID principles) and this is the perfect time to keep your code clean and maintainable.
Sometimes the code abstraction of a complex business rule will result on huge classes and methods. If you apply good unit tests with some BDD techniques and SOLID principles, you won’t just ensure the behavior of this part of the system, you will also let it easy to understand.
“There appears to be a synergy between testability (at the unit level) and good design. If you aim for testability and make some good choices, design gets better. If you aim for good design, your design becomes more testable.”
If you have written unit tests covering most part of the possible resulting behaviours of your classes, you will certainly prevent several bugs.
If you have written good unit tests that covers your methods and classes that you are trying to change, it will let you to feel safe on refactoring the code, because if you break something, tests will warn you.
Can lead to a better design of code
With constant feedback, you can keep the design of code better. But remember that if you don’t write good code and don’t mind on writing huge unit tests for a single method, your design of code won’t get better.
Maintainability gets easier
If you are implementing good SOLID principles on your code and using good names to your classes, methods and variables, when you are refactoring it, based on feedback of unit tests, you will keep your code easier to understand.
For those people who don’t admit that are writing a bad code, constant feedback is really painful, but, as I said before, it’s usually because of the learning curve (or it’s about ego).
Another interesting fact is that some people usually say that refactoring a piece of code, covered by some unit tests, takes too much time to finish, because it will break almost the entire test suite. Actually this may be caused by other symptoms. Maybe it’s because your tests aren’t well written.
Won’t prevent all bugs
Yes, it won’t prevent you to create software without any bug, because some behaviors are unpredictable, especially if you have integrations with other systems, but, with good unit tests, you can predict several behaviors and test your code to handle them.
Time to deliver may be longer
You will really need to write more lines of code: the production code and the test code. But, what people don’t want to see is that this trade-off is to prevent the code rot. If you don’t pay attention to this, the cost (and time) of maintenance of this system will get really high and you will be forced to rewrite this system because nobody can maintain it.
Good developers don’t need to test
Being a good software developer doesn’t mean you will never make mistakes. So, this is not an excuse for you don’t do something. If you have enough experience to say that you can write good code, then you must understand the importance of a good design of code for big and collaborative applications, to avoid the code rot.
As you could see, writing unit tests doesn’t mean that a software is going to be bugless and easy to maintain. Unit tests are a tool that shows you where the problem is in the design of the code (and of course for testing behavior purposes). YOU should do something to handle it. So, if you want to use them only on a critical part of your system, it is up to you. You should prioritize what problems on your systems you want to avoid. You should only use them when you see their need.
What you should keep in your mind is that you will always need to analyze what problems you need to solve. Never say that something is not good at all, because of its disadvantages, especially if you don’t have enough knowledge to assert that.
My humble suggestion is: If you are working on a simple and small application (or even a script), that only one person maintains it and it is easy to keep it updated, you may not need to use unit tests. But, if you are working on a big application for your organization, that is in constant evolution, that many people are contributing, and that needs to keep its cost of change and its lead time controllable, then, I really suggest you to use unit tests to try to avoid that this application will have needed to be rewritten because its cost of change (maintainability) got incredibly high and impracticable.