Follow up to #2105583: Add some sane strictness to phpunit tests to catch risky tests

Problem/Motivation

Checking for unintentionally covered code is useful for identifying weakness in coverage reports and making them more useful. However, checkForUnintentionallyCoveredCode's current behavior causes some problems because it doesn't recursively check parent classes for @uses information. This means any code run in our UnitTestCase::setUp() method will always be "unintentionally covered."

Proposed resolution

Obviously we don't want to work around this by adding the @uses to _every_ unit test we implement so we either need to
1) Remove that code from the setUp
2) Allow usage of phpunit's testcase and convert most tests to use it. add @uses to tests that do user Drupal's UnitTestCase.
3) Work upstream to support recursive @uses resolution.

I don't think 1 or 2 are likely so we'll probably need to work with phpunit to get this feature added.

Remaining tasks

Comments

neclimdul created an issue. See original summary.

neclimdul’s picture

mile23’s picture

1+2 is the correct answer.

::mad scientist:: I TRIED TO TELL THEM BUT THEY WOULDN'T LISTEN!!1!!

Anyway.

Option #4 is to kill \Drupal. Which I would endorse. I'm pretty sure it's less practical than any of the other options, however.

The example code on the github issue has a @uses \Drupal (analogue) for the base class, whereas UnitTestCase is not annotated that way.

The problem in that case would be that it's impossible to get coverage for \Drupal using that test case. So the solution would be that all tests of \Drupal would have to be from another base class.

That's much more doable than converting *all* tests.

So:

  1. Add @uses \Drupal to UnitTestCase.
  2. Convert unit tests of \Drupal to subclass \PHPUnit_Framework_TestCase (or add another suitable subclass if it's needed).

I'm pretty sure the \Drupal tests don't need the container or what-have-you.

mile23’s picture

Status: Active » Needs review
StatusFileSize
new1.33 KB

And a patch. :-)

Which, I now realize, is against 8.0.x, not 8.1.x, but hopefully it will apply.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mile23’s picture

mile23’s picture

Patch still applies to 8.3.x. Re-running tests.

mile23’s picture

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

lendude’s picture

checkForUnintentionallyCoveredCode has been deprecated in PHPUnit 5, see https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-f...

so combined with #2795317: Allow PHPUnit 6+ support for object mocking, not sure what this means for the future of this issue, but thought I'd ask.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

borisson_’s picture

I think #12 means that we close this issue as won't fix.

borisson_’s picture

Status: Needs review » Closed (won't fix)

Closing this issue based on #12.

e0ipso’s picture

Do we want to remove this line?

<!-- TODO set checkForUnintentionallyCoveredCode="true" once https://www.drupal.org/node/2626832 is resolved. -->

vijaycs85’s picture

Status: Closed (won't fix) » Needs review
Issue tags: +Novice
StatusFileSize
new514 bytes

Reached here from core/phpunit.xml.dist. Let's remove it.

tstoeckler’s picture

Wait, but shouldn't we add beStrictAboutCoversAnnotation to phpunit.xml.dist then, instead?

vijaycs85’s picture

StatusFileSize
new712 bytes
new1.05 KB

Did not know we have an alternative. @tstoeckler++

neclimdul’s picture

Status: Needs review » Reviewed & tested by the community

Makes sense. Lets just do it.

mile23’s picture

Issue tags: -Novice +Needs followup

This yields results like this:

$ ./vendor/bin/phpunit -c core/ --testsuite unit --coverage-html ../coverage -v --stop-on-risky
PHPUnit 6.5.9 by Sebastian Bergmann and contributors.

[...]

There was 1 risky test:

1) Drupal\Tests\Core\Database\Driver\pgsql\PostgresqlConnectionTest::testEscapeTable with data set #0 ('nocase', 'nocase')
This test executed code that is not listed as code to be covered or used:
- Drupal::unsetContainer
- Drupal\Component\FileCache\FileCacheFactory::setConfiguration
- Drupal\Component\FileCache\FileCacheFactory::setPrefix
- Drupal\Core\Database\Connection::__construct
- Drupal\Core\Database\Connection::escapeTable
- Drupal\Core\Database\Connection::setPrefix
- Drupal\Core\Database\Driver\pgsql\Connection::__construct
- Drupal\Core\Database\Driver\pgsql\Connection::doEscape

OK, but incomplete, skipped, or risky tests!
Tests: 4, Assertions: 5, Risky: 1.

If you look at PostgresqlConnectionTest you see that it has @coversDefaultClass and @covers annotations. But it lacks @use for code paths that aren't within that default class and its methods. Like this:

/**
 * @coversDefaultClass \Drupal\Core\Database\Driver\pgsql\Connection
 * @group Database
 */
class PostgresqlConnectionTest extends UnitTestCase {

This means that even though our test is annotated to cover \Drupal\Core\Database\Driver\pgsql\Connection, our report says that it is not covered, because we set beStrictAboutCoversAnnotation.

In that report you'll also see that \Drupal::unsetContainer() and file cache management are still a problem and that's what the code changes in #4 try to fix.

Also, if you limit to --group Database (for brevity's sake) you see this result:

OK, but incomplete, skipped, or risky tests!
Tests: 89, Assertions: 124, Risky: 45.

That means roughly half of the existing @covers annotations are being ignored because of the way UnitTestCase works, and because we don't have perfect isolation in the tests themselves.

I won't set this to NW but I'll add the 'needs followup' tag because if we commit to this, it means we need a followup to modify at least UnitTestCase (and maybe KTB) to @use \Drupal and so forth (or add the changes from #4), and also to explicitly mark functional tests as @coversNothing.

I think that'd be a good change, but I'm not sure any actual maintainer wants to go down that path at this stage.

mile23’s picture

BTW the issue in #2 is closed due to lack of feedback, but was referenced by another very similar issue: https://github.com/sebastianbergmann/php-code-coverage/issues/629

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

I dunno this one feels a weird one for me. This only has an effect if xdebug is on so no tests on DrupalCI are going to fail because of it. I think until we've got code coverage reports being generated somewhere this setting is not very useful for us. If you are running code coverage locally and you want to do this there is nothing to stop you setting this up in your local phpunit.xml as you see fit. I think out phpunit.xml.dist should contain how DrupalCI runs the tests and not anything else. If people want to do advance PHPUnit configuration they should be using PHPUnit docs and examples not ours.

borisson_’s picture

I'm not sure if we want to have #19, even as a goal later down the line. I do think that #17 is something we should do, as it removes a reference to a setting that will no longer work.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

teknorah’s picture

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
catch’s picture

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mile23’s picture

Status: Needs review » Postponed
Related issues: +#2974911: Allow run-tests.sh to generate coverage reports

Given #23 let's call this issue postponed on #2974911: Allow run-tests.sh to generate coverage reports. We currently don't do a coverage report for core for the project CI, AFAICT.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.