From 61f7c75a11eb1c6908c87235757a428de2bae6d1 Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Thu, 28 May 2020 15:32:49 +0200 Subject: [PATCH] Closes #4246 --- ChangeLog-9.2.md | 1 + src/Framework/TestCase.php | 1 - src/Framework/TestResult.php | 41 +++++++++++++------ src/Framework/TestSuite.php | 1 - src/Runner/PhptTestCase.php | 1 - src/TextUI/TestRunner.php | 8 ++-- tests/end-to-end/force-covers-annotation.phpt | 24 +++++++++++ .../force-covers-annotation/phpunit.xml | 16 ++++++++ .../force-covers-annotation/tests/Test.php | 18 ++++++++ 9 files changed, 92 insertions(+), 19 deletions(-) create mode 100644 tests/end-to-end/force-covers-annotation.phpt create mode 100644 tests/end-to-end/force-covers-annotation/phpunit.xml create mode 100644 tests/end-to-end/force-covers-annotation/tests/Test.php diff --git a/ChangeLog-9.2.md b/ChangeLog-9.2.md index 89d43367308..e1895ee0d72 100644 --- a/ChangeLog-9.2.md +++ b/ChangeLog-9.2.md @@ -10,6 +10,7 @@ All notable changes of the PHPUnit 9.2 release series are documented in this fil ### Changed +* [#4246](https://github.com/sebastianbergmann/phpunit/issues/4246): Tests that are supposed to have a `@covers` annotation are now marked as risky even if code coverage is not collected * The test runner no longer relies on `$_SERVER['REQUEST_TIME_FLOAT']` for printing the elapsed time [9.2.0]: https://github.com/sebastianbergmann/phpunit/compare/9.1...master diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php index 99cba683810..ff66d05c427 100644 --- a/src/Framework/TestCase.php +++ b/src/Framework/TestCase.php @@ -632,7 +632,6 @@ public function hasFailed(): bool * @throws UtilException * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException - * @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException * @throws \SebastianBergmann\CodeCoverage\RuntimeException * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException diff --git a/src/Framework/TestResult.php b/src/Framework/TestResult.php index e856dcda884..6250520ccba 100644 --- a/src/Framework/TestResult.php +++ b/src/Framework/TestResult.php @@ -17,7 +17,6 @@ use SebastianBergmann\CodeCoverage\CodeCoverage; use SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException as OriginalCoveredCodeNotExecutedException; use SebastianBergmann\CodeCoverage\Exception as OriginalCodeCoverageException; -use SebastianBergmann\CodeCoverage\MissingCoversAnnotationException as OriginalMissingCoversAnnotationException; use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; use SebastianBergmann\Invoker\Invoker; use SebastianBergmann\Invoker\TimeoutException; @@ -158,6 +157,11 @@ final class TestResult implements \Countable */ private $enforceTimeLimit = false; + /** + * @var bool + */ + private $forceCoversAnnotation = false; + /** * @var int */ @@ -596,7 +600,6 @@ public function getCollectCodeCoverageInformation(): bool * * @throws CodeCoverageException * @throws OriginalCoveredCodeNotExecutedException - * @throws OriginalMissingCoversAnnotationException * @throws UnintentionallyCoveredCodeException * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException * @throws \SebastianBergmann\CodeCoverage\RuntimeException @@ -773,6 +776,20 @@ public function run(Test $test): void $risky = true; } + if ($this->forceCoversAnnotation) { + $annotations = $test->getAnnotations(); + + if (!isset($annotations['class']['covers']) && !isset($annotations['method']['covers'])) { + $this->addFailure( + $test, + new MissingCoversAnnotationException( + 'This test does not have a @covers annotation but is expected to have one' + ), + $time + ); + } + } + if ($collectCodeCoverage) { $append = !$risky && !$incomplete && !$skipped; $linesToBeCovered = []; @@ -824,16 +841,6 @@ public function run(Test $test): void ), $time ); - } catch (OriginalMissingCoversAnnotationException $cce) { - if ($linesToBeCovered !== false) { - $this->addFailure( - $test, - new MissingCoversAnnotationException( - 'This test does not have a @covers annotation but is expected to have one' - ), - $time - ); - } } catch (OriginalCodeCoverageException $cce) { $error = true; @@ -1114,6 +1121,16 @@ public function isStrictAboutTodoAnnotatedTests(): bool return $this->beStrictAboutTodoAnnotatedTests; } + public function forceCoversAnnotation(): void + { + $this->forceCoversAnnotation = true; + } + + public function forcesCoversAnnotation(): bool + { + return $this->forceCoversAnnotation; + } + /** * Enables or disables the stopping for risky tests. */ diff --git a/src/Framework/TestSuite.php b/src/Framework/TestSuite.php index 95b11fe046f..d374b66faa4 100644 --- a/src/Framework/TestSuite.php +++ b/src/Framework/TestSuite.php @@ -550,7 +550,6 @@ public function setGroupDetails(array $groups): void * @throws \PHPUnit\Framework\CodeCoverageException * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException - * @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException * @throws \SebastianBergmann\CodeCoverage\RuntimeException * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException diff --git a/src/Runner/PhptTestCase.php b/src/Runner/PhptTestCase.php index 4161128eab6..ec2313addb9 100644 --- a/src/Runner/PhptTestCase.php +++ b/src/Runner/PhptTestCase.php @@ -103,7 +103,6 @@ public function count(): int * @throws Exception * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException - * @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException * @throws \SebastianBergmann\CodeCoverage\RuntimeException * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException diff --git a/src/TextUI/TestRunner.php b/src/TextUI/TestRunner.php index 10058a61809..e32d3c77ef5 100644 --- a/src/TextUI/TestRunner.php +++ b/src/TextUI/TestRunner.php @@ -541,10 +541,6 @@ public function run(TestSuite $suite, array $arguments = [], array $warnings = [ $arguments['strictCoverage'] ); - $codeCoverage->setForceCoversAnnotation( - $arguments['forceCoversAnnotation'] - ); - if (isset($arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'])) { $codeCoverage->setIgnoreDeprecatedCode( $arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'] @@ -627,6 +623,10 @@ public function run(TestSuite $suite, array $arguments = [], array $warnings = [ $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']); $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']); + if (isset($arguments['forceCoversAnnotation']) && $arguments['forceCoversAnnotation'] === true) { + $result->forceCoversAnnotation(); + } + $this->processSuiteFilters($suite, $arguments); $suite->setRunTestInSeparateProcess($arguments['processIsolation']); diff --git a/tests/end-to-end/force-covers-annotation.phpt b/tests/end-to-end/force-covers-annotation.phpt new file mode 100644 index 00000000000..e8755de2dde --- /dev/null +++ b/tests/end-to-end/force-covers-annotation.phpt @@ -0,0 +1,24 @@ +--TEST-- +phpunit ../../_files/BankAccountTest.php +--FILE-- + + + + + tests + + + + + + src + + + diff --git a/tests/end-to-end/force-covers-annotation/tests/Test.php b/tests/end-to-end/force-covers-annotation/tests/Test.php new file mode 100644 index 00000000000..5f937e1533b --- /dev/null +++ b/tests/end-to-end/force-covers-annotation/tests/Test.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +use PHPUnit\Framework\TestCase; + +final class Test extends TestCase +{ + public function testOne(): void + { + $this->assertTrue(true); + } +}