So I’m sure we’ve all heard that the src/
layout is the greatest thing since sliced lists. One of its selling points is that testing a src/
-layout project necessarily involves installing in non-development mode, with the result that, when you write import packagename
in a tests/test_*.py
file, you know you’re importing the installed code rather than what’s in src/
, so you know you’re getting what your users are getting.
However, if your code contains any doctests, you’d probably run your tests with pytest --doctest-modules src tests
, and it turns out that this eliminates the abovementioned benefit of the src/
layout: pytest, in running the doctests in src
, imports the src
version of the code, and then when pytest gets around to running the tests in tests
, it ends up reusing those imports. You can see this for yourself by adding a function to your code that returns __file__
and then adding a test that checks the function’s return value for '*/site-packages/*'
.
Fixing this problem is tricky. The obvious solution of switching the command arguments (to produce pytest --doctest-modules tests src
) produces an ImportMismatchError
from pytest. The only solution I’ve found (and it only works if you’re running your tests in tox) is to change the src
in the command to {envsitepackagesdir}/MODULE
, where MODULE
is the name of the module file (e.g., packagename.py
) or module package that contains your code. The downside to this is that it’s ugly and it causes the report from pytest-cov
to list your source files as “.tox/py*/lib/python*/site-packages/packagename/...
” rather than as just “src/packagename/...
” or “packagename/...
”.
Is there a better way of dealing with this?
Edit: I came up with a solution to the “.tox/py*/lib/python*/site-packages/packagename/...
” thing. I have to set [coverage:run]parallel = True
, NOT set [coverage:run]source
, and set [coverage:paths]source
to src
and .tox/*/site-packages
. I don’t really understand coverage’s options.