Unit testing is a method of determining the correctness of a single function isolated from a larger codebase. The idea is that if all the atomic units of an application work as intended in isolation, then integrating them together as intended is much easier.
Unit testing is just one form of testing that works in combination with other testing approaches to wring out the bugs from a piece of software being developed. When several functions and classes are put together it's often difficult to determine the source of a problem if several bugs are occurring at the same time. Unit testing helps eliminate as many of the individual bugs as possible so when the application comes together as a whole the separate parts work as correct as possible. Then when issues arise they can often be tracked down as unintended consequences of the disparate pieces not fitting together properly.
There are many tools for creating tests in Python. Some of these tools, such as pytest, replace the built-in unittest framework. Other tools, such as nose, are extensions that ease test case creation. Note that many of these tools are also used for integration testing by writing the test cases to exercise multiple parts of code at once.
unittest is the built-in standard library tool for testing Python code.
pytest is a complete testing tool that emphasizes backwards-compatibility and minimizing boilerplate code.
nose is an extension to unittest that makes it easier to create and execute test cases.
Hypothesis is a unit test-generation tool that assists developers in creating tests that exercise edge cases in code blocks. The best way to get started using Hypothesis is by going through the well-written quickstart.
mimesis generates synthetic test data which is useful to apply in your tests.
testify was a testing framework meant to replace the common unittest+nose combination. However, the team behind testify is transitioning to pytest so it's recommended you do not use testify for new projects.
Unit tests are useful in every project regardless of programming language. The following resources provide a good overview of unit testing from several viewpoints and follow up with additional depth in testing Python-specific applications.
Introduction to Unit Testing provides a broad introduction to unit testing, its importance and how to get started in your projects.
Unit Testing Your Twilio App Using Python’s Flask and Nose is a detailed tutorial for using the nose test runner for ensuring a Flask application is working properly.
Unit testing with Python provides a high-level overview of testing and has diagrams to demonstrate what's going on in the testing cycle.
The Python wiki has a page with a list of Python testing tools and extensions.
An Extended Introduction to the nose Unit Testing Framework shows how this test runner can be used to write basic test suites. While the article is from 2006, it remains relevant today for learning how to use nose with your projects.
Revisiting Unit Testing and Mocking in Python
is a wonderful post with many code examples showing how and
why to use dependency injection and @property
to mock unit
tests.
Unit Testing Doesn’t Affect Codebases the Way You Would Think presents research on how unit testing impacts project code and ways that it does not. It is only one research report but the findings on more unit tests leading to higher Cyclomatic Complexity per method are interesting. Perhaps more tests are needed to keep a project running due to the increased complexity.
Python unittest with Robert Collins
is the transcript of an interview with Robert Collins who is a core
committer of unittest
.
Precise Unit Tests with PyHamcrest is a short tutorial on using the PyHamcrest assertion tool for unit testing.
Why most unit testing is a waste discusses how low risk unit tests rarely fail even as the code changes and why they do not matter as much to a project's health as many developers are led to believe based on the test-driven development dogma.
Writing Unit Tests for Django Migrations digs into code examples for testing Django data migrations.
The business case for unit testing makes arguments for management should buy into unit testing, including risk management and faster development timelines.
Unit testing often requires a bunch of fake data to use as inputs that otherwise are generated by users or oother parts of a system not under test. Fake data generation tools can help create data instead of having too write it all yourself. This post on generating fake data with Faker shows how to use the Faker tool with various seeds and outputs into your tests.
Unit Testing Applications that use Flask-Login and Flask-SocketIO explains how to set up a WebSockets unit test with a couple of common Flask libraries.