We are big fans of pytest and use it as our default Python testing tool for work and open source projects. For this month's Python column, we're sharing why we love pytest and some of the plugins that make testing with pytest so much fun.
What is pytest?
As the tool's website says, "The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries."
Pytest allows you to define your tests in any file called
test_*.py and as functions that begin with
test_*. Pytest will then find all your tests, across your whole project, and run them automatically when you run
pytest in your console. Pytest accepts flags and arguments that can change when the testrunner stops, how it outputs results, which tests are run, and what information is included in the output. It also includes a
set_trace() function that can be entered into your test; this will pause your tests and allow you to interact with your variables and otherwise "poke around" in the console to debug your project.
One of the best aspects of pytest is its robust plugin ecosystem. Because pytest is such a popular testing library, over the years many plugins have been created to extend, customize, and enhance its capabilities. These eight plugins are among our favorites.
pytest-sugar changes the default look and feel of pytest, adds a progress bar, and shows failing tests instantly. It requires no configuration; just
pip install pytest-sugar, run your tests with
pytest, and enjoy the prettier, more useful output.
pytest-cov adds coverage support for pytest to show which lines of code have been tested and which have not. It will also include the percentage of test coverage for your project.
pytest-picked runs tests based on code that you have modified but not committed to
git yet. Install the library and run your tests with
pytest --picked to test only files that have been changed since your last commit.
pytest-instafail modifies pytest's default behavior to show failures and errors immediately instead of waiting until pytest has finished running every test.
A brand-new pytest plugin that limits the output to just the things you need.
tldr stands for "too long, didn't read"), like
pytest-sugar, requires no configuration other than basic installation. Instead of pytest's default output, which is pretty verbose,
pytest-tldr's default limits the output to only tracebacks for failing tests and omits the color-coding that some find annoying. Adding a
-v flag returns the more verbose output for those who prefer it.
pytest-xdist allows you to run multiple tests in parallel via the
pytest -n 2, for example, would run your tests on two CPUs. This can significantly speed up your tests. It also includes the
--looponfail flag, which will automatically re-run your failing tests.
pytest-django adds pytest support to Django applications and projects. Specifically,
pytest-django introduces the ability to test Django projects using pytest fixtures, omits the need to import
unittest and copy/paste other boilerplate testing code, and runs faster than the standard Django test suite.
django-test-plus isn't specific to pytest, but it now supports pytest. It includes its own
TestCase class that your tests can inherit from and enables you to use fewer keystrokes to type out frequent test cases, like checking for specific HTTP error codes.
The libraries we mentioned above are by no means your only options for extending your pytest usage. The landscape for useful pytest plugins is vast. Check out the Pytest Plugins Compatibility page to explore on your own. Which ones are your favorites?