Organizing files and packages
Pytest needs to import your code and test modules, and it is up to you how to organize them. Pytest supports two common test layouts, which we will discuss next.
Tests that accompany your code
You can place your test modules together with the code they are testing by creating a tests
folder next to the modules themselves:
setup.py mylib/ tests/ __init__.py test_core.py test_utils.py __init__.py core.py utils.py
By putting the tests near the code they test, you gain the following advantages:
- It is easier to add new tests and test modules in this hierarchy and keep them in sync
- Your tests are now part of your package, so they can be deployed and run in other environments
The main disadvantage with this approach is that some folks don't like the added package size of the extra modules, which are now packaged together with the rest of the code, but this is usually minimal and of little concern.
As an additional benefit, you can use the --pyargs
option to specify tests using their module import path. For example:
λ pytest --pyargs mylib.tests
This will execute all test modules found under mylib.tests
.
Note
You might consider using _tests
for the test module names instead of _test
. This makes the directory easier to find because the leading underscore usually makes them appear at the top of the folder hierarchy. Of course, feel free to use tests
or any other name that you prefer; pytest doesn't care as long as the test modules themselves are named test_*.py
or *_test.py
.
Tests separate from your code
An alternative to the method above is to organize your tests in a separate directory from the main package:
setup.py mylib/ __init__.py core.py utils.py tests/ __init__.py test_core.py test_utils.py
Some people prefer this layout because:
- It keeps library code and testing code separate
- The testing code is not included in the source package
One disadvantage of the above method is that, once you have a more complex hierarchy, you will probably want to keep the same hierarchy inside your tests directory, and that's a little harder to maintain and keep in sync:
mylib/ __init__.py core/ __init__.py foundation.py contrib/ __init__.py text_plugin.py tests/ __init__.py core/ __init__.py test_foundation.py contrib/ __init__.py test_text_plugin.py
Note
So, which layout is the best? Both layouts have advantages and disadvantages. Pytest itself works perfectly well with either of them, so feel free to choose a layout that you are more comfortable with.