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
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!