Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/6428.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Paths appearing in error messages are now correct in case the current working directory has
changed since the start of the session.
10 changes: 8 additions & 2 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from _pytest.mark.structures import MarkDecorator
from _pytest.mark.structures import NodeKeywords
from _pytest.outcomes import fail
from _pytest.pathlib import Path
from _pytest.store import Store

if TYPE_CHECKING:
Expand Down Expand Up @@ -361,9 +362,14 @@ def _repr_failure_py(
else:
truncate_locals = True

# excinfo.getrepr() formats paths relative to the CWD if `abspath` is False.
# It is possible for a fixture/test to change the CWD while this code runs, which
# would then result in the user seeing confusing paths in the failure message.
# To fix this, if the CWD changed, always display the full absolute path.
# It will be better to just always display paths relative to invocation_dir, but
# this requires a lot of plumbing (#6428).
try:
os.getcwd()
abspath = False
abspath = Path(os.getcwd()) != Path(self.config.invocation_dir)
except OSError:
abspath = True

Expand Down
27 changes: 27 additions & 0 deletions testing/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,30 @@ class FakeSession:

outside = py.path.local("/outside")
assert nodes._check_initialpaths_for_relpath(FakeSession, outside) is None


def test_failure_with_changed_cwd(testdir):
"""
Test failure lines should use absolute paths if cwd has changed since
invocation, so the path is correct (#6428).
"""
p = testdir.makepyfile(
"""
import os
import pytest

@pytest.fixture
def private_dir():
out_dir = 'ddd'
os.mkdir(out_dir)
old_dir = os.getcwd()
os.chdir(out_dir)
yield out_dir
os.chdir(old_dir)

def test_show_wrong_path(private_dir):
assert False
"""
)
result = testdir.runpytest()
result.stdout.fnmatch_lines([str(p) + ":*: AssertionError", "*1 failed in *"])