-
Notifications
You must be signed in to change notification settings - Fork 253
Description
Running pytest and pytest -n <executors> does not produce the same nodeid for the tests and therefore this is preventing lastfailed from running properly. Since the nodeids in the cache don't match any test collected, it ends up running tests that are not meant to run.
I have the following workflow:
- Run the tests that can run in parallel using xdist
- Run the tests that need to run serially without using xdist's
-noption - Run pytest with the
--last-failedoption to try rerunning the failures to check if they are flaky. This is again without using xdist's-noption
Here is the reproducer project structure:
$ ls -1R
.:
pytest.cfg
tests
./tests:
api
./tests/api:
__pycache__
test_bar.py
test_foo.pyHere are the file contents:
$ cat tests/api/test_bar.py
def test_bar_1():
assert True
def test_bar_2():
assert True
def test_bar_3():
assert False
$ cat tests/api/test_foo.py
import os
def test_foo_fail():
assert os.environ.get('FOO_PASS', 'false') == 'true'
def test_foo_ok():
assert True
$ cat pytest.cfg
[tool:pytest]
python_files = *.py
testpaths = tests/apiConsidering the project described above, if you run pytest -n <executors> it shows the following (mind the tests' nodeids):
$ pytest -v --tb=no -c pytest.cfg -n 2
================================ test session starts ================================
platform linux -- Python 3.7.3, pytest-4.6.3, py-1.8.0, pluggy-0.12.0 -- /home/elyezer/.local/venvs/pytest/bin/python3
cachedir: .pytest_cache
rootdir: /home/elyezer/code/xdist-reproducer, inifile: pytest.cfg, testpaths: tests/api
plugins: xdist-1.29.0, forked-1.0.2
[gw0] linux Python 3.7.3 cwd: /home/elyezer/code/xdist-reproducer
[gw1] linux Python 3.7.3 cwd: /home/elyezer/code/xdist-reproducer
[gw0] Python 3.7.3 (default, May 11 2019, 00:38:04) -- [GCC 9.1.1 20190503 (Red Hat 9.1.1-1)]
[gw1] Python 3.7.3 (default, May 11 2019, 00:38:04) -- [GCC 9.1.1 20190503 (Red Hat 9.1.1-1)]
gw0 [5] / gw1 [5]
scheduling tests via LoadScheduling
test_bar.py::test_bar_1
test_bar.py::test_bar_2
[gw1] [ 20%] PASSED test_bar.py::test_bar_2
[gw0] [ 40%] PASSED test_bar.py::test_bar_1
test_bar.py::test_bar_3
test_foo.py::test_foo_fail
[gw0] [ 60%] FAILED test_bar.py::test_bar_3
test_foo.py::test_foo_ok
[gw0] [ 80%] PASSED test_foo.py::test_foo_ok
[gw1] [100%] FAILED test_foo.py::test_foo_fail
======================== 2 failed, 3 passed in 0.32 seconds =========================But if we run without the -n option here is the output:
$ pytest -v --tb=no -c pytest.cfg
================================ test session starts ================================
platform linux -- Python 3.7.3, pytest-4.6.3, py-1.8.0, pluggy-0.12.0 -- /home/elyezer/.local/venvs/pytest/bin/python3
cachedir: .pytest_cache
rootdir: /home/elyezer/code/xdist-reproducer, inifile: pytest.cfg, testpaths: tests/api
plugins: xdist-1.29.0, forked-1.0.2
collected 5 items
tests/api/test_bar.py::test_bar_1 PASSED [ 20%]
tests/api/test_bar.py::test_bar_2 PASSED [ 40%]
tests/api/test_bar.py::test_bar_3 FAILED [ 60%]
tests/api/test_foo.py::test_foo_fail FAILED [ 80%]
tests/api/test_foo.py::test_foo_ok PASSED [100%]
======================== 2 failed, 3 passed in 0.04 seconds =========================As you can see both calls has the same rootdir but produce different nodeids for the tests. And if we check the cache for lastfailed:
$ pytest -c pytest.cfg --cache-show=cache/lastfailed
================================ test session starts ================================
platform linux -- Python 3.7.3, pytest-4.6.3, py-1.8.0, pluggy-0.12.0
rootdir: /home/elyezer/code/xdist-reproducer, inifile: pytest.cfg, testpaths: tests/api
plugins: xdist-1.29.0, forked-1.0.2
cachedir: /home/elyezer/code/xdist-reproducer/.pytest_cache
------------------------ cache values for 'cache/lastfailed' ------------------------
cache/lastfailed contains:
{'test_bar.py::test_bar_3': True,
'test_foo.py::test_foo_fail': True,
'tests/api/test_bar.py::test_bar_3': True,
'tests/api/test_foo.py::test_foo_fail': True}
=========================== no tests ran in 0.00 seconds ============================pytest-xdist test nodeid generation is not consistent with plain pytest nodeid generation and this inconsistency is breaking plugins such as the lastfailed that relies on the nodeids to do its job.