If you run core's tests with code coverage on, 25 test classes trigger a PHPUnit warning. Each of them uses #[CoversClass] to name a trait. PHPUnit 12 wants us to use #[CoversTrait] for that.
I did some research, and it appears that PHPUnit changed this in a few steps. PHPUnit 11.2 added #[CoversTrait] (phpunit#5799) and deprecated #[CoversClass] (phpunit#5800). Then it was dropped in PHPUnit 12.0 (phpunit#5801).
PHPUnit only checks these attributes when it collects coverage, so neither the deprecation nor today's warning shows up in a normal test run. You can try it with PCOV or Xdebug in coverage mode and running:
$ vendor/bin/phpunit -c core --coverage-text core/tests/Drupal/Tests/Core/StringTranslation/StringTranslationTraitTest.php
You'll get warnings like:
2 tests triggered 2 PHPUnit warnings: 1) Drupal\Tests\Core\StringTranslation\StringTranslationTraitTest::testT Class Drupal\Core\StringTranslation\StringTranslationTrait is not a valid target for code coverage 2) Drupal\Tests\Core\StringTranslation\StringTranslationTraitTest::testFormatPlural Class Drupal\Core\StringTranslation\StringTranslationTrait is not a valid target for code coverage OK, but there were issues! Tests: 2, Assertions: 6, PHPUnit Warnings: 2.
The solution is pretty simple: switch from #[CoversClass] to #[CoversTrait]. I'd also recommend adding a PHPStan rule to reject #[CoversClass]/#[UsesClass].
Core already uses #[CoversTrait] in some tests, so this would make Core more consistent.
Issue fork drupal-3630772
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
dries commentedComment #3
dries commentedComment #5
dries commentedI converted the
#[CoversClass]'s with the help of Claude Code and opened an MR. The MR switches 25 tests to#[CoversTrait], and adds a test to theTestClassClassMetadataPHPStan rule.Comment #6
dries commentedComment #7
mondrakeDo we really need to add a PHPStan rule too? PHPUnit will be already flagging the error itself (it's 'PHPUnit warning'). It's not like test annotations, where PHPUnit removed the annotation parsing code and we would be left out with crufty annotations without the PHPStan check.
Comment #8
dries commentedFair question and either works for me. I added the rule because PHPUnit only flags it when running with
--coverage-textand Drupal.org's CI/CD pipelines don't. So it would go unnoticed until someone runs the code coverage manually.Comment #9
mondrakeOh I missed that happens only when processing code coverage. Fair enough then. I hope we could soon enable code coverage for core unit testing, with PHPUnit native parallelization coming hopefully in 13.5, https://github.com/sebastianbergmann/phpunit/pull/6784. But that’d be another issue.
Comment #10
mondrake