mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
test: infamy: always emit the "1..N" plan line before exiting
Always emit the "1..N" plan line before exiting with error so test harnesses don't report "test error, no plan" for failed or aborted tests. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
+32
-1
@@ -1,3 +1,32 @@
|
||||
"""TAP (Test Anything Protocol) output helpers for Infamy tests.
|
||||
|
||||
TAP is a simple line-based protocol for communicating test results between a
|
||||
test producer and a consumer (harness). The canonical reference is:
|
||||
|
||||
https://testanything.org/tap-specification.html
|
||||
|
||||
The key elements are:
|
||||
|
||||
Plan line: ``1..N`` — total number of tests, written once
|
||||
Result lines: ``ok N - desc`` — test N passed
|
||||
``not ok N - desc``— test N failed
|
||||
Directives: ``ok N # SKIP`` ``not ok N # TODO``
|
||||
Diagnostics: Any line beginning with ``#`` is a comment/diagnostic.
|
||||
|
||||
The plan line may appear either at the beginning (before any results) or at
|
||||
the end (after all results). Infamy writes it at the END so that the total
|
||||
step count is known; a harness that requires an upfront plan will report
|
||||
"no plan" on failure — see CommentWriter below for a known limitation.
|
||||
|
||||
``CommentWriter`` redirects Python's ``sys.stdout`` so that ordinary
|
||||
``print()`` calls are prefixed with ``# `` and appear as diagnostics, while
|
||||
TAP result lines (written via ``self.out``, the *original* stdout) are emitted
|
||||
verbatim. The plan line is also written via ``self.out``.
|
||||
|
||||
Note: because ``sys.stdout`` is replaced *after* module import the default
|
||||
argument ``output=sys.stdout`` captures the original stream at import time,
|
||||
so nested or re-entrant ``Test()`` instances will share the same ``self.out``.
|
||||
"""
|
||||
import contextlib
|
||||
import datetime
|
||||
import subprocess
|
||||
@@ -41,7 +70,7 @@ class Test:
|
||||
self._not_ok("Missing explicit test result\n")
|
||||
else:
|
||||
if t in (TestPass, TestSkip):
|
||||
self.out.write(f"{self.steps}..{self.steps}\n")
|
||||
self.out.write(f"1..{self.steps}\n")
|
||||
self.out.flush()
|
||||
raise SystemExit(0)
|
||||
if t is AssertionError:
|
||||
@@ -56,6 +85,8 @@ class Test:
|
||||
elif len(e.args) and type(e.args[0]) is subprocess.CompletedProcess:
|
||||
print("Failing subprocess stdout:\n", e.args[0].stdout)
|
||||
|
||||
self.out.write(f"1..{self.steps}\n")
|
||||
self.out.flush()
|
||||
raise SystemExit(1)
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
||||
Reference in New Issue
Block a user