Bug: `#[CoversNothing]` is ignored in Cest tests with PHPUnit 13 / php-code-coverage 12
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 68/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Ruhig
- Tech-Stack
- php
- Bereich
- testing-qa
Rechercherichtung
Beginne mit src/Codeception/Test/Cest.php und src/Codeception/Test/Feature/CodeCoverage.php und führe dann mit dem bereitgestellten Cest-Beispiel vendor/bin/codecept run --coverage aus. Verfolge, wie CoversNothing und false coverage targets in PHPUnit 13 und php-code-coverage 12 behandelt werden. Fertig ist die Aufgabe, wenn CoversNothing-Tests weder abstürzen noch zur Coverage beitragen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
##Bug: #[CoversNothing] is ignored in Cest tests with PHPUnit 13 / php-code-coverage 12
Environment
codeception/codeception: ^5.3.5phpunit/phpunit: ^13.0phpunit/php-code-coverage: ^12.0
Steps to reproduce
use PHPUnit\Framework\Attributes\CoversNothing;
#[CoversNothing]
class SomeCest
{
public function someTest(\AcceptanceTester $I): void
{
// ...
}
}
Run: vendor/bin/codecept run --coverage
Expected: test does not contribute to code coverage.
Actual: TypeError crash — or, if getLinesToBeCovered() returns [],
the test silently contributes to coverage as if the attribute were absent.
Root cause (two-part)
Part 1 — Cest::getLinesToBeCovered() does not handle CoversNothing
PHPUnit\Metadata\Api\CodeCoverage::coversTargets() in PHPUnit 13 handles only
CoversClass, CoversMethod, CoversTrait, etc.
It does not handle #[CoversNothing] — it simply returns an empty TargetCollection.
The correct PHPUnit 13 API for CoversNothing is shouldCodeCoverageBeCollectedFor():
// PHPUnit 13 — PHPUnit\Metadata\Api\CodeCoverage
public function shouldCodeCoverageBeCollectedFor(TestCase $test): bool
{
if ($parser->forClass($test::class)->isCoversNothing()->isNotEmpty()) {
return false;
}
return true;
}
But Cest::getLinesToBeCovered() never calls it, so CoversNothing is lost.
Part 2 — CodeCoverage trait does not handle false return value for php-code-coverage ≥ 12
Historically getLinesToBeCovered() returned false for @coversNothing.
In Feature/CodeCoverage.php, when php-code-coverage >= 12, the result is passed
directly to TargetCollection::fromArray(), which does not accept false:
Proposed fix
1. src/Codeception/Test/Cest.php — check CoversNothing before delegating to coversTargets():
public function getLinesToBeCovered(): array|bool
{
if (PHPUnitVersion::series() < 10) {
return TestUtil::getLinesToBeCovered($this->testClass, $this->testMethod);
}
$metadata = \PHPUnit\Metadata\Parser\Registry::parser()
->forClassAndMethod($this->testClass, $this->testMethod);
if ($metadata->isCoversNothing()->isNotEmpty()) {
return false;
}
if (version_compare(CodeCoverageVersion::id(), '12', '>=')) {
return (new CodeCoverage())->coversTargets($this->testClass, $this->testMethod)->asArray();
}
return (new CodeCoverage())->linesToBeCovered($this->testClass, $this->testMethod);
}
2. src/Codeception/Test/Feature/CodeCoverage.php — handle false before calling TargetCollection::fromArray():
if (version_compare(CodeCoverageVersion::id(), '12', '>=')) {
$tcClass = 'SebastianBergmann\\CodeCoverage\\Test\\Target\\TargetCollection';
if (class_exists($tcClass) && method_exists($tcClass, 'fromArray')) {
if ($linesToBeCovered === false) {
$codeCoverage->stop(false, $status);
return;
}
$linesToBeCovered = $tcClass::fromArray($linesToBeCovered);
$linesToBeUsed = $tcClass::fromArray($linesToBeUsed);
}
}
$codeCoverage->stop(true, $status, $linesToBeCovered, $linesToBeUsed);
Both changes are needed: the first makes CoversNothing detectable again,
the second prevents the TypeError crash when the false value reaches fromArray().
- Vorherrschende Sprache
- PHP
- Sterne
- 4.9k
- Forks
- 1.3k
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus Codeception/Codeception
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
Codeception/Codeception#6949 · 1 Reaktion ·
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 55/100
Codeception/Codeception#6935 · 1 Kommentar ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 52/100
Codeception/Codeception#6923 · 1 Kommentar ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 45/100
Codeception/Codeception#6894 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 48/100
Codeception/Codeception#6883 ·
Alle Issues in Codeception/Codeception
Ähnliche Issues
-
sync-en
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 88/100
-
sync-en
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 88/100
-
Перевод устарел
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 88/100
-
status/awaiting_triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
-
Issue: ready for confirmation Reported on 2.4.x
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100