Writing Unit Tests in Python — Part 1
It’s impossible and scary to imagine having an application without having unit tests.
Once I worked for a company where there was an application written in Python that had around half a million lines of code(which is unimaginable considering the fact that it’s Python code.) The scary part was that there were no unit tests for that gigantic code. This lead to developers having nightmares to touch that code.
Unit tests ensure that granular pieces of code work as expected. They ensure that any changes to the existing code doesn’t break when changes are made. Writing effective unit tests is by no means not an easy task if the functional code itself is not well written. By well written I mean the testability of the functional code. Consider writing unit tests for a function which has 1000 lines of code for example. It would be virtually impossible!
Every programming language has some library using which writing unit tests can be achieved. Python is not an exception. It provides a builtin library called “unittest" for that. Some of the important aspects to keep in mind when writing unit tests are below:
- No OS interaction
- No database communication
- No network communication
Any of the above interactions should be mocked or stubbed. There’s a new paradigm called “Data Driven Testing" which highlights the fact that minimal tests should be written by injecting data into tests rather than writing excessive tests for different kinds of data.
Each unit test should be written for a narrow scope of code under test. Additionally testing the failure conditions is equally important as much as testing successful conditions.
Typically unit tests should run very fast within fraction of seconds. Any unit test which takes many seconds usually signals any issues in test. This could be due to some database connection, or network connection etc., which means that the test should be refactored to mock those dependencies.
Applying Robert Martin ‘s clean coding principles to the code under test helps a great deal in writing focused, clean and manageable unit tests.
As application size grows, the number of unit tests grows proportionally and managing then become a challenge. Various aspects around managing unit tests are listed below:
- Effective directory structure for storing unit test files
- Test discoverability
- Filtering and running tests based on tags, directories or sub-directories etc.
- Generating unit test results metrics
- Generating code coverage metrics is another important consideration which I will cover in another blog
In my next blog we will take a simple Python code and write unit tests.
Related Links