fix(tia): suppress PHPUnit XML coverage during recording (#1845)

When phpunit.xml has <coverage> and <source> sections, PHPUnit
auto-initializes its code coverage driver which takes over
xdebug's coverage APIs. TIA's recorder then gets empty data
from xdebug_get_code_coverage(), resulting in zero recorded
edges and no graph being saved.

Inject --no-coverage into the arguments when TIA enters its
own recording mode (not piggybacking on an explicit coverage
report). This tells PHPUnit to ignore XML-configured coverage
reports, leaving xdebug free for TIA's per-test recording.

Having <coverage> and <source> in phpunit.xml is standard for
any project that generates coverage reports. Without this fix,
users must manually pass --no-coverage alongside --tia, which
is an unnecessary footgun.
This commit is contained in:
Caleb White
2026-08-25 14:55:57 -05:00
committed by GitHub
parent 20a5aacaca
commit fc17365bd1
2 changed files with 43 additions and 0 deletions
+39
View File
@@ -2,6 +2,7 @@
declare(strict_types=1);
use Pest\Support\Coverage;
use Tests\Fixtures\Tia\Project;
afterEach(function (): void {
@@ -39,6 +40,44 @@ test('a plain run after a coverage run records the whole project scope', functio
->and($graph['files'])->toContain('app/Calculator.php');
})->skipOnWindows();
test('xml-configured coverage does not prevent tia recording', function (): void {
$project = Project::make('master');
$project->write('phpunit.xml', <<<'XML_WRAP'
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheDirectory=".phpunit.cache"
colors="true"
failOnRisky="true"
failOnWarning="false"
>
<testsuites>
<testsuite name="default">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<coverage>
<report>
<clover outputFile="coverage/clover.xml" />
</report>
</coverage>
<source>
<include>
<directory suffix=".php">./app</directory>
</include>
</source>
</phpunit>
XML_WRAP);
$result = $project->pest('--tia');
expect($result->exitCode)->toBe(0, $result->describe())
->and($project->graphExists())->toBeTrue()
->and(array_keys($project->graph()['edges']))->toEqualCanonicalizing(array_keys(Project::EDGES));
})->skipOnWindows()->skip(! Coverage::isAvailable(), 'Coverage is not available');
test('a coverage report leaves the edges of an existing graph alone', function (): void {
$project = Project::make('master');
$project->seed('master');