Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code coverage changed between 9.2.17 and 9.2.18 #953

Closed
kukulich opened this issue Nov 1, 2022 · 7 comments
Closed

Code coverage changed between 9.2.17 and 9.2.18 #953

kukulich opened this issue Nov 1, 2022 · 7 comments

Comments

@kukulich
Copy link

kukulich commented Nov 1, 2022

phpunit/php-code-coverage 9.2.17

before

phpunit/php-code-coverage 9.2.18

after

The problem is that infection/infection now think the line is not covered and reports mutants.

With phpunit/php-code-coverage 9.2.17: 10 mutants were not covered by tests
With phpunit/php-code-coverage 9.2.18: 68 mutants were not covered by tests

29) /home/runner/work/BetterReflection/BetterReflection/src/Reflection/StringCast/ReflectionAttributeStringCast.php:27    [M] Concat

--- Original
+++ New
@@ @@
     {
         $arguments = $attributeReflection->getArguments();
         $argumentsFormat = $arguments !== [] ? " {\n  - Arguments [%d] {%s\n  }\n}" : '';
-        return sprintf('Attribute [ %s ]' . $argumentsFormat . "\n", $attributeReflection->getName(), count($arguments), self::argumentsToString($arguments));
+        return sprintf($argumentsFormat . 'Attribute [ %s ]' . "\n", $attributeReflection->getName(), count($arguments), self::argumentsToString($arguments));
     }
@Slamdunk
Copy link
Contributor

Slamdunk commented Nov 2, 2022

There's a lot to talk about here.

First: IMHO infection shouldn't generate mutants for lines that php-code-coverage doesn't consider executable.
Maybe this should be "resolved" by using --only-covered infection's flag, I'm not really sure, but that's none of php-code-coverage business

Second: is 'Attribute [ %s ]' . $argumentsFormat . "\n" and executable line?
I've done some research, and yes it should be because $argumentsFormat could undergo a typecasting during Concat that may generate errors (like a __toString() class), so indeed we should take this into account

Third: does a fix for the second point resolve the issue completely? No.
Take into consideration this example:

/* 1 */    $var
/* 2 */        =
/* 3 */            'a'
/* 4 */            .
/* 5 */            'b'
/* 6 */    ;

The only real executable line is 1 according to xDebug and PCOV, but Infection\Mutator\Operator\Concat doesn't care and Infection will ALWAYS report 'a' . 'b' to 'b' . 'a' mutation as uncovered.
And this would also apply to a plethora of Mutators where code heavily relies on multilines.

Conclusion: a fix is needed to count variables as executable lines during Concat operations, but use --only-covered with Infection otherwise we can't help further

@sebastianbergmann
Copy link
Owner

IMHO infection shouldn't generate mutants for lines that php-code-coverage doesn't consider executable

Agreed.

@theofidry
Copy link

IIRC the reason why infection does it by default is a mix of historical reasons (humbug was doing so as well) and because the goal is to "make sure your tests are good". Since you cannot assert that your code is covered, allowing to mutate non covered codes allows to check that (since you can make infection fail if you don't meet the desired MSI score).

Also there is an argument to be made that some mutants could be killed by other things than tests, such as phpstan/psalm type violation or an obscure black box bash script. Although I think we should be able to manage those scenarios regardless of the flag at some point.

@Slamdunk
Copy link
Contributor

Slamdunk commented Nov 8, 2022

Posted a bug on Infection: infection/infection#1750

Meanwhile, I'll do my best to have meaningful CC here in the upcoming days

@sebastianbergmann
Copy link
Owner

Meanwhile, I'll do my best to have meaningful CC here in the upcoming days

Thank you so much for your work on this!

@mvorisek
Copy link
Contributor

mvorisek commented Nov 10, 2022

see mvorisek#2 (comment)

for example:

u(
$a,
$b . 'x',
);

xdebug outputs (/w opcache) only line 1 as executable (covered/uncovered) if $a and $b is known ($a/b = const expr)

if line 2 and line 3 should be covered, we need to analyse if variable is comming from const expr or not.

Title should be changed to something like "Impl. local variable static analysis and add coverage line for non-const variable". We can then prune also definitively non-reachable if branches.

mvorisek added a commit to mvorisek/php-code-coverage that referenced this issue Nov 10, 2022
Ocramius added a commit to Roave/BetterReflection that referenced this issue Nov 13, 2022
Coverage decreased, mutants increased, caused mostly
by some expressions no longer being considered
as covered code.

This is a regression that only affects our infection
runs: not really other runtime bugs.

For now, we pin to an older coverage tooling.

Ref: sebastianbergmann/php-code-coverage#953
Ocramius added a commit to Roave/SecurityAdvisoriesBuilder that referenced this issue Nov 30, 2022
Ocramius added a commit to Ocramius/GeneratedHydrator that referenced this issue Dec 1, 2022
Ocramius added a commit to Ocramius/GeneratedHydrator that referenced this issue Dec 1, 2022
Ocramius added a commit to Roave/BetterReflection that referenced this issue Dec 5, 2022
Ocramius added a commit to Ocramius/infection that referenced this issue Dec 13, 2022
Fixes infection#1773

Because of sebastianbergmann/php-code-coverage#953,
the current coverage reports used by `infection/infection` are
unreliable, and we cannot reliably use them for computing covered
mutants in most codebases.

This patch introduces a temporary conflict, to be lifted after
@Slamdunk's work on sebastianbergmann/php-code-coverage#964
lands in upstream.

Quoting original issue:

 > As mentioned in the title, it would be useful to (temporarily) add `"conflict": {"phpunit/php-code-coverage": ">9.2.17"}` to the constraints of this package.
 >
 > The reason: coverage report became massively unreliable for the purposes of mutation testing starting with `phpunit/php-code-coverage:9.2.18`, as reported by @kukulich and acknowledged by @Slamdunk in sebastianbergmann/php-code-coverage#953
 >
 > This is only a temporary measure: @Slamdunk has been talking with me about it, and he's hard at work on it in sebastianbergmann/php-code-coverage#964, which should fix the problem, but which may take more time to land.
 >
 > At this moment, many mutation test suites keep going red due to invalid reduced coverage (some packages were even at 100%, and need constant adjustments when `composer.lock` gets changed).
 >
 > Therefore, it would be healthy to declare an incompatibility in a new minor release, for now.
theofidry pushed a commit to infection/infection that referenced this issue Dec 13, 2022
Fixes #1773

Because of sebastianbergmann/php-code-coverage#953,
the current coverage reports used by `infection/infection` are
unreliable, and we cannot reliably use them for computing covered
mutants in most codebases.

This patch introduces a temporary conflict, to be lifted after
@Slamdunk's work on sebastianbergmann/php-code-coverage#964
lands in upstream.

Quoting original issue:

 > As mentioned in the title, it would be useful to (temporarily) add `"conflict": {"phpunit/php-code-coverage": ">9.2.17"}` to the constraints of this package.
 >
 > The reason: coverage report became massively unreliable for the purposes of mutation testing starting with `phpunit/php-code-coverage:9.2.18`, as reported by @kukulich and acknowledged by @Slamdunk in sebastianbergmann/php-code-coverage#953
 >
 > This is only a temporary measure: @Slamdunk has been talking with me about it, and he's hard at work on it in sebastianbergmann/php-code-coverage#964, which should fix the problem, but which may take more time to land.
 >
 > At this moment, many mutation test suites keep going red due to invalid reduced coverage (some packages were even at 100%, and need constant adjustments when `composer.lock` gets changed).
 >
 > Therefore, it would be healthy to declare an incompatibility in a new minor release, for now.
@kukulich
Copy link
Author

Fixed in #964

uzibhalepu added a commit to uzibhalepu/BackwardCompatibilityCheck that referenced this issue Aug 6, 2024
This patch reduces code size, therefore leading to
generally lower scores.

Until we completely switch to `pcov` and the upstream
issues with `sebastianbergmann/php-code-coverage`
are resolved, we will keep having sub-100% mutation
test scores.

Ref: sebastianbergmann/php-code-coverage#945
Ref: sebastianbergmann/php-code-coverage@c304be7
Ref: laminas/laminas-continuous-integration-action#130
Ref: sebastianbergmann/php-code-coverage#953
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants