Testing code is often pretty ugly: A lot of copy & paste, the code is all over the place and hard to understand. In this article you will learn how to structure unit testing code in Python.
I put the tests next to the package. So the tests are not part of the package, only of the repository. The reason is simply to keep the package small.
A part of my package mpu looks like this:
mpu <-- Root of the git repository
├── mpu <-- Root of the package
│ ├── datastructures/
│ │ ├── __init__.py
│ │ └── trie
│ │ ├── char_trie.py
│ │ └── __init__.py
│ ├── geometry.py
│ ├── image.py
│ ├── __init__.py
│ ├── io.py
│ └── _version.py
├── README.md
├── requirements-dev.in
├── requirements-dev.txt
├── tests/
│ ├── files/
│ ├── test_char_trie.py
│ ├── test_datastructures.py
│ ├── test_geometry.py
│ ├── test_image.py
│ ├── test_io.py
│ └── test_main.py
└── tox.ini
You should notice the following:
tests/
are side-by-side to the mpu/
directory which contains the code. The two alternatives are (1) to have a tests/
directory within the mpu/
package so that the tests get shipped with the code or (2) to put the test of a module next to the module. I would discourage (2) as I have never seen it for Python, but (1) is also commonly done and mentioned by pytest.test_
. That makes it easy to recognize which files contain the tests. It’s the default of pytest and I don’t see a reason to change it.When you have a fibonacci(n: int) -> int
function, you will likely have a test_fibonacci
function. And when test suites grow, there might appear a test_fibonacci2
or something similar. Don’t do that. I know, naming things is hard.
You will see the name of this function when the test fails. Which name will help you to quickly understand what was tested?
Comic by Oliver Widder on geek-and-poke.com
#pytest #software-development #unit-testing #python #programming