Python Testing with pytest, 2nd Edition
- 2nd edition is now in Beta, and purchasable as an eBook.
- There are 9 of 17 chapters in the Beta, available as an eBook.
- The physical book will be printed after all 17 chapters are complete, plus appendices, indexing, copy editing, final layout, etc.
- Final version expected Jan 2022
- Check this page you’re looking at for updates.
- Easy url is pytestbook.com. It redirects to right here.
- Pragmatic: The super awesome publisher that agreed to work with me and has tons of other great books.
- During the Beta phase, Pragmatic is the only place.
- After that, it’ll be available lots-o-places.
Questions about the 2nd Edition
Is the 1st edition obsolete?
- Absolutely not. With the errata above, it should still work great to teach you pytest.
So, then, why a 2nd edition?
Will there be a new stickers?
So, should I still buy the 1st edition?
- If you want a physical copy, that’s the only option until the 2nd edition is complete.
- I’m also still fielding questions about the 1st edition, and have one sitting on my desk.
- Why not both? :)
Send any other questions to me on Twitter @brianokken using #pytestbook.
Why a Second Edition?
This section is an excerpt from the Preface, which is available to read as a larger excerpt on the books Pragmatic page.
Both Python and pytest have changed since the first edition of this book was published in 2017. There have been updates to pytest that are now reflected in the book, such as:
- New builtin fixtures
- New flags
- The addition of package scope fixtures
There have also been updates to Python that are reflected in the book:
- The adoption of f-strings and
- The addition of dataclasses
Also, since publication of the first edition, I have taught many, many people about pytest, and I think I’ve learned how to be a better teacher. The second edition not only expands on what is covered in the first edition—it grew from 7 to 17 chapters!—but also it presents the material in what I think is a more gradual, digestible manner.
So what’s in all of these new chapters?
More on parametrization, markers, coverage, mocking, tox and continuous integration, and third-party plugins. All of these topics were covered in the first edition, but in this edition I expand that coverage. I pulled the discussion of parametrization into its own chapter and added a discussion of advanced parametrization techniques. I delve more deeply into markers and include an example of how to pass data from markers to fixtures (which is super cool). I also take you on a deeper dive into test coverage, mocking, and CI, and using and building your own plugins to extend pytest’s capabilities.
A discussion of test strategy. Feedback from the first edition was that the book was great for the mechanics of how to use pytest, but the “What test do I write?” information was a bit lacking. The new Chapter 7: Strategy is push in the right direction of what tests to write. A complete treatment of test strategy would be a book in itself; however, this chapter will get you started.
Information about the Python search path. A lot of readers reached out to me asking about how to get their tests to see their test code, and the first edition didn’t cover it. The project in this book, Cards, doesn’t have that problem because it’s an installed Python package. However, lots of user projects are applications or scripts or lots of other things that are not installed packages. This chapter offers a focused look at the problem and provides some solutions.
I moved coverage of command-line flags and configuration settings in general to their own chapter at the end of the book where, after you’ve learned the basics of pytest, you can check out the ton of cool options that can help you run your tests more efficiently and effectively.
Also, I consolidated the information about debugging test failures into a chapter of its own. In the last edition, this information was spread all throughout the book. It is my hope that when you are faced with a deadline and a failing test suite, bringing this information together into one chapter will help you figure an answer out quickly and ease some stress.
Finally, the example project changed. The first edition used a project called Tasks to illustrate how to use pytest. Now it’s called Cards. Here’s why:
- It’s easier to say out loud. (Try it. Say “tasks” three times, then “cards” three times. Right?)
- The new project itself is different because it uses Typer instead of Click for command-line functionality. Typer code is easier to read.
- The project also uses Rich for formatting the output. Rich didn’t exist (neither did Typer) when the first edition was written.
The code examples have also been simplified. The directory structure of the first edition code examples followed a progression of a possible test directory within a project, with most of the project removed. Seriously, I think it made sense to me at the time. In this edition, there is a project in its own directory,
cards_proj, with no tests. Then each of the chapters have test code (if appropriate) that either work on the one project, or on some local code. Trust me, I think you’ll agree that it’s way easier to follow along now.
Python Testing with pytest, 1st edition
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.
You’re local bookstore. Got a small bookstore in your area? They may have it. If not, I’m sure they could order it if you asked. While you are there, buy a different book from them. Local bookstores are a treasure, and should be supported.
Pragmatic: The second best choice after your local bookstore, buying directly through Pragmatic is the best way to support the people who worked hard to make this book.
Powells: One of my favorite bookstores in Portland. You should really check it out if you visit.
Amazon: <- That’s not an affiliate link, but this is if you’d like to support the author a bit. If you’d like to support a tad more than buying the book, head on over to Test & Code and consider becoming a Petreon supporter or talk to your company about sponsoring a few episodes.
Barnes & Noble: Yep. They still exist. I like to go there to ride the escalator, browse cookbooks, flip through some magazines, and have a coffee.
Waterstones: Never been there. But I hear there are quite a few in the UK.
… probably more, let me know and I’ll add to the list …
It’s also available to read online, through Medium
Read the 1st Edition Online
It’s available to read online, through Medium
Errata for the 1st Edition
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 https://devtalk.com/books/python-testing-with-pytest
However, the following are essential:
- 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.
- Register the custom markers used in the book to avoid warnings.
- 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.
[pytest] markers = smoke get
- “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/conftest.py” and “ch5/pytest-nice/pytest_nice.py”:
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 “setup.py” in “tasks_proj/setup.py”
and again in “ch7/tasks_proj_v2/setup.py”:
install_requires=['click==7.1.2', 'tinydb==3.15.1', 'pytest', 'pytest-mock'],