pytest-dev / pytest-dev/pytest
Test collector bug when --rootdir is not real path
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
- a detailed description of the bug or problem you are having
pytest test collector can get wrong item nodeid when running with a non --rootdir is not real path.
Actually I am studying a strange vscode-python extension behavior that when Linux workspace directory is not real path, vscode-python's test discovery gets wrong info about test file path. Tracking it down now I believe it's caused by this bug in pytest.
- output of
pip listfrom the virtual environment you are using
(.venv) $ pip list
Package Version
---------- -------
attrs 21.2.0
iniconfig 1.1.1
packaging 21.0
pip 21.2.4
pluggy 0.13.1
py 1.10.0
pyparsing 2.4.7
pytest 6.2.4
setuptools 41.6.0
toml 0.10.2
- pytest and operating system versions
pytest: 6.2.4 as shown above
OS: RHEL 8 (I believe other Linux can reproduce this too)
- minimal example if possible
Our demo directory structure (on Linux),
(.venv) $ tree
.
├── mypytest
└── tests
├── __init__.py
└── test_dummy.py
1 directory, 3 files
To see this issue we use a custom plugin to override pytest_collection_finish, to print the collected items nodeid to a log file.
(.venv) $ cat mypytest
#!/usr/bin/env python3
import sys
import pytest
class MyCollector:
def __init__(self, logfile):
self.logfile = logfile
def pytest_collection_finish(self, session):
with open(self.logfile, "w") as f:
for item in session.items:
f.write("%s\n" % dict(nodeid=item.nodeid, fspath=item.fspath))
if __name__ == "__main__":
plugin = MyCollector("./collector.log")
pytest.main(sys.argv[1:], [plugin])
Run test collection from the "tests" subdir: With --rootdir be the project root, if --rootdir is real path, result is good in that nodeid is 'tests/test_dummy.py' as relative to the rootdir. Buf if --rootdir is not real path, like if it's a symlink, the collected test has wrong nodeid.
# chdir to "tests"
(.venv) $ cd tests
(.venv) $ pwd
/var/tmp/pytest-issue/tests
# this is good
(.venv) $ ../mypytest --collect-only --rootdir /var/tmp/pytest-issue > /dev/null && cat collector.log
{'nodeid': 'tests/test_dummy.py::test_plus', 'fspath': local('/var/tmp/pytest-issue/tests/test_dummy.py')}
# bad if rootdir is not realpath: let's run from /var/tmp/foo which is not realpath.
# fspath is good but nodeid has not the "tests" subdir.
(.venv) $ ln -s /var/tmp/pytest-issue /var/tmp/foo
(.venv) $ cd /var/tmp/foo/tests
(.venv) $ ../mypytest --collect-only --rootdir /var/tmp/foo > /dev/null && cat collector.log
{'nodeid': 'test_dummy.py::test_plus', 'fspath': local('/var/tmp/pytest-issue/tests/test_dummy.py')}
vscode-python extension internally does something similar as above command for pytest test discovery. So when our workspace dir is not real path, we get problem with test discovery in vscode: while it detects the test files, it gets wrong idea about their path, causing individual run on a test file to fail.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with pytest --collect-only, --rootdir, and the symlinked project layout described in the report, then trace pytest's collection and rootdir handling. Done means the collected nodeid retains the tests/ subdirectory when --rootdir is a symlink, while fspath remains correct; add regression coverage for both real and non-real root paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux, python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100