feat(pytest): prefix diagnostic messages with parameterized test ID (#33)

Given a test like:

```py
@pytest.mark.parametrize("a,b", [("b", "c"), ("c", "d")])
def test_a(a, b):
    assert False
```

This modifies the diagnostic message from:

```
neotest: assert False
neotest: assert False
```

to:

```

neotest: [b-c] assert False
neotest: [c-d] assert False
```

This is the same internal value which `pytest` uses for parametrized
instances in its output, so it should be fully consistent.

Without this, the diagnostic messages aren't very useful for
parametrized tests: you can't identify _which_ of the multiple test
which execute the given line are failing.

Fixes: #30
This commit is contained in:
Daniel Watkins
2022-11-10 03:22:04 -05:00
committed by GitHub
parent c85a02089d
commit 458f35723f

View File

@@ -109,13 +109,17 @@ class NeotestResultCollector:
errors: List[NeotestError] = [] errors: List[NeotestError] = []
short = self._get_short_output(self.pytest_config, report) short = self._get_short_output(self.pytest_config, report)
msg_prefix = ""
if getattr(item, "callspec", None) is not None:
# Parametrized test
msg_prefix = f"[{item.callspec.id}] "
if report.outcome == "failed": if report.outcome == "failed":
from _pytest._code.code import ExceptionRepr from _pytest._code.code import ExceptionRepr
exc_repr = report.longrepr exc_repr = report.longrepr
# Test fails due to condition outside of test e.g. xfail # Test fails due to condition outside of test e.g. xfail
if isinstance(exc_repr, str): if isinstance(exc_repr, str):
errors.append({"message": exc_repr, "line": None}) errors.append({"message": msg_prefix + exc_repr, "line": None})
# Test failed internally # Test failed internally
elif isinstance(exc_repr, ExceptionRepr): elif isinstance(exc_repr, ExceptionRepr):
error_message = exc_repr.reprcrash.message # type: ignore error_message = exc_repr.reprcrash.message # type: ignore
@@ -123,7 +127,7 @@ class NeotestResultCollector:
for traceback_entry in reversed(call.excinfo.traceback): for traceback_entry in reversed(call.excinfo.traceback):
if str(traceback_entry.path) == abs_path: if str(traceback_entry.path) == abs_path:
error_line = traceback_entry.lineno error_line = traceback_entry.lineno
errors.append({"message": error_message, "line": error_line}) errors.append({"message": msg_prefix + error_message, "line": error_line})
else: else:
# TODO: Figure out how these are returned and how to represent # TODO: Figure out how these are returned and how to represent
raise Exception( raise Exception(