From 9fa82598a96ce28013630a45ef4af0074f73f944 Mon Sep 17 00:00:00 2001 From: Roberto Aldera <51328612+roberto-aldera@users.noreply.github.com> Date: Fri, 19 May 2023 13:24:28 +0200 Subject: [PATCH] Use NamedTuple for pytest_report_teststatus return value (#10972) Closes #10872 --------- Co-authored-by: Bruno Oliveira --- AUTHORS | 1 + changelog/10872.improvement.rst | 1 + doc/en/reference/reference.rst | 6 ++++++ src/_pytest/hookspec.py | 3 ++- src/_pytest/terminal.py | 30 ++++++++++++++++++++++++++---- src/pytest/__init__.py | 2 ++ 6 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 changelog/10872.improvement.rst diff --git a/AUTHORS b/AUTHORS index 92b0b2a1a..c9e990bf1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -308,6 +308,7 @@ Rafal Semik Raquel Alegre Ravi Chandra Robert Holt +Roberto Aldera Roberto Polli Roland Puntaier Romain Dorgueil diff --git a/changelog/10872.improvement.rst b/changelog/10872.improvement.rst new file mode 100644 index 000000000..fe0c01a02 --- /dev/null +++ b/changelog/10872.improvement.rst @@ -0,0 +1 @@ +Update test log report annotation to named tuple and fixed inconsistency in docs for :hook:`pytest_report_teststatus` hook. diff --git a/doc/en/reference/reference.rst b/doc/en/reference/reference.rst index 48fbe2734..6a5512cc1 100644 --- a/doc/en/reference/reference.rst +++ b/doc/en/reference/reference.rst @@ -956,6 +956,12 @@ TestReport :show-inheritance: :inherited-members: +TestShortLogReport +~~~~~~~~~~~~~~~~~~ + +.. autoclass:: pytest.TestShortLogReport() + :members: + _Result ~~~~~~~ diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index 95b4265ea..1f7c368f7 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -41,6 +41,7 @@ if TYPE_CHECKING: from _pytest.reports import TestReport from _pytest.runner import CallInfo from _pytest.terminal import TerminalReporter + from _pytest.terminal import TestShortLogReport from _pytest.compat import LEGACY_PATH @@ -806,7 +807,7 @@ def pytest_report_collectionfinish( # type:ignore[empty-body] @hookspec(firstresult=True) def pytest_report_teststatus( # type:ignore[empty-body] report: Union["CollectReport", "TestReport"], config: "Config" -) -> Tuple[str, str, Union[str, Mapping[str, bool]]]: +) -> "TestShortLogReport | Tuple[str, str, Union[str, Tuple[str, Mapping[str, bool]]]]": """Return result-category, shortletter and verbose word for status reporting. diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index b7793d398..b0cdb58ce 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -21,6 +21,7 @@ from typing import Dict from typing import Generator from typing import List from typing import Mapping +from typing import NamedTuple from typing import Optional from typing import Sequence from typing import Set @@ -112,6 +113,26 @@ class MoreQuietAction(argparse.Action): namespace.quiet = getattr(namespace, "quiet", 0) + 1 +class TestShortLogReport(NamedTuple): + """Used to store the test status result category, shortletter and verbose word. + For example ``"rerun", "R", ("RERUN", {"yellow": True})``. + + :ivar category: + The class of result, for example ``“passed”``, ``“skipped”``, ``“error”``, or the empty string. + + :ivar letter: + The short letter shown as testing progresses, for example ``"."``, ``"s"``, ``"E"``, or the empty string. + + :ivar word: + Verbose word is shown as testing progresses in verbose mode, for example ``"PASSED"``, ``"SKIPPED"``, + ``"ERROR"``, or the empty string. + """ + + category: str + letter: str + word: Union[str, Tuple[str, Mapping[str, bool]]] + + def pytest_addoption(parser: Parser) -> None: group = parser.getgroup("terminal reporting", "Reporting", after="general") group._addoption( @@ -548,10 +569,11 @@ class TerminalReporter: def pytest_runtest_logreport(self, report: TestReport) -> None: self._tests_ran = True rep = report - res: Tuple[ - str, str, Union[str, Tuple[str, Mapping[str, bool]]] - ] = self.config.hook.pytest_report_teststatus(report=rep, config=self.config) - category, letter, word = res + + res = TestShortLogReport( + *self.config.hook.pytest_report_teststatus(report=rep, config=self.config) + ) + category, letter, word = res.category, res.letter, res.word if not isinstance(word, tuple): markup = None else: diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py index f25ecde9c..9c1d5d204 100644 --- a/src/pytest/__init__.py +++ b/src/pytest/__init__.py @@ -62,6 +62,7 @@ from _pytest.reports import TestReport from _pytest.runner import CallInfo from _pytest.stash import Stash from _pytest.stash import StashKey +from _pytest.terminal import TestShortLogReport from _pytest.tmpdir import TempPathFactory from _pytest.warning_types import PytestAssertRewriteWarning from _pytest.warning_types import PytestCacheWarning @@ -152,6 +153,7 @@ __all__ = [ "TempPathFactory", "Testdir", "TestReport", + "TestShortLogReport", "UsageError", "WarningsRecorder", "warns",