Skip to content
This repository was archived by the owner on Sep 1, 2024. It is now read-only.

Commit 3dec178

Browse files
committed
Report file paths as POSIX on Windows
For consistency, we use forward slashes for file paths on all platforms and test frameworks.
1 parent be0feda commit 3dec178

File tree

3 files changed

+25
-16
lines changed

3 files changed

+25
-16
lines changed

src/pytest_unflakable/_plugin.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ def node_path(session: Union[pytest.Item, pytest.Session]) -> PathCompat:
5959
return session.fspath
6060

6161

62-
def relative_to(path: PathCompat, base: PathCompat) -> str:
62+
def posix_relative_to(path: PathCompat, base: PathCompat) -> str:
6363
if hasattr(path, 'relative_to'):
64-
return str(path.relative_to(base))
64+
return path.relative_to(base).as_posix()
6565
else:
66-
return str(path.relto(base)) # type: ignore
66+
return Path(path.relto(base)).as_posix() # type: ignore
6767

6868

6969
def item_name(item: _pytest.nodes.Node) -> Tuple[str, ...]:
@@ -243,7 +243,7 @@ def pytest_collection_modifyitems(
243243
) -> None:
244244
self.logger.debug('called hook pytest_collection_modifyitems')
245245
for idx, item in enumerate(items):
246-
test_path = relative_to(node_path(item), node_path(session))
246+
test_path = posix_relative_to(node_path(item), node_path(session))
247247
test_name = item_name(item)
248248
if (test_path, test_name) in self.quarantined_tests:
249249
self.logger.info(
@@ -261,14 +261,14 @@ def pytest_runtest_protocol(self, item: pytest.Item, nextitem: Optional[pytest.I
261261
ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location)
262262

263263
assert self.session
264-
test_filename = relative_to(node_path(item), node_path(self.session))
264+
test_filename = posix_relative_to(node_path(item), node_path(self.session))
265265
test_name = item_name(item)
266266
for attempt in range(item.config.option.unflakable_failure_retries + 1):
267267
if attempt > 0:
268268
self.logger.info(
269269
'retrying test `%s` in file %s (attempt %d of %d)',
270270
'.'.join(test_name),
271-
relative_to(node_path(item), node_path(item.session)),
271+
posix_relative_to(node_path(item), node_path(item.session)),
272272
attempt + 1,
273273
item.config.option.unflakable_failure_retries + 1,
274274
)
@@ -304,7 +304,7 @@ def pytest_runtest_makereport(
304304
if item.parent:
305305
pass
306306

307-
test_filename = relative_to(node_path(item), node_path(item.session))
307+
test_filename = posix_relative_to(node_path(item), node_path(item.session))
308308
test_name = item_name(item)
309309
is_quarantined = (test_filename, test_name) in self.quarantined_tests and (
310310
self.quarantine_mode == QuarantineMode.IGNORE_FAILURES)

tests/common.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
import subprocess
1010
from enum import Enum
11+
from pathlib import Path
1112
from typing import (TYPE_CHECKING, Callable, Dict, Iterable, List, Optional,
1213
Sequence, Tuple, cast)
1314
from unittest import mock
@@ -422,11 +423,11 @@ def run_test_case(
422423
'^',
423424
r'\[gw[0-9]\]\x1b\[36m \[ *[0-9]+%\] \x1b\[0m',
424425
re.escape(VERBOSE_TEST_ATTEMPT_OUTCOME_CHARS[test_outcome]),
425-
' %s ' % (re.escape('::'.join((test_file,) + test_name))),
426+
' %s ' % (re.escape('::'.join((Path(test_file).as_posix(),) + test_name))),
426427
'$',
427428
] if expect_xdist else [
428429
'^',
429-
'%s ' % (re.escape('::'.join((test_file,) + test_name))),
430+
'%s ' % (re.escape('::'.join((Path(test_file).as_posix(),) + test_name))),
430431
re.escape(VERBOSE_TEST_ATTEMPT_OUTCOME_CHARS[test_outcome]),
431432
# Statuses may be truncated when test names are long (e.g., when there are parent
432433
# classes) to keep lines under 80 chars. Consequently, we assume anything can appear

tests/test_unflakable.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,20 @@ def test_quarantine_flaky(
142142
verbose: bool,
143143
xdist: bool,
144144
) -> None:
145-
pytester.makepyfile(test_input="""
145+
pytester.makepyfile(**{'folder/test_input': """
146146
first_invocation = True
147147
148148
149+
def test_pass():
150+
pass
151+
152+
149153
def test_flaky():
150154
global first_invocation
151155
if first_invocation:
152156
first_invocation = False
153157
assert False
154-
""")
158+
"""})
155159

156160
subprocess_mock.update(branch='MOCK_BRANCH', commit='MOCK_COMMIT')
157161

@@ -160,24 +164,28 @@ def test_flaky():
160164
manifest={'quarantined_tests': [
161165
{
162166
'test_id': 'MOCK_TEST_ID',
163-
'filename': 'test_input.py',
167+
'filename': 'folder/test_input.py',
164168
'name': ['test_flaky']
165169
}
166170
]},
167171
expected_test_file_outcomes=[
168172
(
169-
'test_input.py',
173+
os.path.join('folder', 'test_input.py'),
170174
[
175+
(('test_pass',), [
176+
_TestAttemptOutcome.PASSED,
177+
]),
171178
(('test_flaky',), [
172179
_TestAttemptOutcome.QUARANTINED,
173180
_TestAttemptOutcome.RETRY_PASSED,
174-
])
181+
]),
175182
],
176183
),
177184
],
178-
expected_test_result_counts=_TestResultCounts(num_quarantined=1),
185+
expected_test_result_counts=_TestResultCounts(num_passed=1, num_quarantined=1),
179186
expected_uploaded_test_runs={
180-
('test_input.py', ('test_flaky',)): ['quarantined', 'pass'],
187+
('folder/test_input.py', ('test_pass',)): ['pass'],
188+
('folder/test_input.py', ('test_flaky',)): ['quarantined', 'pass'],
181189
},
182190
expected_exit_code=ExitCode.OK,
183191
expect_xdist=xdist,

0 commit comments

Comments
 (0)