Book Review: Python Testing with Pytest

Posted on 2022-08-01 in review • 4 min read

It’s a bit embarrassing that I haven’t posted anything in more than a year. I need to get back on track with at least semi-regular blogging. What better way to do so than to review the first hardcopy book I’ve purchased in 10+ years?

Python Testing With pytest

Cover of the book Python Testing with pytest, second edition

I’ve been aware of this book for years. It was written by Brian Okken, who co-hosts the Python Bytes podcast. I had some expendable income earlier this spring and decided that the time was right to pick up a copy. Timing was on my side, as the 2nd edition had just been released.

My Take

Working through this book was a fantastic experience. It reminded me of earlier in my career when I had started to learn some CAD software on my own. My experience with pytest was similar - I was able to function and had picked up the basics ok, but there was a whole world of additional functionality that I wasn’t even aware of. I could hear Brian’s voice coming through in the prose and it very much reminded me of learning from a senior-level expert. In the case of this book, Brian strikes a great balance between making valuable suggestions without being overly prescriptive.

I mostly tried to work through a chapter at a time. Initially I did this purely by reading while away from the computer. This meant that I got through the content fairly quickly, but didn’t retain a whole lot. As expected, going through the content a second time by actually working the examples in python was quite valuable. I would say I spent roughly half of the time using the example code more or less verbatim, with the remainder of the time spent applying the knowledge directly on a project.

Early on, my python experience consisted primarily of fairly simple packages and scripts run on the command line. These were fairly straightforward to test, and I was typically disciplined in following a TDD approach. Correspondingly, these tools have held up well in production.

More recently I have been the primary developer of a serverless REST API connected to DynamoDB in AWS. The system architecture here is quite a bit more complicated, and I was really struggling with managing the state of the database and building out a test suite that did not depend on a specific manual state of the data. I also was confounded by repeatability - the suite would be inconsistent between runs as side effects of certain tests affected the function of other tests.

I was already using fixtures, but this book opened my eyes to all the nuances available. Particularly useful was learning about the --setup-show flag that would provide a log of which fixtures were being called at which point. I also learned about marks, test classes, and parametrization. All of these tools have been incorporated into the testing plan for this project.

At a higher level, the testing strategy listed in Part II was very useful. I was struggling to find a nice middle ground between tiny unit tests and full on, end-to-end system tests. Brian’s guidance in the book helped me realize that I don’t need to test everything involved in the app. For example, part of the data strategy relies upon DynamoDB streams. However, testing to confirm the emittance and format of a stream record is not something this app needs to be concerned with. Therefore I was able to greatly simplify the tests and build out some hard-coded test data. This allowed for testing the stream triggers on my local machine, which provides a much shorter feedback loop during debugging and testing.

Strengths and Weaknesses

No technical book is perfect, but this sure is a strong entry.

Pros

Overall I found the book to be balanced and well-paced. The chapters build on each other somewhat, but you can skip around if desired (as I did) and still get a lot of value.

Maybe most importantly, Brian makes a solid case for testing early and often without forcing the reader into a 100% - TDD approach. Chapter 7, Strategy, is one of my favorite parts of the book as it lists solid guidance that otherwise would only be acquired via multiple years of experience.

I haven’t had a use case for it yet, but the book also covers a lot of ground regarding “modern” python development using tools like pyproject.toml and tox.

Cons

The only downside I can see is that the example Cards project is very basic and primarily runs via the command line. That’s understandable as something more complicated would likely overwhelm a rookie pythonista. More involved testing, including tests of a REST API and web interface, are left as an exercise for the reader and probably are best suite to a tool like Playwright.

Conclusion

This book has become another invaluable resource in my library, both as a guide and also for reference purposes. I’m a firm believer in unit testing and code coverage, and as a result of reading this book I’m an even bigger fan of pytest. At the end of the day, it’s clear that if you write python code, you need to use pytest. If you use pytest, you need this book!