diff --git a/platformio/test/reports/stdout.py b/platformio/test/reports/stdout.py index bfeeca6a..2f37bf4a 100644 --- a/platformio/test/reports/stdout.py +++ b/platformio/test/reports/stdout.py @@ -95,5 +95,5 @@ class StdoutTestReport(TestReportBase): for test_case in test_suite.cases: if test_case.status != TestStatus.FAILED: continue - click.echo(test_case.stdout) + click.echo((test_case.stdout or "").strip()) click.echo() diff --git a/platformio/test/result.py b/platformio/test/result.py index a7976088..5f1edbc0 100644 --- a/platformio/test/result.py +++ b/platformio/test/result.py @@ -17,24 +17,36 @@ import functools import operator import time +import click + class TestStatus(enum.Enum): PASSED = enum.auto() FAILED = enum.auto() SKIPPED = enum.auto() + WARNED = enum.auto() ERRORED = enum.auto() @classmethod def from_string(cls, value: str): value = value.lower() - if value.startswith("pass"): + if value.startswith("fail"): + return cls.FAILED + if value.startswith(("pass", "success")): return cls.PASSED if value.startswith(("ignore", "skip")): return cls.SKIPPED - if value.startswith("fail"): - return cls.FAILED + if value.startswith("WARNING"): + return cls.WARNED raise ValueError(f"Unknown test status `{value}`") + def to_ansi_color(self): + if self == TestStatus.FAILED: + return "red" + if self == TestStatus.PASSED: + return "green" + return "yellow" + class TestCaseSource: def __init__(self, file, line=None): @@ -64,6 +76,21 @@ class TestCase: self.duration = duration self.exception = exception + def humanize(self): + parts = [] + if self.source: + parts.append("%s:%d: " % (self.source.file, self.source.line)) + parts.append(self.name) + if self.message: + parts.append(": " + self.message) + parts.extend( + [ + "\t", + "[%s]" % click.style(self.status.name, fg=self.status.to_ansi_color()), + ] + ) + return "".join(parts) + class TestSuite: def __init__(self, env_name, test_name): diff --git a/platformio/test/runners/unity.py b/platformio/test/runners/unity.py index d89d6478..a59b41f1 100644 --- a/platformio/test/runners/unity.py +++ b/platformio/test/runners/unity.py @@ -250,32 +250,15 @@ void unityOutputComplete(void) { unittest_uart_end(); } ) def on_testing_line_output(self, line): - line = strip_ansi_codes(line or "") - if not line.strip(): + if self.options.verbose: click.echo(line, nl=False) + line = strip_ansi_codes(line or "").strip() + if not line: return + test_case = self.parse_test_case(line) + if test_case: + click.echo(test_case.humanize()) + if all(s in line for s in ("Tests", "Failures", "Ignored")): self.test_suite.on_finish() - - # beautify output - line = line.strip() - if line.strip(".").endswith(":PASS"): - click.echo( - "%s\t[%s]" - % (line[: line.rindex(":PASS")], click.style("PASSED", fg="green")) - ) - elif line.strip(".").endswith(":IGNORE"): - click.echo( - "%s\t[%s]" - % ( - line[: line.rindex(":IGNORE")], - click.style("IGNORED", fg="yellow"), - ) - ) - elif ":FAIL" in line: - click.echo("%s\t[%s]" % (line, click.style("FAILED", fg="red"))) - else: - click.echo(line) - - self.parse_test_case(line)