I have the following pytest directory structure:
system_tests/
├── conftest
├── pytest.ini
│
├── suite_1/
│ └── test_A.py
│
└── suite_2/
└── sub_suite_2a/
└── test_B.py
When each test method runs, a number of third-party libraries/processes generate artifacts in the current working directory.
sub_suite
folder (using CLI or IDE "play" button), the files are generated in the sub_suite
folder, where I want them to be.system_tests
folder to run all tests, all artifacts are created in the system_tests
folder, which is not what I want.Is there an easy way to force pytest to always use the test class folder as the working directory so I get the same results regardless of how or where I run a test from?
The easiest way to handle this if you just want to get something running interactively for yourself is as per Cecil Curry's answer: cd to the top-level bluepy and run Pytest as python -m pytest bluepy/test_asdf.py (or just python -m pytest if you want it to discover all test_* files in or under the current directory ...
To change the current working directory in Python, use the chdir() method. The method accepts one argument, the path to the directory to which you want to change. The path argument can be absolute or relative.
The following function-level fixture will change to the test case directory, run the test (yield), then change back to the calling directory to avoid side-effects, as suggested by @hi2meuk:
@pytest.fixture
def change_test_dir(request):
os.chdir(request.fspath.dirname)
yield
os.chdir(request.config.invocation_dir)
request
is a built-in pytest fixturefspath
is the LocalPath
to the test module being executeddirname
is the directory of the test modulerequest.config.invocationdir
- the folder from which pytest was executedrequest.config.rootdir
- pytest root, doesn't change based on where you run pytest. Not used here, but could be useful.Any processes that are kicked off by the test will use the test case folder as their working directory and copy their logs, outputs, etc. there, regardless of where the test suite was executed.
EDIT: Improved Solution
Using monkeypatch as suggested by @Kound removes the boilerplate code to restore the cwd. You can also enable autouse to automatically apply this fixture to all test functions. Add the following fixture to conftest.py to change the cwd for all tests:
@pytest.fixture(autouse=True)
def change_test_dir(request, monkeypatch):
monkeypatch.chdir(request.fspath.dirname)
Instead of creating a fixture for each directory like suggested by @DV82XL you can simply use monkeypatch
to achieve the same:
import pytest
from pathlib import Path
@pytest.fixture
def base_path() -> Path:
"""Get the current folder of the test"""
return Path(__file__).parent
def test_something(base_path: Path, monkeypatch: pytest.MonkeyPatch):
monkeypatch.chdir(base_path / "data" )
# Do something in the data folder
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With