Repository navigation
Description
| Q | A |
|---|---|
| PHPUnit version | 13.4.1 |
| PHP version | 8.5.10 |
| Installation Method | Composer |
Summary
PHP extensions loaded via -d extension= are not enabled in tests that run with process isolation, which can cause an uncaught exception.
Current behavior
If you load a PHP extension not via INI files, but rather on-demand via e.g. php -dextension=pcov.so vendor/bin/phpunit ..., the -d extension option will not be passed to child processes when using process isolation. This results in extensions missing from the child process, which can cause all sort of issues. A concrete example, which is also what led me to file this report, is for coverage drivers, for which PHPUnit will throw an (uncaught) exception as described below.
This is similar/related to a bunch of previously-reported issues such as #3492 and #4664, before which options such as -d pcov.enabled=1 were not passed to subprocesses. However, this one is different in that the option that isn't being passed is not a coverage driver-specific one, but rather the extension directive. As far as I can tell, there is no existing issue covering this, but apologies if there's one I didn't see!
How to reproduce
A concrete example with PCOV:
- Create any valid test file, e.g.
$ cat tests/MyTest.php
<?php
use PHPUnit\Framework\TestCase;
class MyTest extends TestCase {
public function testTrue() {
$this->assertTrue( true );
}
}
- Install PHPUnit (for example, via composer:
composer require --dev "phpunit/phpunit") - Install https://github.com/krakjoe/pcov through your preferred means
- Make sure your PHP interpreter does NOT have pcov enabled by default, e.g. via
sudo phpdismod pcovor manually editing the PHP ini file - Run
php -dextension=pcov.so -dpcov.enabled=1 vendor/bin/phpunit --coverage-html ./coverage --coverage-filter tests tests/MyTest.php(no process isolation) and confirm that everything works correctly - Next run with process isolation:
php -dextension=pcov.so -dpcov.enabled=1 vendor/bin/phpunit --coverage-html ./coverage --coverage-filter tests --process-isolation tests/MyTest.phpwhich should give something like
1) MyTest::testTrue
PHPUnit\Framework\Exception: PHP Fatal error: Uncaught TypeError: PHPUnit\Runner\CodeCoverage::codeCoverage(): Return value must be of type SebastianBergmann\CodeCoverage\CodeCoverage, null returned in vendor/phpunit/phpunit/src/Runner/CodeCoverage.php:187
Stack trace:
#0 Standard input code(105): PHPUnit\Runner\CodeCoverage->codeCoverage()
#1 Standard input code(166): __phpunit_run_isolated_test()
#2 {main}
thrown in vendor/phpunit/phpunit/src/Runner/CodeCoverage.php on line 187
Fatal error: Uncaught TypeError: PHPUnit\Runner\CodeCoverage::codeCoverage(): Return value must be of type SebastianBergmann\CodeCoverage\CodeCoverage, null returned in vendor/phpunit/phpunit/src/Runner/CodeCoverage.php:187
Stack trace:
#0 Standard input code(105): PHPUnit\Runner\CodeCoverage->codeCoverage()
#1 Standard input code(166): __phpunit_run_isolated_test()
#2 {main}
thrown in vendor/phpunit/phpunit/src/Runner/CodeCoverage.php on line 187
Expected behavior
PHPUnit should load pcov in the subprocess as well. I think it principle this should be considered for all PHP extensions, but for a start, it could be done for pcov and xdebug only by matching on the loaded extension name.
Activity
[-]PHP extensions loaded via `-d` are not passed to subprocesses when using process isolation[/-][+]Extensions loaded using `-d extension` or `-d zend_extension` are not loaded in child processes[/+]Closes sebastianbergmann#7053
Merge branch '12.5' into 13.4
Merge branch '13.4'