Мутаційні тести
Тема мутаційного тестування, на жаль, не є дуже популярною. Про цей вид тестування мало хто знає і ще менше хто використовує. Але він може стати вам у нагоді при аналізі покриття коду юніт тестами.
Покривати код тестами — завжди гарна ідея. Але як дізнатись чи хороші у нас тести ? Чи коректні перевірки ?
Мутаційні тести покликані перевірити наші тести.
Уявіть тест, який немає перевірки. Або можливо результат перевіряється не повністю. Тобто, щоб не перевіряти весь об’єкт, перевіряється просто, що він не NULL. У таких випадках інструмент аналізу покриття коду (Sonar наприклад), скаже, що код покритий, хоча тести будуть погані.
Також, якщо ми пропустили якийсь набір вхідних даних — мутаційні тести зможуть виявити це.
Як це працює
- Аналізується існуючий код і у нього вводяться зміни мутатором і в результати версія нашого коду називається мутантом. Наш код незмінний, окрім однієї деталі. Мутатор — mutator — тип помилки, яка вводиться у код. Наприклад, арифметичний мутатор : у коді є операція + мутатор замінить її на —
- Запускаються тести
- Якщо результат тесту на мутанті відмінний від оригінального — мутант вбитий (killed). Це добре, означає, що тест відловлює зміни у коді.
- Якщо результат двох тестів однаковий — мутант живий (survived). Це означає, що код почав працювати інакше, а тести не відловили зміни. Це погано.
- Після цього розраховується рахунок — mutation score — співвідношення між вбитими та живими мутантами.
Інструменти
На жаль, не існує багато інструментів для мутаційного тестування. З того, що зараз є на ринку :
- Stryker — існує для JS\TS, Scala та .NET. Власне, приклад буде на останньому
- PIT — використовується на JAVA
Це не єдині інструменти, але вони найбільш популярні.
Приклад
Для прикладу візьмемо фреймворк Stryker для платформи .NET. Гітхаб проекту. Для початку вам потрібен ваш код на мові C# та проект з юніт тестами.
Давайте покроково
- Відкрийте локацію з вашим проектом тестів у консолі та виконайте команду
dotnet tool install -g dotnet-stryker
- Або можна встановити nuget пакет для цього проекту. Назва пакету dotnet-stryker
- Запустіть з командного рядка команду
dotnet stryker
- Буде згенерована тека StrykerOutput, у якій буде міститись репорт по мутантах
- Обравши файл, можна побачити, який саме мутатор був використаний і де
- можна обрати і вбитих мутантів
Мутатори
Основним елементом мутаційних тестів є мутатори. Які основні види мутаторів існують :
- арифметичні — змінюють арифметичні операції а протилежні
- логічні — змінюють логічний оператор, наприклад з операції І на операцію АБО
- Порівняльні- змінюють знаки порівнять. Наприклад, з > на =<
- Boolean — змінюють логічне значення на протилежне. з true на false
- Рядкові — змінюють рядок
- LINQ — змінюють LINQ метод. наприклад, з
Last()
наFirst()
З детальним списком можна познайомитись ось тут
Підсумок
Мутаційні тести доволі рідко використовують, але як бачите з прикладу — насправді це легко. Звісно, з недоліків варто виділити, що аналіз великого продукту, може зайняти ГОДИНИ та варто розуміти, що якийсь відсоток мутантів може бути безглуздим. Але не спробувавши — не дізнаєшся. Тому, якщо ви шукаєте нові способи покращення якості ваших тестів — мутанти можуть стати у нагоді.