pytest
fixtures¶Required boilerplate for using pytest
inside notebooks.
# Let's make sure pytest and ipytest packages are installed
# ipytest is required for running pytest inside Jupyter notebooks
import sys
!{sys.executable} -m pip install pytest
!{sys.executable} -m pip install ipytest
# These are needed for running pytest inside Jupyter notebooks
import ipytest
ipytest.autoconfig()
import pytest
Requirement already satisfied: pytest in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (7.3.1) Requirement already satisfied: tomli>=1.0.0 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest) (2.0.1) Requirement already satisfied: exceptiongroup>=1.0.0rc8 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest) (1.1.1) Requirement already satisfied: iniconfig in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest) (2.0.0) Requirement already satisfied: pluggy<2.0,>=0.12 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest) (1.0.0) Requirement already satisfied: packaging in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest) (23.1) [notice] A new release of pip available: 22.3.1 -> 23.1.1 [notice] To update, run: pip install --upgrade pip Requirement already satisfied: ipytest in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (0.13.1) Requirement already satisfied: ipython in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipytest) (8.12.0) Requirement already satisfied: packaging in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipytest) (23.1) Requirement already satisfied: pytest>=5.4 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipytest) (7.3.1) Requirement already satisfied: tomli>=1.0.0 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest>=5.4->ipytest) (2.0.1) Requirement already satisfied: iniconfig in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest>=5.4->ipytest) (2.0.0) Requirement already satisfied: exceptiongroup>=1.0.0rc8 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest>=5.4->ipytest) (1.1.1) Requirement already satisfied: pluggy<2.0,>=0.12 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pytest>=5.4->ipytest) (1.0.0) Requirement already satisfied: jedi>=0.16 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (0.18.2) Requirement already satisfied: appnope in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (0.1.3) Requirement already satisfied: pickleshare in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (0.7.5) Requirement already satisfied: stack-data in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (0.6.2) Requirement already satisfied: prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (3.0.38) Requirement already satisfied: backcall in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (0.2.0) Requirement already satisfied: pygments>=2.4.0 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (2.15.0) Requirement already satisfied: decorator in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (5.1.1) Requirement already satisfied: traitlets>=5 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (5.9.0) Requirement already satisfied: pexpect>4.3 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (4.8.0) Requirement already satisfied: matplotlib-inline in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from ipython->ipytest) (0.1.6) Requirement already satisfied: parso<0.9.0,>=0.8.0 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from jedi>=0.16->ipython->ipytest) (0.8.3) Requirement already satisfied: ptyprocess>=0.5 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from pexpect>4.3->ipython->ipytest) (0.7.0) Requirement already satisfied: wcwidth in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30->ipython->ipytest) (0.2.6) Requirement already satisfied: executing>=1.2.0 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from stack-data->ipython->ipytest) (1.2.0) Requirement already satisfied: asttokens>=2.1.0 in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from stack-data->ipython->ipytest) (2.2.1) Requirement already satisfied: pure-eval in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from stack-data->ipython->ipytest) (0.2.2) Requirement already satisfied: six in /Users/jerrypussinen/.virtualenvs/learn-python/lib/python3.10/site-packages (from asttokens>=2.1.0->stack-data->ipython->ipytest) (1.16.0) [notice] A new release of pip available: 22.3.1 -> 23.1.1 [notice] To update, run: pip install --upgrade pip
Similarly as you can parametrize test functions with pytest.mark.parametrize
, you can parametrize fixtures:
PATHS = ["/foo/bar.txt", "/bar/baz.txt"]
@pytest.fixture(params=PATHS)
def executable(request):
return request.param
%%ipytest -s
def test_something_with_executable(executable):
print(executable)
/foo/bar.txt ./bar/baz.txt . 2 passed in 0.01s
pytest.mark.usefixtures
¶pytest.mark.usefixtures
is useful especially when you want to use some fixture in a set of tests but you don't need the return value of the fixture.
%%ipytest -s
@pytest.fixture
def my_fixture():
print("\nmy_fixture is used")
@pytest.fixture
def other_fixture():
return "FOO"
@pytest.mark.usefixtures('my_fixture')
class TestMyStuff:
def test_somestuff(self):
pass
def test_some_other_stuff(self, other_fixture):
print(f'here we use also other_fixture which returns: {other_fixture}')
my_fixture is used . my_fixture is used here we use also other_fixture which returns: FOO . 2 passed in 0.01s
pytest
built-in fixtures¶Here are a couple of examples of the useful built-in fixtures, you can view all available fixtures by running pytest --fixtures
.
monkeypatch
¶Built-in monkeypatch
fixture lets you e.g. set environment variables and set/delete attributes of objects. The use cases are similar as with patching/mocking with unittest.mock.patch
/unittest.mock.MagicMock
which are part of the Python Standard Library.
Monkeypatching environment variables:
import os
def get_env_var_or_none(var_name):
return os.environ.get(var_name, None)
%%ipytest -s
def test_get_env_var_or_none_with_valid_env_var(monkeypatch):
monkeypatch.setenv('MY_ENV_VAR', 'secret')
res = get_env_var_or_none('MY_ENV_VAR')
assert res == 'secret'
def test_get_env_var_or_none_with_missing_env_var():
res = get_env_var_or_none('NOT_EXISTING')
assert res is None
.. 2 passed in 0.01s
Monkeypatching attributes:
class SomeClass:
some_value = "some value"
@staticmethod
def tell_the_truth():
print("This is the original truth")
def fake_truth():
print("This is modified truth")
@pytest.fixture
def fake_some_class(monkeypatch):
monkeypatch.setattr("__main__.SomeClass.some_value", "fake value")
monkeypatch.setattr("__main__.SomeClass.tell_the_truth", fake_truth)
%%ipytest -s
def test_some_class(fake_some_class):
print(SomeClass.some_value)
SomeClass.tell_the_truth()
fake value This is modified truth . 1 passed in 0.01s
def word_count_of_txt_file(file_path):
with open(file_path) as f:
content = f.read()
return len(content.split())
%%ipytest -s
def test_word_count(tmpdir):
test_file = tmpdir.join('test.txt')
test_file.write('This is example content of seven words')
res = word_count_of_txt_file(str(test_file)) # str returns the path
assert res == 7
. 1 passed in 0.01s
@pytest.fixture(scope="function")
def func_fixture():
print("\nfunc")
@pytest.fixture(scope="module")
def module_fixture():
print("\nmodule")
@pytest.fixture(scope="session")
def session_fixture():
print("\nsession")
%%ipytest -s
def test_something(func_fixture, module_fixture, session_fixture):
pass
def test_something_else(func_fixture, module_fixture, session_fixture):
pass
session module func . func . 2 passed in 0.01s
@pytest.fixture
def some_fixture():
print("some_fixture is run now")
yield "some magical value"
print("\nthis will be run after test execution, you can do e.g. some clean up here")
%%ipytest -s
def test_something(some_fixture):
print('running test_something')
assert some_fixture == 'some magical value'
print('test ends here')
some_fixture is run now running test_something test ends here . this will be run after test execution, you can do e.g. some clean up here 1 passed in 0.01s
@pytest.fixture(autouse=True)
def my_fixture():
print("\nusing my_fixture")
%%ipytest -s
def test_1():
pass
def test_2():
pass
using my_fixture . using my_fixture . 2 passed in 0.01s