mirror of
https://github.com/pestphp/pest.git
synced 2026-04-22 23:17:28 +02:00
Fix parallel file selection and empty-suite reporting
This commit is contained in:
@ -171,6 +171,14 @@ final class ResultPrinter
|
|||||||
|
|
||||||
$state = (new StateGenerator)->fromPhpUnitTestResult($this->passedTests, $testResult);
|
$state = (new StateGenerator)->fromPhpUnitTestResult($this->passedTests, $testResult);
|
||||||
|
|
||||||
|
if ($testResult->numberOfTestsRun() === 0 && $state->testSuiteTestsCount() === 0) {
|
||||||
|
$this->output->writeln([
|
||||||
|
'',
|
||||||
|
' <fg=white;options=bold;bg=blue> INFO </> No tests found.',
|
||||||
|
'',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$this->compactPrinter->errors($state);
|
$this->compactPrinter->errors($state);
|
||||||
$this->compactPrinter->recap($state, $testResult, $duration, $this->options);
|
$this->compactPrinter->recap($state, $testResult, $duration, $this->options);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,7 @@ use function dirname;
|
|||||||
use function file_get_contents;
|
use function file_get_contents;
|
||||||
use function max;
|
use function max;
|
||||||
use function realpath;
|
use function realpath;
|
||||||
|
use function str_starts_with;
|
||||||
use function unlink;
|
use function unlink;
|
||||||
use function unserialize;
|
use function unserialize;
|
||||||
use function usleep;
|
use function usleep;
|
||||||
@ -485,14 +486,52 @@ final class WrapperRunner implements RunnerInterface
|
|||||||
private function getTestFiles(SuiteLoader $suiteLoader): array
|
private function getTestFiles(SuiteLoader $suiteLoader): array
|
||||||
{
|
{
|
||||||
/** @var array<string, non-empty-string> $files */
|
/** @var array<string, non-empty-string> $files */
|
||||||
$files = [
|
$files = array_fill_keys(array_values(array_filter(
|
||||||
...array_values(array_filter(
|
|
||||||
$suiteLoader->tests,
|
$suiteLoader->tests,
|
||||||
fn (string $filename): bool => ! str_ends_with($filename, "eval()'d code")
|
fn (string $filename): bool => ! str_ends_with($filename, "eval()'d code")
|
||||||
)),
|
)), null);
|
||||||
...TestSuite::getInstance()->tests->getFilenames(),
|
|
||||||
];
|
|
||||||
|
|
||||||
return $files; // @phpstan-ignore-line
|
foreach (TestSuite::getInstance()->tests->getFilenames() as $filename) {
|
||||||
|
if ($this->shouldIncludeBootstrappedTestFile($filename)) {
|
||||||
|
$files[$filename] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys($files); // @phpstan-ignore-line
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldIncludeBootstrappedTestFile(string $filename): bool
|
||||||
|
{
|
||||||
|
if (! $this->options->configuration->hasCliArguments()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$resolvedFilename = realpath($filename);
|
||||||
|
|
||||||
|
if ($resolvedFilename === false) {
|
||||||
|
$resolvedFilename = realpath($this->options->cwd.DIRECTORY_SEPARATOR.$filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($resolvedFilename === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->options->configuration->cliArguments() as $path) {
|
||||||
|
$resolvedPath = realpath($path);
|
||||||
|
|
||||||
|
if ($resolvedPath === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($resolvedFilename === $resolvedPath) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_dir($resolvedPath) && str_starts_with($resolvedFilename, $resolvedPath.DIRECTORY_SEPARATOR)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1757,6 +1757,9 @@
|
|||||||
✓ parallel
|
✓ parallel
|
||||||
✓ a parallel test can extend another test with same name
|
✓ a parallel test can extend another test with same name
|
||||||
|
|
||||||
|
PASS Tests\Visual\ParallelNestedDatasets
|
||||||
|
✓ parallel reports missing nested datasets without a passing summary
|
||||||
|
|
||||||
PASS Tests\Visual\SingleTestOrDirectory
|
PASS Tests\Visual\SingleTestOrDirectory
|
||||||
✓ allows to run a single test
|
✓ allows to run a single test
|
||||||
✓ allows to run a directory
|
✓ allows to run a directory
|
||||||
@ -1782,4 +1785,4 @@
|
|||||||
✓ pass with dataset with ('my-datas-set-value')
|
✓ pass with dataset with ('my-datas-set-value')
|
||||||
✓ within describe → pass with dataset with ('my-datas-set-value')
|
✓ within describe → pass with dataset with ('my-datas-set-value')
|
||||||
|
|
||||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 39 todos, 35 skipped, 1188 passed (2813 assertions)
|
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 39 todos, 35 skipped, 1189 passed (2819 assertions)
|
||||||
|
|||||||
@ -21,5 +21,5 @@ test('parallel', function () use ($run) {
|
|||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
test('a parallel test can extend another test with same name', function () use ($run) {
|
test('a parallel test can extend another test with same name', function () use ($run) {
|
||||||
expect($run('tests/Fixtures/Inheritance'))->toContain('Tests: 1 skipped, 2 passed (2 assertions)');
|
expect($run('tests/Fixtures/Inheritance'))->toContain('Tests: 1 skipped, 1 passed (1 assertions)');
|
||||||
});
|
});
|
||||||
|
|||||||
91
tests/Visual/ParallelNestedDatasets.php
Normal file
91
tests/Visual/ParallelNestedDatasets.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
|
$fixture = function (): array {
|
||||||
|
$directory = dirname(__DIR__).DIRECTORY_SEPARATOR.'Features'.DIRECTORY_SEPARATOR.'ParallelNestedDatasetRepro';
|
||||||
|
$datasetsDirectory = $directory.DIRECTORY_SEPARATOR.'Datasets'.DIRECTORY_SEPARATOR.'Nested';
|
||||||
|
$target = $directory.DIRECTORY_SEPARATOR.'TestFileWithNestedDataset.php';
|
||||||
|
|
||||||
|
if (! is_dir($datasetsDirectory)) {
|
||||||
|
mkdir($datasetsDirectory, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_put_contents($datasetsDirectory.DIRECTORY_SEPARATOR.'Users.php', <<<'PHP'
|
||||||
|
<?php
|
||||||
|
|
||||||
|
dataset('nested.users', [
|
||||||
|
['alice'],
|
||||||
|
['bob'],
|
||||||
|
]);
|
||||||
|
PHP);
|
||||||
|
|
||||||
|
file_put_contents($target, <<<'PHP'
|
||||||
|
<?php
|
||||||
|
|
||||||
|
test('loads nested dataset', function (string $name) {
|
||||||
|
expect($name)->not->toBeEmpty();
|
||||||
|
})->with('nested.users');
|
||||||
|
PHP);
|
||||||
|
|
||||||
|
return [$directory, 'tests/Features/ParallelNestedDatasetRepro/TestFileWithNestedDataset.php'];
|
||||||
|
};
|
||||||
|
|
||||||
|
$cleanup = function (string $directory): void {
|
||||||
|
if (! is_dir($directory)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$iterator = new RecursiveIteratorIterator(
|
||||||
|
new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS),
|
||||||
|
RecursiveIteratorIterator::CHILD_FIRST,
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($iterator as $item) {
|
||||||
|
if ($item->isDir()) {
|
||||||
|
rmdir($item->getPathname());
|
||||||
|
} else {
|
||||||
|
unlink($item->getPathname());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rmdir($directory);
|
||||||
|
};
|
||||||
|
|
||||||
|
$run = function (string $target, bool $parallel = false): array {
|
||||||
|
$command = ['php', 'bin/pest', $target, '--colors=never'];
|
||||||
|
|
||||||
|
if ($parallel) {
|
||||||
|
$command[] = '--parallel';
|
||||||
|
$command[] = '--processes=2';
|
||||||
|
}
|
||||||
|
|
||||||
|
$process = new Process($command, dirname(__DIR__, 2),
|
||||||
|
['COLLISION_PRINTER' => 'DefaultPrinter', 'COLLISION_IGNORE_DURATION' => 'true'],
|
||||||
|
);
|
||||||
|
|
||||||
|
$process->run();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'exitCode' => $process->getExitCode(),
|
||||||
|
'output' => removeAnsiEscapeSequences($process->getOutput().$process->getErrorOutput()),
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
test('parallel reports missing nested datasets without a passing summary', function () use ($cleanup, $fixture, $run) {
|
||||||
|
[$directory, $target] = $fixture();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$serial = $run($target);
|
||||||
|
$parallel = $run($target, true);
|
||||||
|
|
||||||
|
expect($serial['exitCode'])->toBe(2)
|
||||||
|
->and($parallel['exitCode'])->toBe(2)
|
||||||
|
->and($serial['output'])->toContain('INFO No tests found.')
|
||||||
|
->and($parallel['output'])->toContain('INFO No tests found.')
|
||||||
|
->and($parallel['output'])->toContain('Parallel: 2 processes')
|
||||||
|
->and($parallel['output'])->not->toContain('passed');
|
||||||
|
} finally {
|
||||||
|
$cleanup($directory);
|
||||||
|
}
|
||||||
|
})->skipOnWindows();
|
||||||
Reference in New Issue
Block a user