| Q |
A |
| PHPUnit version |
12.4.2 |
| PHP version |
8.3.27 |
| Installation Method |
Composer |
Summary
If the SUT forks a child process and waits for it to exit, the test will output "Fatal error: Premature end of PHP process".
Current behavior
The test passes but outputs an error message. Interestingly beStrictAboutOutputDuringTests="true" has no effect here.
How to reproduce
final readonly class Forker
{
public function fork(): bool
{
$child = pcntl_fork();
if ($child === -1) {
// couldn't fork
return false;
} elseif ($child) {
// we are the parent process
pcntl_wait($child);
return true;
} else {
// we are the child process
exit(0);
}
}
}
final class ForkerTest extends TestCase
{
public function testFork(): void
{
$actual = (new Forker())->fork();
self::assertTrue($actual);
}
}
Output:
✗ vendor/bin/phpunit test/ForkerTest.php
PHPUnit 12.4.2 by Sebastian Bergmann and contributors.
Runtime: PHP 8.3.27
Configuration: /Users/xxx/yyy/phpunit.xml
Fatal error: Premature end of PHP process when running ForkerTest::testFork.
. 1 / 1 (100%)
Time: 00:00.013, Memory: 20.00 MB
OK (1 test, 1 assertion)
(In the real world I'm testing Swoole stuff, which is a headache enough 😁 )
Expected behavior
I'm not sure if anything can be done with ShutdownHandler that would detect if it were in a child process. If not, it would be good to have a way to suppress the message. Right now I'm calling ShutdownHandler::resetMessage(), but that method is @internal.
Summary
If the SUT forks a child process and waits for it to exit, the test will output "Fatal error: Premature end of PHP process".
Current behavior
The test passes but outputs an error message. Interestingly
beStrictAboutOutputDuringTests="true"has no effect here.How to reproduce
Output:
(In the real world I'm testing Swoole stuff, which is a headache enough 😁 )
Expected behavior
I'm not sure if anything can be done with
ShutdownHandlerthat would detect if it were in a child process. If not, it would be good to have a way to suppress the message. Right now I'm callingShutdownHandler::resetMessage(), but that method is@internal.