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
PHPUnit 9.3 compatibility issue #1283
Comments
I would assume so, too. To be sure: which changes does Infection make to On a related note: are you missing CLI options that you could use instead of manipulating the XML configuration file?
I am not convinced that it is Infection's responsibility to configure code coverage when the project Infection is used for does not configure code coverage in its XML configuration file for PHPUnit. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
It does two sets of changes, one is to remove certain things like logging out of way, and add our own bootstrap procedure, and second set is about adding a list of tests we want to run to tests against certain mutation. Last time I checked it wasn't possible to specify a list of files to run from the command line, only a directory. Indeed, some of the things we have to do here have a corresponding command line option, but I think since we have to alter |
9.3 is not compatible with Infection yet infection/infection#1283
@sanmai based on what I saw in the code Infection is only removing the existing loggers/printers. How these affect Infection's behaviour? Apart from that, what's the minimum PHPUnit version that Infection offers compatibility? @sebastianbergmann I see PHPUnit offers the argument |
No. |
We have several cases where we disable/enable certain things from the configuration file. About removing the existing printers, I can speculate as to why but @maks-rafalko might know a definite answer. |
I remember there was a discussion, but I don't remember seeing a conclusion. But I might be biased towards no conclusion since I routinely use Infection with the likes of PHPUnit 6. But if we support PHPUnit 8, supporting earlier versions should require no effort. |
Because Infection isn't fully compatible with PHPUnit 9.3+ format yet. More info: infection/infection#1283
Right. When Infection removes loggers, it does so for performance reasons. If you have a coverage logger, PHPUnit will activate the machinery to collect coverage data, which in turn will make everything slower.
Let's consider what Infection does. It takes a file, and makes a small change to it. Then it runs a bunch of tests to see if they notice the change. And repeats this process over and over. If you leave coverage loggers this will quickly add up, at worst cases making all things twice as slow. @lcobucci Makes sense? |
@sanmai sure thing, I was just trying to find the right balance for this. My suggestion to solve this issue is a mix of everything we discussed:
What do you think? |
I'm on board with this idea because:
@theofidry @maks-rafalko What do you think? |
@sanmai sorry it's been a while, at what point and in what case do we try to configure the coverage? I thought this was purely for the loggers (which IMO we should be the ones configuring) |
Under "configure the coverage" I mean the loggers and the filtering, where the latter is going to be called just coverage moving forward. They have changed very substantially in 9.3. The problem here is that we're configuring them using old syntax, which kind of works sometimes, but sometimes it does not, and that's a problem because it'll get convoluted very quickly if we try to work around it straight away. |
I am quite conflicted here. I see where you guys are coming from and we can question this whole PHPUnit manipulation. Instead we could generate one at the init step and then require the user to keep it up to date, Infection would use it directly. This is another direction which has its pros and cons. Meanwhile for now we are configuring PHPUnit ourselves. Regarding the filtering: we are explicitly asking the user which files to cover (the source directories) so IMO requiring the user to configure his PHPUnit config to match this (and in case one forgets, gets a big disparity in the result without any warning) is a non insignificant step back from a UX. An alternative solution: we know the PHPUnit version used, since we check it to ensure we are working with a supported version (especially useful when using the PHPUnit PHAR or using the Infection PHAR). So maybe there is a way to pass that version and adjust the filtering settings depending of the version used? |
@theofidry not really, running PHPUnit 9.3 with the old format works. The issue happens for users who have already updated the config file because Infection mixes up the old and new formats. |
Then it should be easy to inspect if there is already a configuration in place and either adjust it or leave it untouched (since the user already configured it) no? |
@theofidry have you seen the patch? It does what you're suggesting in a way that's compatible with all versions. I'll leave the decision up to you folks, I'm changing all my libs to generate the coverage with phpunit directly to avoid this issue, so I won't put much pressure on the matter. Let me know if I can help in any way. |
Oh totally missed that patch thanks. I can't say I find it pretty, but looks ok to me and it's also a quite easily testable class so I could live with it. But I'm quite deep a rabbit hole at work with very dirty and obscure workarounds and issues so maybe it makes this workaround look much better than it is... |
I've added a description of another workaround. It seems to be working fine at the moment, but if anyone wishes to test it, I'd be happy to hear any feedback. |
@sebastianbergmann Is it reasonable to expect that PHPUnit 10 won't accept legacy configuration format? |
Yes. |
Fixes #1283 to the point we're using Infection with the newest PHPUnit configuration.
PHPUnit 9.3 comes with a change of terminology and structure, mainly going away from blacklist/whitelist, but not only.
Infection has to change provided
phpunit.xml
to run each and every mutation. So far I can tell these changes are in the clear.The problem is in the changes Infection adding to collect coverage during the initial test. Specifically it will add
<filter>
tag like below, even if there is PHPUnit 9.3 compatible<coverage>
directive:Signs of legacy configuration:
Signs of updated configuration:
Possible solution
There are several consideration:
<coverage>
element before adding<filter>
element. If it so happens that thisphpunit.xml
is being used with earlier version of PHPUnit that isn't aware of this new element, then this will be caught during validation against xsd.<coverage>
or<filter>
elements. In this case we can check ifvendor/phpunit/phpunit/phpunit.xsd
mentions<coverage>
element, and then decide to add either, but to be honest I'd rather see Infection fail with an explanation.phpunit.xsd
. This does not say that we cannot have a negative dependency, that is a future version of Infection can be in conflict with earlier versions of PHPUnit by standard means offered bycomposer.json
.Alternative solution
As for failing with a message, Infection could check if there are
<coverage>
or<filter>
elements, and if not, fail with an explanation instead of adding such elements.Workaround
Current workaround is to run PHPUnit to collect coverage before running Infection like so:
vendor/bin/phpunit --coverage-xml=build/logs/coverage-xml --log-junit=build/logs/junit.xml vendor/bin/infection --skip-initial-tests --threads=$(nproc) --coverage=build/logs --show-mutations --no-interaction
I'd like to think this is the right way to run Infection during CI, but there might be other opinions.
Another workaround
If you do not plan to use PHPUnit older than 9.3, there's another workaround. One problem here is that Infection tries to validate updated
phpunit.xml
, but it uses newest schema where PHPUnit will be happy to use older one. When we instruct Infection to use older schema, it just works. Just like so:This workaround requires the least amount of effort if you don't mind being nagged by PHPUnit about "--migrate-configuration" now and then.
If you do plan to use PHPUnit 9.2 or earlier together with 9.3, then you would probably need to inject something like this somewhere in your CI pipeline:
Thanks to @terabytesoftw for pointing at these changes.
The text was updated successfully, but these errors were encountered: