Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

То, что тесты должны быть как можно проще, и при этом быстры и стабильны — понятно всем. Но как измерить эти качества и ответить на вопрос «А хорошо ли мой тест проверяет код»?

Один из способов разобраться в этом — мутационное тестирование. Этот инструмент, внося небольшие правки в исходный код и перепрогоняя после этого тесты, позволяет выявить бесполезные тесты и низкокачественное покрытие.

В своем докладе я расскажу, как можно организовать мутационное тестирование для PHP-кода, с какими проблемами вы можете столкнуться, а также покажу, как мы внедряем это в Badoo.

Badoo Tech

March 16, 2019
Tweet

More Decks by Badoo Tech

Other Decks in Programming

Transcript

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

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

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

  4. Code Coverage 1. количественная, а не качественная метрика 2. есть

    продвинутые branch & path coverage, но нет инструмента для PHP 3. можно иметь 100% coverage, но это ничего не гарантирует
  5. 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)); } } Граничное условие не тестируется
  6. 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()); } } Нет ассерта на поле
  7. Что такое мутационное тестирование?

  8. Алгоритм

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

  10. Получаем code coverage 2

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

  12. Mutant

  13. function isAdult(int $age) : bool { return $age 18; }

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

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

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

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

  18. Метрики

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

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

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

  22. Mutation Score Indicator (MSI) KilledMutants / TotalMutants

  23. Mutation Code Coverage CoveredMutants / TotalMutants

  24. Covered Code MSI KilledMutants / CoveredMutants

  25. Проблемы

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

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

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

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

  30. for ($i = 0; $i < 1; $i++) { …

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

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

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

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

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

  36. Humbug vs Infection

  37. здесь должно было быть сравнение фреймворков и выводы, что Infection

    лучше, НО github.com/humbug/humbug
  38. Infection Humbug vs

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

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

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

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

  43. Code Coverage 1. сбор coverage занимает вечность (100 000 тестов)

    2. можно «скормить» готовый, но это куча XML, > 30Гб
  44. SoftMocks 1. наша open source библиотека для моков 2. Infection

    с ней несовместим, сделать совместимым можно только сильно сломав его архитектуру
  45. None
  46. 1. Мутационные операторы утащили из Infection 2. Работает с SoftMocks

    3. Дружит с нашим сервисом coverage 4. Простая, нет больше половины фичей Infection
  47. Как используем?

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

  49. None
  50. Отчет по мастеру

  51. None
  52. Отчет по git branch

  53. None
  54. Что дало нам?

  55. 1 Coverage - хорошо, но еще ничего не гарантирует 2

    Мутационное тестирование поможет сделать Unit- тесты лучше 3 Есть отличный инструмент - Infection! 4 Начните хотя бы прогонять мутации вручную Выводы
  56. © 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