The Importance of Unit Tests
Recently I've taken on a new job as a software engineer. As part of this job, I'm required to write unit tests for all my work. Up until this point in my software career, I haven't built tests for the code I've written. Personal projects or frontend websites have never truly warranted them. At first, I was frustrated that I had to spend extra work on writing code for my code, where was the fun in that? It wasn't until I went back to my own personal projects with a determination to write unit tests for all of them and get to 80% code coverage or better that I finally realized how important unit tests really are - they saved my code.
Example
Here is an example we can look at of a recent unit test I was writing and why it's important:
# My code logic
message = 'example error message'
raise ValueError(message)
LOGGER.critical(message)
# My test
...
message = 'example error message'
with pytest.raises(ValueError) as error:
my_module.my_function()
assert mock_logger.critical.called_with(message)
assert message == str(error.value)
This test fails - it took me a couple hours to find out why after playing with all sorts of ways to mock logging but that's beside the point. Did you spot why it failed? The logger never gets called because an error is raised first. This code has sat this way for months meaning that until I came back to this project and wrote unit tests for it, I wasn't aware of this bug in the code! As soon as I swapped the logger to come before throwing the error, the test passed which also means I fixed a longstanding bug. This is a small and seemingly trivial example but this same thing occurred over and over as I wrote tests for each of my projects.
Lessons Learned
Writing tests for my projects opened my eyes to MANY things I needed to be doing better. Here are just a few:
- Unit tests expose bugs that are either overlooked or may not always manifest themselves in normal end-to-end testing
- Unit tests expose unused code as you try to build test coverage - I found that much of my code could either be removed or reworked once I realized that I didn't need to test code that wasn't ever being used and therefore it could be deleted
- Unit tests expose functions that do not return anything at all or anything meaningful - I've since made sure that all my functions return something
- Unit tests guide you to write small units of testable code - much of my code in its first iteration wasn't testable because functions either did way too much (separation of concerns, limit scope, single assertion). Writing unit tests helped me refactor much of my code to be easier to read and maintain
- Unit test coverage reports push you to write better code because it ensures you can actually test everything. This in turn improves user confidence in your code as they know it's been tested - it can even be addicting to improve your test coverage on a project
I'd encourage anyone whether you are just starting your software career or are deep into it to write tests for your code. It exposes bugs, helps you write better software, and is incredibly insightful into what needs to change. Not to mention, it's much easier to do from the beginning than it is to come back to.
Comments
Please login to leave a comment.