Що таке покриття коду

У цій статті ви дізнаєтеся, що таке покриття коду (code coverage), як почати працювати з цією метрикою, як обрати відповідний інструмент для її вимірювання та як правильно інтерпретувати результати.

Покриття коду — це показник, який допомагає зрозуміти, яка частина вихідного коду перевіряється тестами. Ця метрика широко використовується під час розробки програмного забезпечення, оскільки дозволяє оцінити ефективність і повноту тестового набору.

Чим більше частин коду охоплюють тести, тим вища ймовірність того, що система працює стабільно і критичні помилки будуть виявлені ще на етапі розробки.

Як розраховується покриття коду

Інструменти для вимірювання покриття аналізують, які частини програми виконуються під час запуску тестів. Для цього вони використовують різні критерії та формують звіти з кількома ключовими метриками.

Найпоширеніші з них:

Покриття функцій (Function Coverage). Показує, яка кількість функцій у програмі була викликана під час виконання тестів.

Покриття операторів (Statement Coverage). Відображає, скільки операторів або інструкцій коду було виконано.

Покриття гілок (Branch Coverage). Показує, чи були перевірені всі можливі гілки логіки програми, наприклад різні варіанти виконання умовних операторів.

Покриття умов (Condition Coverage). Визначає, чи були перевірені логічні підвирази у різних станах — коли вони повертають значення true і коли false.

Покриття рядків (Line Coverage). Показує, яка частина рядків вихідного коду була виконана під час тестування.

Зазвичай усі ці показники відображаються у звітах у вигляді:

  • кількості перевірених елементів
  • загальної кількості елементів у коді
  • відсотка покриття

Формула виглядає так: покриття = (кількість перевірених елементів / загальна кількість елементів) × 100%

Приклад різниці між типами покриття

Хоча ці метрики пов’язані між собою, вони вимірюють різні аспекти тестування. Це добре видно на простому прикладі.

Розглянемо невелику функцію JavaScript, яка перевіряє, чи є число кратним десяти:

function isMultipleOf10(x) {
if (x % 10 == 0)
return true;
else
return false;
}console.log(isMultipleOf10(100));

У цьому прикладі функція перевіряє, чи ділиться число на 10 без залишку. Після цього ми викликаємо її для значення 100.

Якщо запустити цей код разом з інструментом аналізу покриття, наприклад Istanbul, можна отримати звіт, який покаже, які частини коду були виконані.

Результати можуть виглядати приблизно так:

  • покриття функцій — 100%, оскільки функція була викликана під час виконання коду
  • покриття гілок — лише 50%, тому що була перевірена тільки одна гілка умови (true), а інша (false) не виконувалася

Також можна помітити, що деякі інструменти не обчислюють усі типи метрик. Наприклад, у стандартному звіті Istanbul метрика покриття умов може бути відсутня.

Цей приклад добре демонструє, що навіть при високому відсотку покриття функцій або рядків не всі логічні сценарії програми обов’язково перевірені.

Приклад коду

function isMultipleOf10(x) {
if (x % 10 == 0)
return true;
else
return false;
}console.log(isMultipleOf10(100));
console.log(isMultipleOf10(34)); // цей виклик змусить виконатися гілку "return false"

Після додавання другого виклику функції інструмент аналізу покриття покаже, що виконано обидві гілки умови. Завдяки цьому показник покриття для цього прикладу зросте до 100%, оскільки код тепер перевіряє і сценарій, коли умова повертає true, і сценарій, коли вона повертає false.

Досягнення 100% покриття за різними метриками

У нашому прикладі результати просто виводяться в консоль. Проте на практиці такий самий принцип використовується під час запуску автоматизованих тестів.

Інструмент для вимірювання покриття відстежує виконання тестів і визначає:

  • які функції були викликані
  • які оператори виконалися
  • які гілки умов були перевірені
  • які рядки коду фактично виконувалися

Після цього формується звіт, який показує рівень покриття для кожної з цих категорій.

Наприклад, інструмент Istanbul для JavaScript дозволяє створювати детальні звіти, де можна побачити, які саме частини коду виконувалися під час тестування, а які залишилися неперевіреними.

Покриття коду: 6 порад для початку

1. Оберіть правильний інструмент для свого проєкту

Вибір інструмента залежить насамперед від мови програмування, яку ви використовуєте. Для більшості популярних мов існують спеціалізовані рішення для вимірювання покриття.

Деякі з найпоширеніших інструментів:

Java

  • Atlassian Clover
  • Cobertura
  • JaCoCo

JavaScript

  • Istanbul

PHP

  • PHPUnit

Python

  • Coverage.py

Ruby

  • SimpleCov

Порівняння можливостей різних інструментів допоможе знайти найбільш зручне рішення. Деякі з них виводять результати прямо в термінал, тоді як інші можуть генерувати повноцінні HTML-звіти, де легко переглянути, які частини коду ще не покриті тестами.

2. Якого відсотка покриття слід прагнути

Не існує універсального значення покриття, яке гарантує якість програмного забезпечення. Навіть дуже високий показник покриття не означає, що всі важливі сценарії протестовані. Можлива ситуація, коли тести виконують більшість рядків коду, але при цьому не перевіряють критичні бізнес-сценарії.

У галузі часто вважається, що покриття на рівні приблизно 80% є хорошою практикою. Спроба досягти значно вищих значень може вимагати великих витрат часу, але не завжди дає пропорційний приріст якості. Якщо ви запускаєте інструмент покриття вперше, цілком нормально побачити досить низький відсоток. Це особливо поширено на початкових етапах розвитку тестування.

Не варто одразу намагатися штучно підняти показник до 80%. Надмірний тиск може призвести до того, що команда почне писати тести лише для того, щоб закрити кожен рядок коду, а не для перевірки реальних сценаріїв використання системи. Наприклад, у нашому попередньому прикладі ми досягли 100% покриття, перевіривши числа 100 і 34. Але залишається питання: що станеться, якщо передати у функцію рядок або інший тип даних?

Чи повинна функція повернути true або false? Чи має виникнути помилка?

Такі питання важливо розглядати з точки зору поведінки системи для користувача, а не лише з точки зору рядків коду. Метрика покриття сама по собі не покаже, чи пропустили ви важливі сценарії.

3. Почніть з модульних тестів

Модульні тести перевіряють окремі компоненти системи — функції, методи або класи.

Їх основні переваги:

  • швидке виконання
  • відносно проста реалізація
  • можливість швидко знайти помилки на ранньому етапі

Саме тому модульні тести часто стають першим кроком до підвищення покриття коду. Вони допомагають перевірити базову логіку програми і поступово охопити значну частину коду тестами.

4. Використовуйте звіти про покриття для пошуку прогалин

З часом тестів у проєкті стає настільки багато, що складно зрозуміти, які саме частини системи перевіряються. Коли збірка падає, ви бачите, що щось зламалося, але не завжди легко визначити, які компоненти взагалі були перевірені.

Саме тут звіти про покриття стають особливо корисними.

Більшість інструментів дозволяє:

  • переглядати код, який не був виконаний під час тестів
  • знаходити критичні ділянки без перевірок
  • визначати, де необхідно додати нові тести

Наприклад, SimpleCov для Ruby може показати, які методи або файли залишилися без тестування.

5. Інтегруйте покриття коду у процес безперервної інтеграції

Коли процес тестування стабільний, метрики покриття можна інтегрувати у систему безперервної інтеграції (CI). Це дозволяє автоматично перевіряти рівень покриття при кожній новій збірці.

Наприклад, можна налаштувати правило:

  • якщо покриття падає нижче певного порогу — збірка вважається невдалою

Проте важливо обирати реалістичні значення. Якщо встановити занадто високий поріг, наприклад 90%, це може призвести до частих збоїв збірки. Якщо ціль — 80%, можна встановити поріг перевірки на рівні 70%, щоб уникнути поступового зниження якості тестування.

При цьому варто пам’ятати, що надмірний тиск на команду щодо показників покриття може призвести до неякісних тестів.

6. Високе покриття не завжди означає хороші тести

Якісна культура тестування починається з розуміння того, як має поводитися система у різних сценаріях.

Необхідно перевіряти:

  • нормальну роботу системи
  • граничні випадки
  • неправильне використання
  • спроби зламати логіку програми

Інструменти покриття допомагають зрозуміти, де саме слід додати тести, але вони не можуть оцінити якість самих тестів.

Тому досягнення високого відсотка покриття має поєднуватися з продуманим тестовим набором, який перевіряє як окремі компоненти, так і цілісність системи.

Покриття коду — це важлива метрика, яка допомагає зрозуміти, наскільки добре тестами перевіряється програмний код. Вона дозволяє виявити частини системи, які ще не були протестовані, і допомагає команді поступово покращувати якість тестового набору.

Проте важливо пам’ятати, що високий відсоток покриття сам по собі не гарантує відсутності помилок. Набагато важливіше, щоб тести перевіряли реальні сценарії використання програми, охоплюючи нестандартні та помилкові ситуації.

Тому найкращий підхід — використовувати покриття коду як додатковий інструмент для аналізу якості тестування, поєднуючи його з продуманими тестами, які перевіряють як окремі компоненти, так і роботу системи в цілому.

Select the fields to be shown. Others will be hidden. Drag and drop to rearrange the order.
  • Image
  • SKU
  • Rating
  • Price
  • Stock
  • Availability
  • Add to cart
  • Description
  • Content
  • Weight
  • Dimensions
  • Additional information
Click outside to hide the comparison bar
Compare