Effective Python Testing With Pytest

Effective Python Testing With Pytest https://realpython.com/pytest-python-testing/ 2022-06-22T14:00:00+00:00 In this tutorial, you'll learn how to take your testing to the next level with pytest. You'll cover intermediate and advanced pytest features such as fixtures, marks, parameters, and plugins. With pytest, you can make your test suites fast, effective, and less painful to maintain.

Testing your code brings a wide variety of benefits. It increases your confidence that the code behaves as you expect and ensures that changes to your code won’t cause regressions. Writing and maintaining tests is hard work, so you should leverage all the tools at your disposal to make it as painless as possible. pytest is one of the best tools that you can use to boost your testing productivity.

In this tutorial, you’ll learn:

  • What benefits pytest offers
  • How to ensure your tests are stateless
  • How to make repetitious tests more comprehensible
  • How to run subsets of tests by name or custom groups
  • How to create and maintain reusable testing utilities

How to Install pytest

To follow along with some of the examples in this tutorial, you’ll need to install pytest. As most Python packages, pytest is available on PyPI. You can install it in a virtual environment using pip:

PS> python -m venv venv PS> .\venv\Scripts\activate (venv) PS> python -m pip install pytest 
$ python -m venv venv $ source venv/bin/activate (venv) $ python -m pip install pytest 

The pytest command will now be available in your installation environment.

What Makes pytest So Useful?

If you’ve written unit tests for your Python code before, then you may have used Python’s built-in unittest module. unittest provides a solid base on which to build your test suite, but it has a few shortcomings.

A number of third-party testing frameworks attempt to address some of the issues with unittest, and pytest has proven to be one of the most popular. pytest is a feature-rich, plugin-based ecosystem for testing your Python code.

If you haven’t had the pleasure of using pytest yet, then you’re in for a treat! Its philosophy and features will make your testing experience more productive and enjoyable. With pytest, common tasks require less code and advanced tasks can be achieved through a variety of time-saving commands and plugins. It’ll even run your existing tests out of the box, including those written with unittest.

As with most frameworks, some development patterns that make sense when you first start using pytest can start causing pains as your test suite grows. This tutorial will help you understand some of the tools pytest provides to keep your testing efficient and effective even as it scales.

Less Boilerplate

Most functional tests follow the Arrange-Act-Assert model:

  1. Arrange, or set up, the conditions for the test
  2. Act by calling some function or method
  3. Assert that some end condition is true

Testing frameworks typically hook into your test’s assertions so that they can provide information when an assertion fails. unittest, for example, provides a number of helpful assertion utilities out of the box. However, even a small set of tests requires a fair amount of boilerplate code.

Imagine you’d like to write a test suite just to make sure that unittest is working properly in your project. You might want to write one test that always passes and one that always fails:

# test_with_unittest.py from unittest import TestCase class TryTesting(TestCase): def test_always_passes(self): self.assertTrue(True) def test_always_fails(self): self.assertTrue(False) 

You can then run those tests from the command line using the discover option of unittest:

(venv) $ python -m unittest discover F. ====================================================================== FAIL: test_always_fails (test_with_unittest.TryTesting) ---------------------------------------------------------------------- Traceback (most recent call last):  File "...\effective-python-testing-with-pytest\test_with_unittest.py",  line 10, in test_always_fails  self.assertTrue(False) AssertionError: False is not true ---------------------------------------------------------------------- Ran 2 tests in 0.006s FAILED (failures=1) 

As expected, one test passed and one failed. You’ve proven that unittest is working, but look at what you had to do:

  1. Import the TestCase class from unittest
  2. Create TryTesting, a subclass of TestCase
  3. Write a method in TryTesting for each test
  4. Use one of the self.assert* methods from unittest.TestCase to make assertions

That’s a significant amount of code to write, and because it’s the minimum you need for any test, you’d end up writing the same code over and over. pytest simplifies this workflow by allowing you to use normal functions and Python’s assert keyword directly:

Read the full article at https://realpython.com/pytest-python-testing/ »

[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]