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.

Directory Layout

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:

  1. The 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.
  2. Every test file starts with 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.

Names of Test Functions

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?

Image for post

Comic by Oliver Widder on geek-and-poke.com

#pytest #software-development #unit-testing #python #programming

Unit Testing in Python — Structure
1.20 GEEK