Pick which directory to run pytest from

Viewed 280

I'm developing a Python application using Pytest, Pycharm and gitlab-ci.

My project folder structure looks like this:

├── config
│   └── config.yaml
├── models
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-38.pyc
│   │   └── models.cpython-38.pyc
│   └── models.py
├── modules
│   ├── __init__.py
│   ├── sliceconfigbuilder.py
│   └── slicefailoverhandler.py
├── slicefailover.py
└── test
    ├── __init__.py
    ├── config
    │   ├── 50-project.conf
    │   ├── hosts
    │   ├── slicefailoverconfig.yaml
    │   ├── systemconfig-1.xml
    │   ├── systemconfig-12.xml
    │   └── systemconfig.xml
    ├── locks
    ├── original
    │   └── systemconfig.xml
    ├── test_sliceconfigbuilder.py
    └── test_slicefailoverhandler.py

Some of my (py)tests involve loading an external yaml file, namely config.yaml. Furthermore, config.yaml specifies the paths to more external files that are loaded during testing.

The issue I have is figuring out the correct relativ path so this works both in Pycharm and gitlab-ci. Running tests with the "play" symbol out of pycharm is very convenient. The issue is that the play symbol in pycharm seems to run pytest out of the tests directory, while pytest in gitlab-ci is ran out of the root directory.

I can't find the proper option in pytest to change the "base directory" in which pytest is starting. pytest does offer the "rootdir" option (https://docs.pytest.org/en/stable/customize.html) but that does not seem to do what I want.

One workaround I have found is passing a "cd test" argument to my .gitlab-ci.yaml, but since this seems to be such a common problem I'm looking for a better solution how to handle this and how to handle working with external paths during testing as a whole.

1 Answers

For what it is worth, here is some boilerplate that will make this work if added to the top of all your test files that is in the sprit of "dynamically change directory", by giving you a global that you can prefix filepaths with.

# --- Globals for config
if os.path.exists("config/config.yaml"):
    # - Running from git
    NAV2ROOT = "config/"
else:
    # - Running directly from file in PyCharm
    NAV2ROOT = "../config/"
CONFIG_PATH = os.path.join(NAV2ROOT,config.yaml)

I agree that the option to run test files singly in PyCharm (with the play symbol) with a different root would be useful and seems like it should exist, but AFAIK it doesn't.

More generally, it seems the prefered pattern for PyCharm & Pytest is using conftest.py fixtures to load in stuff that is common to many tests (as config.yaml presumably is).

Related