Simple, Rapid, Effective, and Scalable

by Brian Okken

Do less work when testing your Python code, but be just as expressive, just as elegant, and just as readable. The pytest testing framework helps you write tests quickly and keep them readable and maintainable—with no boilerplate code. Using a robust yet simple fixture model, it’s just as easy to write small tests with pytest as it is to scale up to complex functional testing for applications, packages, and libraries. This book shows you how.

Also available through all fine book sellers. I encourage you to ask at your local bookstore. 

It’s also available through Powells’, Amazon, Barnes & Noble,   Waterstones, …


Changes have happened in pytest since the book was published.

“Python Testing with pytest” is still the best way to learn pytest quickly and effectively. However, minor tweaks to the code will help you get a smooth learning experience.

The official errata from Pragmatic can be found at

However, the following are essential:

  1. Pin the tinydb version to 3.15.1. The API changed in the 4.x series of tinydb. However, the change doesn’t affect you learning pytest.
  2. Register the custom markers used in the book to avoid warnings.
  3. Change “pytest.config” to “config” in hook functions and add “config” to the hook function parameter list.
  • Warnings about unregistered custom marks. pytest now requires custom marks to be registered before use. This is a good change to pytest, but causes warnings when running the code from the book download page. Fix it by adding this small pytest.ini file in the tests directory wherever you see the warning. This affects chapters 2, 3, 5.
markers =
  • “config” is now a parameter to hooks. This affects chapter 5. This appears on page 101 and 103. Make the changes to the code in “ch5/c/tasks_proj/tests/” and “ch5/pytest-nice/”:
def pytest_report_header(config):
"""Thank tester for running tests."""
if config.getoption('nice'):
return "Thanks for running the tests."

def pytest_report_teststatus(report, config):
"""Turn failures into opportunities."""
if report.when == 'call':
if report.failed and config.getoption('nice'):
return (report.outcome, 'O', 'OPPORTUNITY for improvement')
  • “tinydb” version 3.15.1 is required, and not newer 4.x versions. This is a change to “” in “tasks_proj/”
install_requires=['click==7.1.2', 'tinydb==3.15.1'],
  • and again in “ch7/tasks_proj_v2/”:
install_requires=['click==7.1.2', 'tinydb==3.15.1', 'pytest', 'pytest-mock'],