рд▓реЗрдЦрди рдкрд░реАрдХреНрд╖рдг рдХреЛ рдХреЛрдб рдХреЗ рд╕рд╣реА рд╕рдВрдЪрд╛рд▓рди рдореЗрдВ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЛ рдкреНрд░реЗрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдХреНрд╕рд░ рд╣рдо рдХреЛрдб рдХреЗ рдХрд╡рд░реЗрдЬ рдХреА рдбрд┐рдЧреНрд░реА рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рд╣рдо 100% рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдорд╛рдзрд╛рди рд╕рд╣реА рд╣реИред рдХреНрдпрд╛ рдЖрдк рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд╣реИрдВ? рд╢рд╛рдпрдж рдПрдХ рдЙрдкрдХрд░рдг рд╣реИ рдЬреЛ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдЧрд╛?
рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдг
рдпрд╣ рд╢рдмреНрдж рдПрдХ рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдХреЛрдб рдХреЗ рдЫреЛрдЯреЗ рдЯреБрдХрдбрд╝реЛрдВ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдХреИрд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐, рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдмрд╛рдж, рдкрд░реАрдХреНрд╖рдг рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреЛрдб рдХреЗ рдЗрди рдЯреБрдХрдбрд╝реЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИрдВред рдмреЗрд╢рдХ, рдпрд╣ рд╕рдм рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдмрджрд▓ рд░рд╣реЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рд╕рднреА рд╕рдмрд╕реЗ рдЫреЛрдЯреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрдВрдбреЗрдВрдЯ рдпрд╛ рдЪрд░ рдирд╛рдо, рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХреЗ рдмрд╛рдж рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рднреА рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреВрд░рд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рд╣рдо рддрдерд╛рдХрдерд┐рдд рдореНрдпреВрдЯреЗрдЯрд░ (рд╕рдВрд╢реЛрдзрдХ рд╡рд┐рдзрд┐рдпреЛрдВ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рдХреЛрдб рдХреЛ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рддрд░рд╣ рд╕реЗ рдЬреЛ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдиреАрдЪреЗ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред рдХрднреА-рдХрднреА рд╣рдо рдЦреБрдж рдРрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рдЕрдЧрд░ рд╣рдо рдХреЛрдб рдореЗрдВ рдХреБрдЫ рдмрджрд▓рддреЗ рд╣реИрдВ рддреЛ рдЬрд╛рдБрдЪ рдЯреВрдЯ рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рд╣рдордиреЗ "рдЖрдзрд╛ рд╕рд┐рд╕реНрдЯрдо" рдХреЛ рд░рд┐рдлреИрдХреНрдЯ рдХрд┐рдпрд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЕрднреА рднреА рд╣рд░реЗ рд╣реИрдВ, рддреЛ рд╣рдо рддреБрд░рдВрдд рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдЦрд░рд╛рдм рд╣реИрдВред рдФрд░ рдЕрдЧрд░ рдХрд┐рд╕реА рдиреЗ рдРрд╕рд╛ рдХрд┐рдпрд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЕрдЪреНрдЫреЗ рдереЗ, рддреЛ рдмрдзрд╛рдИ!
рд╕рдВрдХреНрд░рд╛рдордХ рдлреНрд░реЗрдорд╡рд░реНрдХ
рдЖрдЬ PHP рдореЗрдВ, рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдг рдврд╛рдВрдЪрд╛
рд╕рдВрдХреНрд░рдордг рд╣реИ ред рдпрд╣ PHPUnit рдФрд░ PHPSpec рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП PHP 7.1+ рдФрд░ Xdebug рдпрд╛ phpdbg рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдкрд╣рд▓рд╛ рд▓реЙрдиреНрдЪ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
рдкрд╣рд▓реА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдо рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рдЬреЛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд┐рд╢реЗрд╖ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рддрд╛ рд╣реИ - рд╕рдВрдХреНрд░рдордгред json.distред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
{ "timeout": 10, "source": { "directories": [ "src" }, "logs": { "text": "infection.log", "perMutator": "per-mutator.md" }, "mutators": { "@default": true }
Timeout
- рдПрдХ рд╡рд┐рдХрд▓реНрдк рдЬрд┐рд╕рдХрд╛ рдореВрд▓реНрдп рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХреА рдЕрдзрд┐рдХрддрдо рдЕрд╡рдзрд┐ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
source
рд╣рдо рдЙрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдирд╕реЗ рд╣рдо рдХреЛрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВрдЧреЗ, рдЖрдк рдЕрдкрд╡рд╛рдж рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
logs
рдореЗрдВ рдПрдХ
text
рд╡рд┐рдХрд▓реНрдк рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо рдХреЗрд╡рд▓ рдЧрд▓рдд рдкрд░реАрдХреНрд╖рдгреЛрдВ рдкрд░ рдЖрдБрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред
perMutator
рд╡рд┐рдХрд▓реНрдк рдЖрдкрдХреЛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдП рдЧрдП
perMutator
рдХреЛ рдмрдЪрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдкрдврд╝реЗрдВред
рдЙрджрд╛рд╣рд░рдг
final class Calculator { public function add(int $a, int $b): int { return $a + $b; } }
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрдкрд░реЛрдХреНрдд рд╡рд░реНрдЧ рд╣реИред рдЖрдЗрдП PHPUnit рдореЗрдВ рдПрдХ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВ:
final class CalculatorTest extends TestCase { private $calculator; public function setUp(): void { $this->calculator = new Calculator(); } public function testAdd(int $a, int $b, int $expected): void { $this->assertEquals($expected, $this->calculator->add($a, $b)); } public function additionProvider(): array { return [ [0, 0, 0], [6, 4, 10], [-1, -2, -3], [-2, 2, 0] ]; } }
рдмреЗрд╢рдХ, рдпрд╣ рдкрд░реАрдХреНрд╖рдг
add()
рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬрдм рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛ
./vendor/bin/phpunit
рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:
PHPUnit 8.2.2 by Sebastian Bergmann and contributors. .... 4 / 4 (100%) Time: 39 ms, Memory: 4.00 MB OK (4 tests, 4 assertions)
рдЕрдм рдЪрд▓рд╛рдПрдВ
./vendor/bin/infection
:
You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /
рд╕рдВрдХреНрд░рдордг рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рд╕рдЯреАрдХ рд╣реИрдВред
Per-mutator.md рдлрд╝рд╛рдЗрд▓ рдореЗрдВ
, рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдореНрдпреВрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:
рдореНрдпреВрдЯреЗрдЯрд░ рдкреНрд▓рд╕ рдкреНрд▓рд╕ рд╕реЗ рдорд╛рдЗрдирд╕ рддрдХ рд╕рд╛рдЗрди рдХрд╛ рдПрдХ рд╕рд░рд▓ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИ, рдЬреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рддреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░
PublicVisibility
рдЙрддреНрдкрд░рд┐рд╡рд░реНрддреА рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдПрдХреНрд╕реЗрд╕ рд╕рдВрд╢реЛрдзрдХ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рднреА рддреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЕрдм рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
public function findGreaterThan(array $numbers, int $threshold): array { return \array_values(\array_filter($numbers, static function (int $number) use ($threshold) { return $number > $threshold; })); } public function testFindGreaterThan(array $numbers, int $threshold, array $expected): void { $this->assertEquals($expected, $this->calculator->findGreaterThan($numbers, $threshold)); } public function findGreaterThanProvider(): array { return [ [[1, 2, 3], -1, [1, 2, 3]], [[-2, -3, -4], 0, []] ]; }
рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдмрд╛рдж, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВрдЧреЗ:
You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /
рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдареАрдХ рдирд╣реАрдВ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, infection.log рдлрд╝рд╛рдЗрд▓ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:
Escaped mutants: ================ 1) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:19 [M] UnwrapArrayValues --- Original +++ New @@ @@ */ public function findGreaterThan(array $numbers, int $threshold) : array { - return \array_values(\array_filter($numbers, static function (int $number) use($threshold) { + return \array_filter($numbers, static function (int $number) use($threshold) { return $number > $threshold; - })); + }); } 2) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:20 [M] GreaterThan --- Original +++ New @@ @@ public function findGreaterThan(array $numbers, int $threshold) : array { return \array_values(\array_filter($numbers, static function (int $number) use($threshold) { - return $number > $threshold; + return $number >= $threshold; })); } Timed Out mutants: ================== Not Covered mutants: ====================
рдкрд╣рд▓реА рдЕрдирд╕реБрд▓рдЭреА рд╕рдорд╕реНрдпрд╛
array_values
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐
array_filter
рдорд╛рдиреЛрдВ рдХреЛ рдкрд┐рдЫрд▓реА рд╕рд░рдгреА рд╕реЗ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдРрд╕рд╛ рдХреЛрдИ рдорд╛рдорд▓рд╛ рдирд╣реАрдВ рд╣реИ рдЬрдм
array_values
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреНрдпрдерд╛ рдПрдХ рд╣реА рдорд╛рди рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рд▓реЗрдХрд┐рди рд╡рд┐рднрд┐рдиреНрди рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рджреВрд╕рд░реА рд╕рдорд╕реНрдпрд╛ рд╕реАрдорд╛рд╡рд░реНрддреА рдорд╛рдорд▓реЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рддреБрд▓рдирд╛ рдореЗрдВ, рд╣рдордиреЗ
>
рд╕рд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рд╣рдо рдХрд┐рд╕реА рднреА рд╕реАрдорд╛ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП
>=
рд╕рд╛рде рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдЯреВрдЯрддреЗ рд╣реИрдВред рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
public function findGreaterThanProvider(): array { return [ [[1, 2, 3], -1, [1, 2, 3]], [[-2, -3, -4], 0, []], [[4, 5, 6], 4, [5, 6]] ]; }
рдФрд░ рдЕрдм рд╕рдВрдХреНрд░рдордг рд╕рдм рдХреБрдЫ рд╕реЗ рдЦреБрд╢ рд╣реИ:
You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /
Calculator
рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ
subtract
рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ, рд▓реЗрдХрд┐рди PHPUnit рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд┐рдирд╛:
public function subtract(int $a, int $b): int { return $a - $b; }
рдФрд░ рдЗрдиреНрдлреЗрдХреНрд╢рди рдЪрд▓рдиреЗ рдХреЗ рдмрд╛рдж рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ:
You are running Infection with Xdebug enabled. ____ ____ __ _ / _/___ / __/__ _____/ /_(_)___ ____ /
рдЗрд╕ рдмрд╛рд░, рдЯреВрд▓ рдиреЗ рджреЛ рдЦреБрд▓рд╛ рдореНрдпреВрдЯреЗрд╢рди рд▓реМрдЯрд╛ рджрд┐рдПред
Escaped mutants: ================ Timed Out mutants: ================== Not Covered mutants: ==================== 1) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:24 [M] PublicVisibility --- Original +++ New @@ @@ return $number > $threshold; })); } - public function subtract(int $a, int $b) : int + protected function subtract(int $a, int $b) : int { return $a - $b; } 2) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:26 [M] Minus --- Original +++ New @@ @@ public function subtract(int $a, int $b) : int { - return $a - $b; + return $a + $b; }
рдореИрдЯреНрд░рд┐рдХреНрд╕
рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдмрд╛рдж, рдЙрдкрдХрд░рдг рддреАрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рд▓реМрдЯрд╛рддрд╛ рд╣реИ:
Metrics: Mutation Score Indicator (MSI): 47% Mutation Code Coverage: 67% Covered Code MSI: 70%
Mutation Score Indicator
- рдкрд░реАрдХреНрд╖рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкрддрд╛ рдЪрд▓рд╛ рдореНрдпреВрдЯреЗрд╢рди рдХрд╛ рдкреНрд░рддрд┐рд╢рддред
рдореАрдЯреНрд░рд┐рдХ рдХреА рдЧрдгрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:
TotalDefeatedMutants = KilledCount + TimedOutCount + ErrorCount; MSI = (TotalDefeatedMutants / TotalMutantsCount) * 100;
Mutation Code Coverage
- рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХреЛрдб рдХрд╛ рдЕрдиреБрдкрд╛рддред
рдореАрдЯреНрд░рд┐рдХ рдХреА рдЧрдгрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:
TotalCoveredByTestsMutants = TotalMutantsCount - NotCoveredByTestsCount; CoveredRate = (TotalCoveredByTestsMutants / TotalMutantsCount) * 100;
Covered Code Mutation Score Indicator
- рдкрд░реАрдХреНрд╖рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдП рдЧрдП рдХреЛрдб рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдкреНрд░рднрд╛рд╡рд╢реАрд▓рддрд╛ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдореАрдЯреНрд░рд┐рдХ рдХреА рдЧрдгрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:
TotalCoveredByTestsMutants = TotalMutantsCount - NotCoveredByTestsCount; TotalDefeatedMutants = KilledCount + TimedOutCount + ErrorCount; CoveredCodeMSI = (TotalDefeatedMutants / TotalCoveredByTestsMutants) * 100;
рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╡рд░реНрдЧ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдмрд┐рдирд╛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рдВрдХреНрд░рдордг рдЪрд▓рд╛рдпрд╛ред рд▓реЗрдХрд┐рди рд╕рд╛рдзрд╛рд░рдг рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рдХрд╛рдо рдореЗрдВ
тАУfilter
рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛, рдЬреЛ рдЖрдкрдХреЛ рдЙрди рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рди рдкрд░ рд╣рдо рдореНрдпреВрдЯреЗрд╢рди рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
./vendor/bin/infection --filter=Calculator.php
рдЭреВрдареА рд╕рдХрд╛рд░рд╛рддреНрдордХрддрд╛
рдХреБрдЫ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЛрдб рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╕рдВрдХреНрд░рдордг 100% рд╕реЗ рдХрдо рдПрдордПрд╕рдЖрдИ рджреЗрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рд╣рдореЗрд╢рд╛ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреБрдЫ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдРрд╕реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдЖрдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рд╣реА рдХреБрдЫ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:
public function calcNumber(int $a): int { return $a / $this->getRatio(); } private function getRatio(): int { return 1; }
рдмреЗрд╢рдХ, рдпрд╣рд╛рдБ
getRatio
рдкрджреНрдзрддрд┐ рдХрд╛
getRatio
рдирд╣реАрдВ рд╣реИ, рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рд╕рдВрднрд╡рддрдГ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рд╣реЛрдЧреАред рд▓реЗрдХрд┐рди рдкрд░рд┐рдгрд╛рдо
1
рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рдВрдХреНрд░рдордг рд░рд┐рдЯрд░реНрди:
Escaped mutants: ================ 1) /home/sarven/projects/infection-playground/infection-playground/src/Calculator.php:26 [M] Division --- Original +++ New @@ @@ public function calcNumber(int $a) : int { - return $a / $this->getRatio(); + return $a * $this->getRatio(); } private function getRatio() : int
рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ, рдореВрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░, 1 рд╕реЗ рдЧреБрдгрд╛ рдХрд░рдирд╛ рдФрд░ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдПрдХ рд╣реА рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред рддреЛ рдпрд╣ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдирд╣реАрдВ рддреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╕рдЯреАрдХрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдВрдХреНрд░рдордг рдХреЗ рд╡рд┐рдЪреНрдЫреЗрджрди рдХреЗ рдмрд╛рд╡рдЬреВрдж, рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рд╣реИред
рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рди
рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдВрдХреНрд░рдордг рдмрд╣реБрдд рд╕рдордп рд▓реЗ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдХреЗрд╡рд▓ рд╕рдВрд╢реЛрдзрд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЖрдк CI рдХреЗ рджреМрд░рд╛рди рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджреЗрдЦреЗрдВ:
https://infection.imtqy.com/guide/how-to.htmlрдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рд╕рдВрд╢реЛрдзрд┐рдд рдХреЛрдб рдкрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдХреЗрд╡рд▓ рддрднреА рд╕рдВрднрд╡ рд╣реИ рдЬрдм рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд╕реНрд╡рддрдВрддреНрд░ рд╣реЛрдВред рдЕрд░реНрдерд╛рддреН, рдРрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдЕрдЪреНрдЫреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
тАУthreads
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
./vendor/bin/infection --threads=4
рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ?
Infection рдврд╛рдВрдЪреЗ рдореЗрдВ AST (Abstract Syntax Tree) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╕рд╛рд░ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, PHP (
php-parser ) рдХреЗ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП
рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЙрдкрдХрд░рдг рдХреЗ рд╕рд░рд▓реАрдХреГрдд рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
- рдХреЛрдб рдЖрдзрд╛рд░рд┐рдд рдПрдПрд╕рдЯреА рдкреАрдврд╝реАред
- рдЙрдкрдпреБрдХреНрдд рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди (рдкреВрд░реНрдг рд╕реВрдЪреА рдпрд╣рд╛рдВ рд╣реИ ) рдХрд╛ рдЙрдкрдпреЛрдЧред
- рдПрдПрд╕рдЯреА рдЖрдзрд╛рд░рд┐рдд рд╕рдВрд╢реЛрдзрд┐рдд рдХреЛрдб рдмрдирд╛рдПрдБред
- рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХреЛрдб рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдПрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдорд╛рдЗрдирд╕ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдореНрдпреВрдЯреЗрдЯрд░ рдкреНрд▓рд╕ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
<?php declare(strict_types=1); namespace Infection\Mutator\Arithmetic; use Infection\Mutator\Util\Mutator; use PhpParser\Node; use PhpParser\Node\Expr\Array_; final class Plus extends Mutator { public function mutate(Node $node) { return new Node\Expr\BinaryOp\Minus($node->left, $node->right, $node->getAttributes()); } protected function mutatesNode(Node $node): bool { if (!($node instanceof Node\Expr\BinaryOp\Plus)) { return false; } if ($node->left instanceof Array_ || $node->right instanceof Array_) { return false; } return true; } }
mutate()
рд╡рд┐рдзрд┐ рдПрдХ рдирдпрд╛ рддрддреНрд╡ рдмрдирд╛рддреА рд╣реИ, рдЬрд┐рд╕реЗ рдПрдХ рдкреНрд▓рд╕ рджреНрд╡рд╛рд░рд╛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
Node
рд╡рд░реНрдЧ php-parser рдкреИрдХреЗрдЬ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ; рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдПрд╕рдЯреА рдкрд░рд┐рдЪрд╛рд▓рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдФрд░ PHP рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╣реАрдВ рднреА рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП
mutatesNode()
рд╡рд┐рдзрд┐ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рд╢рд░реНрддреЗрдВ рд╣реИрдВред рдпрджрд┐ рдкреНрд▓рд╕ рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдпрд╛ рдорд╛рдЗрдирд╕ рдХреЗ рджрд╛рдИрдВ рдУрд░ рдПрдХ рд╕рд░рдгреА рд╣реИ, рддреЛ рдкрд░рд┐рд╡рд░реНрддрди рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред рдЗрд╕ рдХреЛрдб рдХреЗ рдХрд╛рд░рдг рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
$tab = [0] + [1]; is correct, but the following one isn't correct. $tab = [0] - [1];
рдкрд░рд┐рдгрд╛рдо
рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдкрд░реАрдХреНрд╖рдг рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрдкрдХрд░рдг рд╣реИ рдЬреЛ рд╕реАрдЖрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдкреВрд░рдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╣рд░реА рд╣рд╛рдЗрд▓рд╛рдЗрдЯрд┐рдВрдЧ рд╣рдореЗрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рджрд┐рд▓рд╛рддреА рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдк рдореНрдпреВрдЯреЗрд╢рдирд▓ рдкрд░реАрдХреНрд╖рдг - рдпрд╛ рдкрд░реАрдХреНрд╖рдг рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рд╕рдЯреАрдХрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЬреЛ рд╕рдорд╛рдзрд╛рди рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╣рдорд╛рд░реЗ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИред рдмреЗрд╢рдХ, рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ 100% рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЖрдкрдХреЛ рд▓реЙрдЧ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдкрд░реАрдХреНрд╖рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред