From 58cbe5ff35e2cc0633e7ff7c46d48a66d597a025 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Thu, 21 Dec 2023 20:25:22 -0600 Subject: [PATCH 1/2] Fix verbose reporting of skipped tests On 3.12.1+, unittest doesn't call `startTest` for skipped tests. This is treated as a fix to how tests are counted, which is why it appeared in a point release. Because the nose2 path for test reporting uses the test result methods as the point of connection between `unittest` and nose2 plugins, losing the `startTest` call in this case means that the reporter plugin doesn't emit proper output. The test result object now tracks whether or not a test has been started, and the reporter will check this attribute to ensure that the skipped test output is correct. --- docs/changelog.rst | 6 ++++++ nose2/plugins/result.py | 12 +++++++++--- nose2/result.py | 4 ++++ nose2/tests/functional/test_junitxml_plugin.py | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 18ec30f5..5e1c46c1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,12 @@ testsuites. Unreleased ---------- +* Fix the reporting of skipped tests in verbose mode on newer pythons (3.12.1+), + in which a skipped test is no longer treated as "started". + + ``nose2`` will not introduce a ``StartTestEvent`` in such cases -- + the fix is narrowly and adjustment to the test reporter. + 0.14.0 (2023-10-04) ------------------- diff --git a/nose2/plugins/result.py b/nose2/plugins/result.py index fe953129..fb95ec7a 100644 --- a/nose2/plugins/result.py +++ b/nose2/plugins/result.py @@ -80,6 +80,9 @@ def testOutcome(self, event): etc) """ + if not event.result.test_started: + self._show_test_description(self.stream, event.test) + if event.outcome == result.ERROR: self.reportCategories["errors"].append(event) self._reportError(event) @@ -145,11 +148,14 @@ def _reportStartTest(self, event): self.session.hooks.reportStartTest(evt) if evt.handled: return + self._show_test_description(evt.stream, event.test) + + def _show_test_description(self, stream, test): if self.session.verbosity > 1: # allow other plugins to override/spy on stream - evt.stream.write(self._getDescription(event.test, errorList=False)) - evt.stream.write(" ... ") - evt.stream.flush() + stream.write(self._getDescription(test, errorList=False)) + stream.write(" ... ") + stream.flush() def _reportError(self, event): self._report(event, "reportError", "E", "ERROR") diff --git a/nose2/result.py b/nose2/result.py index 48adc22a..fe19e8b1 100644 --- a/nose2/result.py +++ b/nose2/result.py @@ -31,6 +31,9 @@ def __init__(self, session): self.shouldStop = False # XXX TestCase.subTest expects a result.failfast attribute self.failfast = False + # track whether or not the test actually started + # (in py3.12.1+ a skipped test is not started) + self.test_started = False def startTest(self, test): """Start a test case. @@ -40,6 +43,7 @@ def startTest(self, test): """ event = events.StartTestEvent(test, self, time.time()) self.session.hooks.startTest(event) + self.test_started = True def stopTest(self, test): """Stop a test case. diff --git a/nose2/tests/functional/test_junitxml_plugin.py b/nose2/tests/functional/test_junitxml_plugin.py index acd175d8..1b289dd2 100644 --- a/nose2/tests/functional/test_junitxml_plugin.py +++ b/nose2/tests/functional/test_junitxml_plugin.py @@ -161,7 +161,7 @@ def test_skip_reason_in_message(self): self.assertTestRunOutputMatches( proc, - stderr=r"test \(test_junitxml_skip_reason.Test" + stderr=r"test \(test_junitxml_skip_reason\.Test" + _method_name() + r"\) \.* skip", ) From 316ba77bde55ee206a8ac21834146b5d20f09bd3 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Thu, 21 Dec 2023 20:33:12 -0600 Subject: [PATCH 2/2] Fix testing-from-sdist CI build --- .github/workflows/build.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7a1bea2f..d714e5bb 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -15,10 +15,12 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.x" + python-version: "3.12" + - name: install build prereqs + run: pip install build - name: test run: | - python setup.py sdist + python -m build --sdist version="$(cat nose2/__init__.py | grep '^__version__' | cut -d '"' -f2)" cd dist tar -xzf "nose2-${version}.tar.gz"