chore: fixes test printer

This commit is contained in:
nuno maduro
2026-07-19 13:59:31 +01:00
parent b5e1b83bb4
commit c6073511a2
7 changed files with 143 additions and 36 deletions
+1
View File
@@ -18,6 +18,7 @@ final class BootOverrides implements Bootstrapper
* @var array<int, string>
*/
public const array FILES = [
'ParaTest/WrapperRunner/ProgressPrinterOutput.php',
'Runner/Filter/NameFilterIterator.php',
'Runner/ResultCache/DefaultResultCache.php',
'Runner/TestSuiteLoader.php',
+21 -22
View File
@@ -15,11 +15,6 @@ use PHPUnit\Event\Test\AfterLastTestMethodErrored;
use PHPUnit\Event\Test\AfterLastTestMethodFailed;
use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
use PHPUnit\Event\Test\BeforeFirstTestMethodFailed;
use PHPUnit\Event\Test\ConsideredRisky;
use PHPUnit\Event\Test\Errored;
use PHPUnit\Event\Test\Failed;
use PHPUnit\Event\Test\MarkedIncomplete;
use PHPUnit\Event\Test\Skipped;
use PHPUnit\Event\TestSuite\TestSuite;
use PHPUnit\Event\TestSuite\TestSuiteForTestMethodWithDataProvider;
use PHPUnit\Framework\Exception as FrameworkException;
@@ -254,25 +249,29 @@ final readonly class Converter
...$result->testMarkedIncompleteEvents(),
];
$numberOfNotPassedTests = count(
array_unique(
array_map(
function (AfterLastTestMethodErrored|AfterLastTestMethodFailed|BeforeFirstTestMethodErrored|BeforeFirstTestMethodFailed|Errored|Failed|Skipped|ConsideredRisky|MarkedIncomplete $event): string {
if ($event instanceof BeforeFirstTestMethodErrored
|| $event instanceof AfterLastTestMethodErrored
|| $event instanceof BeforeFirstTestMethodFailed
|| $event instanceof AfterLastTestMethodFailed) {
return $event->testClassName();
}
$notPassedTests = [];
return $this->getTestCaseLocation($event->test());
},
$events
)
)
);
foreach ($events as $event) {
if ($event instanceof AfterLastTestMethodErrored) {
// PHPUnit's collector does not count these towards `numberOfTestsRun`...
continue;
}
if ($event instanceof AfterLastTestMethodFailed) {
// PHPUnit's collector does not count these towards `numberOfTestsRun`...
continue;
}
if ($event instanceof BeforeFirstTestMethodErrored || $event instanceof BeforeFirstTestMethodFailed) {
$notPassedTests[] = $event->testClassName();
$numberOfPassedTests = $result->numberOfTestsRun() - $numberOfNotPassedTests;
continue;
}
$notPassedTests[] = $this->getTestCaseLocation($event->test());
}
$numberOfPassedTests = $result->numberOfTestsRun()
- count(array_unique($notPassedTests))
- $result->numberOfTestSkippedByTestSuiteSkippedEvents();
return $this->stateGenerator->fromPhpUnitTestResult($numberOfPassedTests, $result);
}
@@ -14,6 +14,10 @@ final class TestSkippedSubscriber extends Subscriber implements SkippedSubscribe
{
public function notify(Skipped $event): void
{
if ($event->message() === '__TODO__') {
return; // "todo" tests are reported in the summary, not as ignored tests...
}
$this->logger()->testSkipped($event);
}
}
@@ -120,10 +120,6 @@ final class ResultPrinter
$unexpectedOutput = $this->tail($outputFile);
if ($unexpectedOutput !== '') {
if (preg_match('/^T+$/', $unexpectedOutput) > 0) {
return;
}
$this->output->write($unexpectedOutput);
}
+36 -4
View File
@@ -10,6 +10,10 @@ use NunoMaduro\Collision\Exceptions\TestOutcome;
use PHPUnit\Event\Code\TestDoxBuilder;
use PHPUnit\Event\Code\TestMethod;
use PHPUnit\Event\Code\ThrowableBuilder;
use PHPUnit\Event\Test\AfterLastTestMethodErrored;
use PHPUnit\Event\Test\AfterLastTestMethodFailed;
use PHPUnit\Event\Test\BeforeFirstTestMethodErrored;
use PHPUnit\Event\Test\BeforeFirstTestMethodFailed;
use PHPUnit\Event\Test\Errored;
use PHPUnit\Event\Test\Failed;
use PHPUnit\Event\Test\PhpunitDeprecationTriggered;
@@ -35,8 +39,7 @@ final class StateGenerator
$testResultEvent->throwable()
));
} else {
// @phpstan-ignore-next-line
$state->add(TestResult::fromBeforeFirstTestMethodErrored($testResultEvent));
$this->addClassLevelEvent($state, $testResultEvent);
}
}
@@ -48,8 +51,7 @@ final class StateGenerator
$testResultEvent->throwable()
));
} else {
// @phpstan-ignore-next-line
$state->add(TestResult::fromBeforeFirstTestMethodErrored($testResultEvent));
$this->addClassLevelEvent($state, $testResultEvent);
}
}
@@ -184,6 +186,36 @@ final class StateGenerator
return $state;
}
/**
* Adds the given class-level "hook" failure to the state. Collision's
* `fromBeforeFirstTestMethodErrored` only accepts `BeforeFirstTestMethodErrored`
* events, so the remaining class-level events get a synthesized test method.
*/
private function addClassLevelEvent(State $state, AfterLastTestMethodErrored|AfterLastTestMethodFailed|BeforeFirstTestMethodErrored|BeforeFirstTestMethodFailed $event): void
{
if ($event instanceof BeforeFirstTestMethodErrored) {
$state->add(TestResult::fromBeforeFirstTestMethodErrored($event));
return;
}
$methodName = $event instanceof BeforeFirstTestMethodFailed ? 'beforeAll' : 'afterAll';
$state->add(TestResult::fromPestParallelTestCase(
new TestMethod(
$event->testClassName(), // @phpstan-ignore-line
$methodName,
'', // @phpstan-ignore-line
1,
TestDoxBuilder::fromClassNameAndMethodName($event->testClassName(), $methodName), // @phpstan-ignore-line
MetadataCollection::fromArray([]),
TestDataCollection::fromArray([])
),
TestResult::FAIL,
$event->throwable()
));
}
/**
* @param array<string, list<PhpunitDeprecationTriggered|PhpunitErrorTriggered|PhpunitNoticeTriggered|PhpunitWarningTriggered>> $testResultEvents
*/