Skip to content

Commit 61f7c75

Browse files
Closes #4246
1 parent a7a3cf2 commit 61f7c75

File tree

9 files changed

+92
-19
lines changed

9 files changed

+92
-19
lines changed

ChangeLog-9.2.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ All notable changes of the PHPUnit 9.2 release series are documented in this fil
1010

1111
### Changed
1212

13+
* [#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
1314
* The test runner no longer relies on `$_SERVER['REQUEST_TIME_FLOAT']` for printing the elapsed time
1415

1516
[9.2.0]: https://github.com/sebastianbergmann/phpunit/compare/9.1...master

src/Framework/TestCase.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,6 @@ public function hasFailed(): bool
632632
* @throws UtilException
633633
* @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
634634
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
635-
* @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException
636635
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
637636
* @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException
638637
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException

src/Framework/TestResult.php

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use SebastianBergmann\CodeCoverage\CodeCoverage;
1818
use SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException as OriginalCoveredCodeNotExecutedException;
1919
use SebastianBergmann\CodeCoverage\Exception as OriginalCodeCoverageException;
20-
use SebastianBergmann\CodeCoverage\MissingCoversAnnotationException as OriginalMissingCoversAnnotationException;
2120
use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
2221
use SebastianBergmann\Invoker\Invoker;
2322
use SebastianBergmann\Invoker\TimeoutException;
@@ -158,6 +157,11 @@ final class TestResult implements \Countable
158157
*/
159158
private $enforceTimeLimit = false;
160159

160+
/**
161+
* @var bool
162+
*/
163+
private $forceCoversAnnotation = false;
164+
161165
/**
162166
* @var int
163167
*/
@@ -596,7 +600,6 @@ public function getCollectCodeCoverageInformation(): bool
596600
*
597601
* @throws CodeCoverageException
598602
* @throws OriginalCoveredCodeNotExecutedException
599-
* @throws OriginalMissingCoversAnnotationException
600603
* @throws UnintentionallyCoveredCodeException
601604
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
602605
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
@@ -773,6 +776,20 @@ public function run(Test $test): void
773776
$risky = true;
774777
}
775778

779+
if ($this->forceCoversAnnotation) {
780+
$annotations = $test->getAnnotations();
781+
782+
if (!isset($annotations['class']['covers']) && !isset($annotations['method']['covers'])) {
783+
$this->addFailure(
784+
$test,
785+
new MissingCoversAnnotationException(
786+
'This test does not have a @covers annotation but is expected to have one'
787+
),
788+
$time
789+
);
790+
}
791+
}
792+
776793
if ($collectCodeCoverage) {
777794
$append = !$risky && !$incomplete && !$skipped;
778795
$linesToBeCovered = [];
@@ -824,16 +841,6 @@ public function run(Test $test): void
824841
),
825842
$time
826843
);
827-
} catch (OriginalMissingCoversAnnotationException $cce) {
828-
if ($linesToBeCovered !== false) {
829-
$this->addFailure(
830-
$test,
831-
new MissingCoversAnnotationException(
832-
'This test does not have a @covers annotation but is expected to have one'
833-
),
834-
$time
835-
);
836-
}
837844
} catch (OriginalCodeCoverageException $cce) {
838845
$error = true;
839846

@@ -1114,6 +1121,16 @@ public function isStrictAboutTodoAnnotatedTests(): bool
11141121
return $this->beStrictAboutTodoAnnotatedTests;
11151122
}
11161123

1124+
public function forceCoversAnnotation(): void
1125+
{
1126+
$this->forceCoversAnnotation = true;
1127+
}
1128+
1129+
public function forcesCoversAnnotation(): bool
1130+
{
1131+
return $this->forceCoversAnnotation;
1132+
}
1133+
11171134
/**
11181135
* Enables or disables the stopping for risky tests.
11191136
*/

src/Framework/TestSuite.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,6 @@ public function setGroupDetails(array $groups): void
550550
* @throws \PHPUnit\Framework\CodeCoverageException
551551
* @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
552552
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
553-
* @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException
554553
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
555554
* @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException
556555
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException

src/Runner/PhptTestCase.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ public function count(): int
103103
* @throws Exception
104104
* @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
105105
* @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException
106-
* @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException
107106
* @throws \SebastianBergmann\CodeCoverage\RuntimeException
108107
* @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException
109108
* @throws \SebastianBergmann\RecursionContext\InvalidArgumentException

src/TextUI/TestRunner.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,6 @@ public function run(TestSuite $suite, array $arguments = [], array $warnings = [
541541
$arguments['strictCoverage']
542542
);
543543

544-
$codeCoverage->setForceCoversAnnotation(
545-
$arguments['forceCoversAnnotation']
546-
);
547-
548544
if (isset($arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'])) {
549545
$codeCoverage->setIgnoreDeprecatedCode(
550546
$arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage']
@@ -627,6 +623,10 @@ public function run(TestSuite $suite, array $arguments = [], array $warnings = [
627623
$result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']);
628624
$result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']);
629625

626+
if (isset($arguments['forceCoversAnnotation']) && $arguments['forceCoversAnnotation'] === true) {
627+
$result->forceCoversAnnotation();
628+
}
629+
630630
$this->processSuiteFilters($suite, $arguments);
631631
$suite->setRunTestInSeparateProcess($arguments['processIsolation']);
632632

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
phpunit ../../_files/BankAccountTest.php
3+
--FILE--
4+
<?php declare(strict_types=1);
5+
$_SERVER['argv'][1] = '--configuration';
6+
$_SERVER['argv'][2] = __DIR__ . '/force-covers-annotation/phpunit.xml';
7+
$_SERVER['argv'][3] = __DIR__ . '/force-covers-annotation/tests/Test.php';
8+
9+
require __DIR__ . '/../bootstrap.php';
10+
PHPUnit\TextUI\Command::main();
11+
--EXPECTF--
12+
PHPUnit %s by Sebastian Bergmann and contributors.
13+
14+
R 1 / 1 (100%)
15+
16+
Time: %s, Memory: %s
17+
18+
There was 1 risky test:
19+
20+
1) Test::testOne
21+
This test does not have a @covers annotation but is expected to have one
22+
23+
OK, but incomplete, skipped, or risky tests!
24+
Tests: 1, Assertions: 1, Risky: 1.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.2/phpunit.xsd"
4+
forceCoversAnnotation="true">
5+
<testsuites>
6+
<testsuite name="default">
7+
<directory suffix="Test.php">tests</directory>
8+
</testsuite>
9+
</testsuites>
10+
11+
<filter>
12+
<whitelist processUncoveredFilesFromWhitelist="true">
13+
<directory suffix=".php">src</directory>
14+
</whitelist>
15+
</filter>
16+
</phpunit>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
use PHPUnit\Framework\TestCase;
11+
12+
final class Test extends TestCase
13+
{
14+
public function testOne(): void
15+
{
16+
$this->assertTrue(true);
17+
}
18+
}

0 commit comments

Comments
 (0)