Python Friday #47: (Built-in) Fixtures in Pytest

Fixtures are a powerful feature in pytest. You can write your own fixtures as a replacement for setup and teardown methods or use the built-in ones to access common functionality. This post has a closer look to the fixtures that come directly with pytest and shows you how to use them.

This post is part of my journey to learn Python. You can find the other parts of this series here.

 

What fixtures come with pytest?

My pytest in version 5.4.3 comes with 19 built-in fixtures. You can find the full list here or run this command to see the list in your terminal:

===================== test session starts ======================
cache
Return a cache object that can persist state between testing sessions.

capsys
Enable text capturing of writes to sys.stdout and sys.stderr.

caplog
Access and control log capturing.

… (and many more)

 

How to use them

To use a fixture, we need pass its name as a parameter to our test function. To access the request fixture, we can write our function like this:

When we run our tests, pytest will check if there is a fixture with the name of request and if so, will put an instance of request into our test function. This feature works like a simple dependency injection container for your test code.

===================== test session starts ======================
platform win32 — Python 3.8.1, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python
plugins: cov-2.10.1, html-2.1.1, metadata-1.10.0
collected 1 item

test_fixtures.py **found: 1**
**failed: 0**

.

The request fixture allows us to ask pytest about the test execution and access things like the number of failed tests. You may use this fixture when you need to add specific clean-up code for resources you need to test your code.

 

Access the captured system output

If you run pytest without the -s option, the output to stdout/stderr gets captured by pytest. What is annoying at first has its benefits. We can use this feature and test code that writes to the console – without us refactoring it first to write to a file. All we need to do is to pass the capsys fixture to our test method:

With readouterr() we get a tuple of stdout and stderr back. We can check the output for errors with the err property (given the code we test writes errors to the stderr output):

 

Get a temporary directory

Sometimes we need a temporary place to store a file. While we could come up with our own logic, the tmpdir and tmp_path fixtures are much simpler. With tmp_path you get a pathlib/pathlib2.Path object while tmpdir gives a py.path.local object. Depending on what you want to do with the temporary path you can use either one of those fixtures:

If you run these tests you see that pytest creates a different directory for each test function:

===================== test session starts ======================
platform win32 — Python 3.8.1, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python
plugins: cov-2.10.1, html-2.1.1, metadata-1.10.0
collected 6 items

test_fixtures.py
A: C:\Users\jgraber\AppData\Local\Temp\pytest-of-jgraber\pytest-27\test_a_temp_fileA0
.
B: C:\Users\jgraber\AppData\Local\Temp\pytest-of-jgraber\pytest-27\test_a_temp_fileB0
.

You can modify the base of the temporary directory with this command line argument:

===================== test session starts ======================
platform win32 — Python 3.8.1, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: D:\Python
plugins: cov-2.10.1, html-2.1.1, metadata-1.10.0
collected 6 items

test_fixtures.py
A: D:\Python\DEMO\test_a_temp_fileA0
.
B: D:\Python\DEMO\test_a_temp_fileB0
.

Be aware that pytest will not clean-up those temporary directories, that is a task you have do to.

 

Next

Those are the basics you need to know to work with the built-in fixtures of pytest. The same principles of passing fixtures to your test function and the dependency injection part will come up again with our own fixtures. Before we can look at them, we need to make a little detour to the yield statement.

3 thoughts on “Python Friday #47: (Built-in) Fixtures in Pytest”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.