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

⚡ Розумний підсумок

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

  • 📐 Дві формули: V(G) = E – N + 2 з графіка, або V(G) = P + 1 з кількості точок прийняття рішення.
  • 🧮 Пряме значення: Значення дорівнює максимальній кількості незалежних шляхів, а отже, і необхідним тестовим випадкам.
  • 🗺️ Основа графіка: Вузли представляють кроки обробки, а ребра представляють потік керування між ними.
  • 🟢 1 до 10: Структурований, добре написаний код з високою тестованістю та низькими витратами на обслуговування.
  • 🟠 21 до 40: Дуже складний код з низькою тестованістю, де рефакторинг зазвичай коштує менше, ніж тестування.
  • 🛠️ інструменти: SonarQube, Visual Studio Code Метрики, Радон та Ящірка обчислюють це автоматично.

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

Що таке цикломатична складність Маккейба?

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

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

Цей показник був розроблений Томасом Дж. Маккейбом у 1976 році, і він базується на представленні потоку керування програмою. Потік керування зображує програму як граф, який складається з вузлів і ребер.

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

Цикломатична складність Маккейба

Нотація блок-графа для програми

Нотація Flow Graph для програми визначає кілька вузлів, з’єднаних ребрами. Нижче наведено блок-схеми для таких операторів, як if-else, While, until і звичайної послідовності потоку.

Нотація потокового графіка для програми

Як розрахувати цикломатичну складність

Математичне представлення:

Математично, це множина незалежних шляхів через графову діаграму. Code Складність програми можна визначити за формулою –

V(G) = E - N + 2

Де

E – кількість ребер

N – кількість вузлів

V (G) = P + 1

Де P = кількість предикатних вузлів (вузол, який містить умову)

Приклад -

i = 0;
n=4; //N-Number of nodes present in the graph

while (i<n-1) do
j = i + 1;

while (j<n) do

if A[i]<A[j] then
swap(A[i], A[j]);

end do;
j=j+1;

end do;

Потоковий графік для цієї програми буде

Розрахувати цикломатичну складність

Математичні обчислення,

  • V(G) = 9 – 7 + 2 = 4
  • V(G) = 3 + 1 = 4 (вузли умов — 1,2, 3 і XNUMX вузли)

Базовий набір, чотири незалежні шляхи виконання:

  • 1, 7
  • 1, 2, 6, 1, 7
  • 1, 2, 3, 4, 5, 2, 6, 1, 7
  • 1, 2, 3, 5, 2, 6, 1, 7

Властивості цикломатичної складності

Нижче наведено властивості цикломатичної складності:

  1. V (G) — максимальна кількість незалежних шляхів у графі
  2. V (G) >=1
  3. G матиме один шлях, якщо V (G) = 1
  4. Загальноприйнятим правилом є утримання V(G) на рівні 10 або нижче для одного модуля.

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

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

Ця метрика корисна через властивості цикломатичної складності (M) –

  1. M може бути кількістю тестів для досягнення покриття гілок (верхня межа)
  2. M може бути кількістю шляхів через графіки. (Нижня межа)

Розглянемо цей приклад –

If (Condition 1)
Statement 1

Else
Statement 2

If (Condition 2)
Statement 3

Else
Statement 4

Цикломатична складність для цієї програми буде 8-7+2=3.

Оскільки складність розрахована як 3, для повного покриття шляху для наведеного вище прикладу необхідні три тести.

Кроки, яких слід дотримуватися

Для обчислення цикломатичної складності та розробки тестових випадків необхідно виконати наступні кроки.

крок 1 – Побудова графа з вузлами та ребрами з коду

крок 2 – Виявлення незалежних шляхів

крок 3 – Розрахунок цикломатичної складності

крок 4 – Дизайн тестових випадків

Коли основний набір сформований, ТЕСТОВІ КЕЙСИ слід записати для виконання всіх шляхів.

Більше про V (G)

Цикломатичну складність можна розрахувати вручну, якщо програма невелика. Автоматизовані інструменти потрібно використовувати, якщо програма дуже складна, оскільки вона передбачає більше графів потоку. Виходячи з рівня складності, команда може зробити висновок про дії, які необхідно виконати для заходу.

У наступній таблиці наведено огляд числа складності та відповідного значення v (G):

Номер складності Сенс
1 до 10,

Структурований та добре написаний код

Висока тестоздатність

Витрати та зусилля менші

11 до 20,

Складний код

Середня тестованість

Вартість та зусилля середні

21 до 40,

Дуже складний код

Низька тестованість

Витрати та зусилля високі

> 40

Зовсім не перевіряється

Дуже високі витрати та зусилля

Інструменти для розрахунку цикломатичної складності

Для визначення складності програми доступно багато інструментів. Деякі інструменти розрахунку складності використовуються для конкретних технологій. Складність можна визначити за кількістю точок прийняття рішень у програмі. Точками прийняття рішення є оператори if, for, for-each, while, do, catch, case у вихідному коді.

Прикладами інструментів є

  • OCLint – Статичний аналізатор коду для C і споріднених мов
  • SonarQube – Повідомляє про цикломатичну та когнітивну складність у більш ніж 25 мовах
  • Visual Studio Code Метрики – вбудований цикломатичний аналіз складності для збірок .NET
  • Radon та Lizard – аналізатори складності командного рядка для Python та для багатомовних проектів відповідно
  • GMetrics – Знайти показники в Java пов'язані програми

Використання цикломатичної складності

Цикломатична складність може виявитися дуже корисною в

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

Як зменшити цикломатичну складність

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

  • Extracт-метод. Переміщення гілки в окрему функцію розподіляє складність між двома модулями. Загальна складність системи залишається незмінною, але кожен блок стає незалежно тестованим.
  • Замініть умовний ланцюжок пошуком. Довга сходинка if-in-if, яка перевіряє ту саму змінну, стає картою або перемикачем, що об'єднує багато точок прийняття рішень в одну.
  • Використовуйте охоронні речення. Раннє повернення при недійсному введенні видаляє вкладеність, яку створює один великий блок if-else, не змінюючи поведінки.
  • Замініть умовні оператори поліморфізмом. Там, де умова перемикає тип, переміщення кожної гілки в окремий клас повністю скасовує рішення.

Раніше, з V(G) = 4:

if (user != null) {
    if (user.isActive()) {
        if (user.hasRole("admin")) {
            return grantAccess();
        }
    }
}
return denyAccess();

Після, з такою ж поведінкою та видаленим вкладенням:

if (user == null) return denyAccess();
if (!user.isActive()) return denyAccess();
if (!user.hasRole("admin")) return denyAccess();
return grantAccess();

Застереження щодо метрики. Цикломатична складність враховує рішення, а не труднощі. Оператор switch з двадцятьма простими випадками має 21 бал, але його легко читати, тоді як глибоко вкладений блок, який отримує 8 балів, може бути набагато складнішим для розуміння. Використовуйте це число, щоб знайти кандидатів для розгляду, а не як ціль для маніпулювання.

Поширені запитання

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

Обидва дають однаковий результат. P + 1 швидший для ручного обчислення, оскільки ви враховуєте лише точки прийняття рішень. E – N + 2 – це те, що використовують інструменти, оскільки вони вже будують граф потоку керування.

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

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

Так. Помічники ШІ пропонують запобіжні положення, наприкладtracted методи та таблиці пошуку, що зменшують кількість. Перевірте поведінку за допомогою існуючого набору тестів, оскільки рефакторинг, який змінює логіку, зводить нанівець мету.

Підсумуйте цей пост за допомогою: