Slide 1

Slide 1 text

Владимир Янц Мутационное тестирование в PHP

Slide 2

Slide 2 text

Проблема оценки качества тестов

Slide 3

Slide 3 text

Как оценить качество тестов?

Slide 4

Slide 4 text

Code Coverage 1. количественная, а не качественная метрика 2. есть продвинутые branch & path coverage, но нет инструмента для PHP 3. можно иметь 100% coverage, но это ничего не гарантирует

Slide 5

Slide 5 text

function isAdult(int $age) : bool { return $age > 18; } class MyTest extends \PHPUnit\Framework\TestCase { public function isAdultProvider() : array { return [ ['age' => 17, 'expected' => false], ['age' => 19, 'expected' => true], ]; } /** * @dataProvider isAdultProvider */ public function testIsAdult(int $age, bool $expected) : void { assertEquals($expected, isAdult($age)); } } Граничное условие не тестируется

Slide 6

Slide 6 text

function buildPromoBlock() : PromoBlock { return PromoBlock::create() ->setMssg('some_cool_text') ->setSomeThing(true) ->setAction('some_cool_action'); } class MyTest extends \PHPUnit\Framework\TestCase { public function testBuildPromoBlock() : void { $PromoBlock = buildPromoBlock(); assertEquals('some_cool_action', $PromoBlock->getAction()); assertEquals('some_cool_text', $PromoBlock->getMssg()); } } Нет ассерта на поле

Slide 7

Slide 7 text

Что такое мутационное тестирование?

Slide 8

Slide 8 text

Алгоритм

Slide 9

Slide 9 text

Берем исходный код 1

Slide 10

Slide 10 text

Получаем code coverage 2

Slide 11

Slide 11 text

Анализируем исходный код и генерируем мутантов 3

Slide 12

Slide 12 text

Mutant

Slide 13

Slide 13 text

function isAdult(int $age) : bool { return $age 18; } >= >

Slide 14

Slide 14 text

Мутации не хаотичны и осуществляются по заранее описанным правилам

Slide 15

Slide 15 text

Существуют десятки мутационных операторов для PHP

Slide 16

Slide 16 text

Прогоняем тесты, которые покрывают мутировавшую строчку 4

Slide 17

Slide 17 text

Оцениваем результат 5

Slide 18

Slide 18 text

Метрики

Slide 19

Slide 19 text

Немного терминологии KilledMutant

Slide 20

Slide 20 text

Немного терминологии EscapedMutant

Slide 21

Slide 21 text

Немного терминологии CoveredMutant

Slide 22

Slide 22 text

Mutation Score Indicator (MSI) KilledMutants / TotalMutants

Slide 23

Slide 23 text

Mutation Code Coverage CoveredMutants / TotalMutants

Slide 24

Slide 24 text

Covered Code MSI KilledMutants / CoveredMutants

Slide 25

Slide 25 text

Проблемы

Slide 26

Slide 26 text

1. скорость выполнения

Slide 27

Slide 27 text

1. параллелизация 2. инкрементальные прогоны 3. тюнинг мутаций

Slide 28

Slide 28 text

Мутационное тестирование только для UNIT-тестов

Slide 29

Slide 29 text

2. «бесконечные» мутанты

Slide 30

Slide 30 text

for ($i = 0; $i < 1; $i++) { … } $i--

Slide 31

Slide 31 text

1. тюнинг мутаций 2. таймаут для прогонов тестов

Slide 32

Slide 32 text

3. идентичные мутанты

Slide 33

Slide 33 text

$a *= -1; И $a /= -1;

Slide 34

Slide 34 text

конкретного решения нет

Slide 35

Slide 35 text

Инструменты для мутационного тестирования в PHP

Slide 36

Slide 36 text

Humbug vs Infection

Slide 37

Slide 37 text

здесь должно было быть сравнение фреймворков и выводы, что Infection лучше, НО github.com/humbug/humbug

Slide 38

Slide 38 text

Infection Humbug vs

Slide 39

Slide 39 text

Автор инструмента

Slide 40

Slide 40 text

Мутационное тестирование в Badoo

Slide 41

Slide 41 text

Infection — отличный инструмент

Slide 42

Slide 42 text

но не подошел для badoo.git

Slide 43

Slide 43 text

Code Coverage 1. сбор coverage занимает вечность (100 000 тестов) 2. можно «скормить» готовый, но это куча XML, > 30Гб

Slide 44

Slide 44 text

SoftMocks 1. наша open source библиотека для моков 2. Infection с ней несовместим, сделать совместимым можно только сильно сломав его архитектуру

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

1. Мутационные операторы утащили из Infection 2. Работает с SoftMocks 3. Дружит с нашим сервисом coverage 4. Простая, нет больше половины фичей Infection

Slide 47

Slide 47 text

Как используем?

Slide 48

Slide 48 text

Ручной прогон

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

Отчет по мастеру

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

Отчет по git branch

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

Что дало нам?

Slide 55

Slide 55 text

1 Coverage - хорошо, но еще ничего не гарантирует 2 Мутационное тестирование поможет сделать Unit- тесты лучше 3 Есть отличный инструмент - Infection! 4 Начните хотя бы прогонять мутации вручную Выводы

Slide 56

Slide 56 text

© 2019 [email protected] telegram: YantsV СПАСИБО! Ссылки 1. Infection PHP Mutation Testing Framework https:// infection.github.io 2. Humbug Mutation Testing for PHP https://github.com/ humbug/humbug 3. [Habr] Мутационное тестирование https://habr.com/ru/ post/334394/ (статья от автора Infection) 4. [Habr] SoftMocks: наша замена runkit для PHP 7 https://habr.com/ru/company/badoo/blog/279617/ http://bit.ly/BadooPHPMeetup2