You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: [mutate] Windows: the 5 s minimum per-mutant timeout is shorter than a child boot under Xdebug, so untested mutants are scored as killed #1968
On Windows, pest --mutate scores some mutants as killed when no test can kill them, because their child process times out before the covering test has even run.
MutationTest::calculateTimeout() gives each mutant run the initial suite duration plus max(5, 20%):
When the targeted test set is small (a single test file, as when mutating one class), the initial suite takes ~2 s, so each child gets ~7 s. On Windows, booting a child Pest process (Laravel app) takes 4 to 7 s on its own, partly because children inherit XDEBUG_MODE=coverage and the --coverage-php=... argument (see the TODO: filter arguments to remove unnecessary stuff (Teamcity, Coverage, etc.) in MutationTest::start()). Some legitimate runs exceed the budget, hasFinished() maps the ProcessTimedOutException to Timeout, and the score counts Timeout as killed.
Expected: a mutant that no test kills is reported as untested, regardless of process start-up time.
How to Reproduce
On Windows, with Xdebug, write a test that executes a class but asserts nothing about it:
it('runs the code without checking anything', function () {
(newSomeValueObject(120.5, 80.0))->format();
expect(true)->toBeTrue();
});
Result: Mutations: 15 untested, 6 timeout, 0 tested, score 28.57 %. No test can kill any of these 21 mutants, so the expected score is 0 %.
With the minimum raised from 5 to 30 s on Windows (max(PHP_OS_FAMILY === 'Windows' ? 30 : 5, ...)), the same run reports 21 untested, 0 tested, score 0.00 %.
This was measured with the child-launch fix from #1916 applied (otherwise every mutant is scored as killed and this bug is invisible).
Sample Repository
None (private project). The reproduction above only needs any Laravel app with Pest and one class.
Filed here because issues are disabled on pestphp/pest-plugin-mutate.
Related: #1843 (timed-out mutants scored as killed, different root cause: a deadlock) and #1916 (child process fails to launch on Windows, also scored as killed). pestphp/pest-plugin-mutate#45 would make all three visible instead of silent.
Possible fixes, from least to most invasive:
do not pass coverage arguments/env to the per-mutant children (the existing TODO), which removes most of the start-up cost;
a higher minimum timeout, or a --mutate-timeout option;
report Timeout separately from kills in the score.
Activity