At PyConDE Berlin 2019 Florian Bruhin gave a really nice session about testing with pytest, which I try to recap here.
Table of Contents
Writing Tests
If You want to work with pytest you can install it via:
pip install pytest
When you know basic python unittest fixtures, good news ahead:
pytest is compatible and will run your old unittest classes as well, but pytest doesn’t need to have a testclass derived from some subclass.
It is sufficient to have a single python file which name starts with test_ containing a function which name also starts with test_
def test_stuff():
x = 5.0
assert x == 5
That’s all You need!
Autodiscovery
If you run pytest from the command line it will automatically discover tests which cohere to this naming convention like unittest -discover
pytest
Select test cases
You can specify the tests to be run by module::test_function or by module::test_class::test_method e.g.
pytest test_sort_algortihms.py::TestSortAlgorithms::test_python_sorted
As an alternative you can use the option -k “test_case_name” to glob testcases.
Execution time
If you pass --durations=0
execution time for all tests will be reported.
Useful command line arguments
When learning pytest, it is good to learn some command line flags as well
- -h : help
- -k “<name_of_test>” : glob test name
- -x : quit on first error
- – -pdb : start debugger on error
- -v : increase verbosity
- -s : show print output
- -rf : reason for failure
- -rs : reason for skipping
- -m <marker_name> : run only marked tests
- –fixtures : show fixtures in modules
Configuration via file
You can save your preferences for running pytest in a file called pytest.ini
[pytest] addopts = -x --durations=0 -vv
Understanding Fixtures
Fixtures are pytest’s equivalent to setUp methods from unittest with the difference that you can define when they should be used.
import pytest
@pytest.fixture
def some_value():
return 42
def test_function(some_value):
assert some_value == 42
After declaring a fixture with decorator @pytest.fixture you can use this special function as a parameter to your test functions.
Fixture scope
Without any further definition a fixture function is called before every function it is used in. When You do some heavy lifting in a fixture and you want to reuse that you can specify the module scope so that the fixture function just runs once per module
@pytest.fixture(scope="module")
If you even want to instantiate a fixture once per session this is also possible with
@pytest.fixture(scope="session")
Next part pytest Tutorial – Part 2