Using pytest where test in subfolder
Well I kind of solved it, not sure it is the best way but it is working:
In each of the tests:
- I check if the test is being executed from it directory or from
\Main\Tests
- If it is being executed from
\Main\Tests
then Ichdir
to\Main\Tests\A_test
I do this under the def setUpClass
method.
For example:
@classmethod
def setUpClass(cls):
if (os.path.exists(os.path.join(os.curdir, "A_test"))):
os.chdir("A_test")
This makes the test pass no matter if it is executed from Tests
folder (with pytest) or from A_test
folder (through pycharm)
Option A — Minimal solution
At the root of your project, create a file called tests.py with the following in it
import os, pathlib
import pytest
os.chdir( pathlib.Path.cwd() / 'Tests' )
pytest.main()
You can then use the command python tests.py
to run the tests.
Option B — With batch/bash test runners
For those who prefer using batch/bash to run scripts, we can change directories within batch/bash, and then call a Python script that runs the pytest framework. To do this, create the following scripts in the project folder.
test.bat (for Windows)
@echo off
cd /d %~dp0Tests
python %~dp0Tests/runner.py %*
cd /d %~dp0
test.sh (for Linux)
cd $PWD/Tests
python runner.py $@
cd $PWD
And then in the Tests folder, create a file called runner.py with the following
import pathlib, sys
import pytest
cwd = pathlib.Path.cwd()
# Add the project's root directory to the system path
sys.path.append(str( cwd.parent ))
# This is optional, but you can add a lib directory
# To the system path for tests to be able to use
sys.path.append(str( cwd / 'lib' ))
pytest.main()
If your directory structure includes some type of lib folder within your Tests folder, we can instruct pytest to ignore it by creating a pytest.ini config file with the following.
[pytest]
norecursedirs = lib
Under this scenario, your directory/file structure would end up being:
root
├── test.bat
├── test.sh
├── Main
└── Tests
├── runner.py
├── pytest.ini # Optional pytest config file
├── lib # Optional, contains helper modules for the tests
├── tests # Tests go here
└── # Or, in the OPs case, you could also place all of your tests here
Additional Comments
The methods above aren't the typical way of running pytest, but I prefer using pytest.main()
because it allows us to:
- Have any directory structure.
- Execute code before the test runner starts.
- And you can still pass in command line options, and it will behave exactly the same as if you were running the
pytest
command directly.
Adding __init__.py
to the package of the tests worked for me. All test are executed afterwards.