Testing in Python
Writing good unit tests in Python with ease — Part 3
This article series is aimed at people working in the public sector (like me), academics and students, people new to their careers in the private sector and anyone else for whom testing code is not yet second nature. When I refer to “tests” or “testing” in this article the context is constrained to unit and component/modular tests. My experience is mostly derived from building analytical pipelines in Python using
pyspark and testing in
The series started as a written summary of a presentation given to the Office for National Statistics on Feb 26 2021. There is also an accompanying GitHub repo with some more advanced test parameterisation examples and other resources.
Here is a list of the articles in this series:
- Part 1: Why you should write unit tests
- Part 2: The basics of testing with pytest
- Part 3: Testing workflow tips (this article)
Here are the topics covered in this chapter:
If you can’t write your test straight away, write a test shell so you know to come back to it!
Snakes in the Grass 🐍
Mark your test shells using
pytest.mark.skip(reason="test_shell") so that you can see where you have missing tests from
pytest output at a glance.
Add these to your
.bashrc to quickly cycle through your recent
pytest commands in your bash history.
VS Code Shortcuts
I find the VS Code shortcuts extremely helpful for manipulating hard coded test data. They take a lot of the pain out of the process. I demo my favourite ones in this article.
VS Code Snippets
Rules that you can break
There are some rules I feel comfortable breaking in my test scripts. These are:
- Having max line length over 72 chars
- Not obeying all docstring conventions
- Not being DRY — at least not when starting out
As always, use your own judgement, and try to be consistent above all else.
It is probably worth mentioning a couple of common pitfalls that have caught me out a few times. If you can think of any more, please leave a comment and I’ll add to this list:
- Grouping tests by class but forgetting to add
selfto the parameters.
The error message for this is probably going to cause a little confusion as it treats whatever parameter name is passed first instead as the class —
self is just a conventional name for that parameter anyway, so
pytest assumes you’ve just given it a different name when you probably forgot it altogether.
Here’s an example of what the error output looks like:
- Forgetting to declare something as a fixture
Luckily the error message for this one is a bit more straightforward.
- Doing too much — cut your functions down! Did I say this already? The number one thing that is going to slow down your testing process is trying to test functions that are doing too much logic in one go. Consider writing a component test to cover the main expected behaviour of your program, then refactor a large function into multiple smaller units.
- OK — now you’ve read the article, go write some tests.
- Check out the accompanying GitHub repo for some additional resources.
- If you liked something about this article or found it interesting, please leave a “clap”.
- If you disagreed with something or have some additional tips to share then please leave a comment.
I hope these articles will be a good reference for you on your testing journey. Bon chance!