6. Pytest

6.1. Why?

  • Detailed info on failing assert statements (no need to remember self.assert* names);

  • Auto-discovery of test modules and functions;

  • Modular fixtures for managing small or parametrized long-lived test resources;

  • Can run unittest (including trial) and nose test suites out of the box;

  • Python 3.5+ and PyPy 3;

  • Rich plugin architecture, with over 315+ external plugins and thriving community;

def my_func(number):
    return number + 1

def test():
    assert my_func(3) == 4

6.2. Running

python -m pytest my_file.py
python -m pytest -v my_file.py
python -m pytest -v -s my_file.py

6.4. pytest.raises

with raises(ZeroDivisionError):
    1/0

with raises(ValueError, match='must be 0 or None'):
    raise ValueError("value must be 0 or None")

with raises(ValueError, match=r'must be \d+$'):
    raise ValueError("value must be 42")

6.5. Fixtures

  • Fixtures are requested by test functions or other fixtures by declaring them as argument names.

  • It’s to think of fixtures as a set of resources that need to be set up before a test starts, and cleaned up after.

  • @pytest.fixture(scope='module')

import pytest

@pytest.fixture()
def setUp():
    print('\nsetup')

def test_1_that_needs_setup(setUp):
    print('test_1_that_needs_setup()')

def test_2_that_does_not():
    print('\ntest_2_that_does_not()')

def test_3_that_does(setUp):
    print('test_3_that_does()')
$ python -m pytest -v -s tmp7.py
# ====================================== test session starts ======================================
# platform darwin -- Python 3.7.4, pytest-5.1.2, py-1.8.0, pluggy-0.13.0 -- /Users/Developer/.venv-3.7.3/bin/python
# cachedir: .pytest_cache
# rootdir: /Users/Developer/book-python
# collected 3 items
#
# tmp7.py::test_1_that_needs_setup
# setup
# test_1_that_needs_setup()
# PASSED
# tmp7.py::test_2_that_does_not
# test_2_that_does_not()
# PASSED
# tmp7.py::test_3_that_does
# setup
# test_3_that_does()
# PASSED
#
# ======================================= 3 passed in 0.01s =======================================