I am using pytest to test a project I am working on. I have a project structure like
|my_project
||__init__.py
||my_code.py
||test.py
and test.py
looks like
# contents of test.py
import .my_code
def test_function():
...
...
To run the tests, I can just run python -m pytest
from this directory. So far so good.
But for the code to run remotely, I have to use Pants to build a virtual environment so that the import statement will actually look like:
import long.path.to.my_project.my_code as my_code
I want to make sure that the code still works in this virtual environment as well, so right now I have a different file called test_venv.py
with identical tests, where the only difference is the import.
# contents of test_venv.py
import long.path.to.my_project.my_code as my_code
def test_function():
...
...
This does work, but it's very annoying to have two almost identical test files. Is there a way to make the import statement parameterized, so that I can tell pytest where I want to import from when I run the test?
After playing around with @morhc's suggestion to use this, I figured out a way. It involves using parameterized fixtures and importlib
. I set up the fixture as follows.
@pytest.fixture(scope='module', params=['local', 'installed'])
def my_code_module(request):
if request.param == 'local':
return importlib.import_module("my_code")
if request.param == 'installed':
return importlib.import_module("long.path.to.my_project.my_code")
Then write the tests to request the fixture as follows.
def test_code(my_code_module):
assert my_code_module.whatever() == ...