Condition Testing

Condition Testing (тестування умов) — це структурний метод тестування програмного забезпечення, при якому тестуються логічні умови в коді з метою виявлення помилок у логіці.

Цей тип тестування належить до тестування білої скриньки (white-box testing), тобто, коли тестувальник має доступ до коду програми і перевіряє внутрішню логіку виконання.

Мета Condition Testing

Основні цілі:

  1. Перевірити логіку умовних виразів
    • Кожна частина складної умови повинна бути перевірена на істинність (true) та хибність (false).
  2. Забезпечити правильність роботи кожної окремої умови
  3. Збільшити покриття коду
    • Щоб усі логічні умови були перевірені, і в результаті — знайдено більше потенційних помилок.
  4. Забезпечити надійність програми
    • Особливо важливо для критичних систем (медицина, авіація, банківські системи).

Що таке умова (Condition)?

Умова — це логічний вираз, який може бути істинним або хибним. Наприклад:

if (x > 0 && y < 10)

У цьому виразі є дві атомарні умови:

  1. x > 0
  2. y < 10

Вони об’єднані за допомогою логічного оператора && (AND).

Чому недостатньо просто перевірити весь if?

Можна протестувати, чи виконується if, але не перевірити, як поводить себе кожна умова окремо. Наприклад:

  • Якщо x > 0 завжди істинне у всіх тестах, ми не знаємо, як поводиться програма, коли x <= 0.
  • Якщо y < 10 завжди хибне — ми не перевіряємо гілку, де воно стає істинним.

Тестування лише результату if не гарантує правильності логіки усіх умов у виразі.

Що саме тестується в Condition Testing?

  • Кожна атомарна умова (елемент логічного виразу)
  • Перевіряється, чи вона може бути як true, так і false
  • Перевіряється, чи вона впливає на результат усього виразу

Види тестування умов

Види покриттяОпис
Condition CoverageКожна атомарна умова в логічному виразі перевіряється на true і false
Decision (Branch) CoverageПеревірка, що кожна гілка рішення (if, else, switch) виконується хоча б раз
Condition/Decision CoverageКомбіноване покриття — кожна умова і кожне рішення
MC/DC (Modified Condition/Decision Coverage)Перевірка, що кожна умова впливає на результат рішення незалежно

Приклад:

def check_discount(age, is_member):
    if age > 65 or is_member:
        return "Discount"
    else:
        return "No Discount"

Тут маємо 2 умови поєднані логічним оператором or:

  • age > 65
  • is_member

Щоб провести condition testing, потрібно створити такі тести:

Test Caseage > 65is_memberРезультат
1TrueFalseDiscount
2FalseTrueDiscount
3FalseFalseNo Discount
4TrueTrueDiscount

Тут кожна умова приймає значення true і false принаймні один раз.

Чому Condition Testing важливе?

  1. Знаходить логічні помилки, які не видно при поверхневому тестуванні.
  2. Гарантує, що кожен логічний елемент працює як треба
  3. Допомагає при розробці складних алгоритмів — особливо там, де є багато if/else, циклів, вкладених умов.

Підсумок

ПараметрОпис
Що це?Тестування атомарних умов у логічних виразах
МетаПеревірити, чи кожна умова працює як треба
Основна діяКожна умова тестується на true і false
ПеревагаЗнаходить логічні помилки на ранній стадії

Branch Testing

Branch testing — це техніка тестування програмного забезпечення, що полягає в перевірці кожної гілки умовних операторів (наприклад, if, else, switch) у програмі. Це метод, який дозволяє перевірити, чи будуть виконуватися всі можливі варіанти розгалужень в програмному коді.

Мета:

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

Як це працює?

У більшості мов програмування ми маємо умовні оператори або конструкції, які змінюють хід виконання програми в залежності від певних умов. Коли умова виконується, програма “розгалужується” на два або більше можливих шляхи виконання. Branch testing полягає в тому, щоб перевірити кожен з цих шляхів, щоб переконатися, що вони правильно обробляються.

Приклад: простий умовний оператор

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

def check_number(x):
    if x > 0:
        return "positive"
    else:
        return "non-positive"

У цьому коді є одне умовне розгалуження: перевірка умови if x > 0. Це розгалуження створює дві гілки:

  • Гілка 1: умова x > 0 істинна, тобто виконується код в першій частині if, і повертається "positive".
  • Гілка 2: умова якщо x > 0 не виконується, тобто є хибною, себто виконується код в блоці else, і повертається "non-positive".

Щоб провести branch testing, нам потрібно протестувати обидві гілки:

  • Один тест, де x > 0 (наприклад, x = 5).
  • Один тест, де x <= 0 (наприклад, x = -1 або x = 0).

Тільки в цьому випадку ми можемо бути впевнені, що обидві гілки були виконані і правильно працюють.

Чому важливо тестувати кожну гілку?

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

  • Логічні помилки: Іноді програма працює не так, як очікується, через помилки в логіці розгалужень. Наприклад, неправильно оброблена умова може призвести до неочікуваних результатів.
  • Виконання всіх можливих шляхів: Кожна умова може мати декілька варіантів виконання в залежності від значень, що передаються в програму. Тестування лише одного шляху може не виявити помилки, які виникають при інших значеннях.

Branch Coverage: як вимірюється ефективність?

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

Формула:

Branch coverage (%) = (Кількість виконаних гілок / Загальна кількість гілок) × 100%

Трохи складніший приклад:

def analyze_number(x):
    if x > 0:
        return "positive"
    elif x == 0:
        return "zero"
    else:
        return "negative"

Тут ми маємо 3 можливі гілки:

  1. x > 0 — це позитивна гілка.
  2. x == 0 — це гілка для нуля.
  3. x < 0 — це негативна гілка.

Щоб досягти 100% branch coverage, потрібно виконати 3 тести:

  • Один, де x > 0 (наприклад, x = 5).
  • Один, де x == 0 (наприклад, x = 0).
  • Один, де x < 0 (наприклад, x = -1).

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

Різниця між Branch Testing і Statement Testing

Statement testing та branch testing — це дві різні техніки:

  • Statement testing — перевіряє лише, чи виконуються всі окремі оператори (наприклад, if, return). У цьому випадку перевіряється, чи виконується сам оператор, незалежно від того, яким чином виконується умова.
  • Branch testing — перевіряє, чи були виконані всі можливі гілки умов, тобто чи перевірялися всі шляхи виконання програми, які можуть виникнути через умови.

Чи завжди достатньо branch testing?

Branch testing — це вагомий метод, але інколи його може бути недостатньо для повної перевірки програми, особливо коли мова йде про складні логічні конструкції або великі проекти. Для кращого покриття можна поєднувати branch testing з іншими техніками тестування, такими як:

  • Path testing: Перевірка всіх можливих шляхів виконання програми, що включає не тільки розгалуження, але й їх комбінації.
  • Condition coverage: Перевірка кожної умови, щоб вона була істинною та хибною.

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

Statement testing

Statement testing — це один із базових підходів до тестування програмного забезпечення, який належить до категорії white-box testing (тестування з доступом до коду). Його мета — перевірити, чи всі оператори (інструкції) у програмному коді були виконані хоча б один раз під час тестування.

Основна ідея

Програма складається з набору інструкцій (наприклад, присвоєння, виклики функцій, умовні переходи тощо). Statement testing гарантує, що тестові випадки проходять через усі ці інструкції, тобто кожна з них потрапляє у coverage (покриття).

Приклад:

def is_positive(n):
    if n > 0:
        return True
    else:
        return False

Щоб покрити всі інструкції:

  • Нам потрібно перевірити випадок, коли n > 0 — виконається return True
  • І випадок, коли n <= 0 — виконається return False

Якщо протестувати лише з n = 5, то буде виконано лише return True, і покриття буде неповним.

Вимірювання

Результат statement testing часто виражається у відсотках покриття коду — statement coverage:

Statement Coverage = (Кількість виконаних інструкцій / Загальна кількість інструкцій) × 100%

Переваги:

  • Простий у реалізації.
  • Допомагає виявити “мертвий код” (який ніколи не виконується).

Недоліки:

  • Не гарантує покриття всіх умов або гілок (наприклад, не перевіряє всі варіанти if/else або циклів).
  • Може пропустити помилки, якщо інструкція виконується, але не в усіх логічних сценаріях.

Порівняння з іншими видами:

Тип тестуванняЩо перевіряє
Statement TestingЧи виконана кожна інструкція
Branch TestingЧи виконана кожна гілка (if/else)
Path TestingЧи пройдені всі можливі шляхи
Condition TestingЧи перевірені всі умови логіки

Підсумок

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

White Box Test Techniques

White Box Test Techniques (техніки тестування білої скриньки) — це підхід до тестування програмного забезпечення, при якому тестувальник має доступ до внутрішньої структури коду (наприклад, логіки, умов, циклів, змінних тощо) і використовує цю інформацію для розробки тестів.

Основна ідея:

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

Основні техніки White Box Testing:

  1. Coverage-based Testing (тестування на покриття):
    • Statement Coverage (покриття операторів) — перевіряє, що кожен оператор (рядок коду) виконується хоча б один раз.
    • Branch Coverage (покриття гілок) — перевіряє, що всі можливі гілки умов (if/else) були пройдені.
    • Condition Coverage — перевіряє, що кожна умова в логічному виразі приймала і true, і false.
  2. Path Coverage (покриття шляхів) — перевіряє всі можливі шляхи виконання через програму.
  3. Loop Testing — тестування циклів (наприклад, перевірити цикл при 0, 1 та багатьох ітераціях).
  4. Control Flow Testing — аналіз керуючого потоку програми: як виконання переходить від одного блоку до іншого.
  5. Data Flow Testing — аналіз, як дані передаються і змінюються в програмі (від моменту ініціалізації до використання).

Переваги:

  • Високий рівень покриття коду.
  • Виявлення «мертвого» або невикористаного коду.
  • Допомагає знайти логічні помилки.

Недоліки:

  • Не підходить для тестування без доступу до коду (наприклад, сторонніх сервісів).
  • Вимагає знань програмування.
  • Не покриває питання зручності інтерфейсу чи бізнес-логіки — тільки реалізацію.

Use Case Testing

Use Case Testing (Тестування на основі сценаріїв використання) — це метод тестування програмного забезпечення, при якому тестові сценарії створюються на основі use cases — описів того, як користувачі взаємодіють із системою для досягнення певної цілі.

Іншими словами, ми перевіряємо, чи працює система так, як її очікує бачити користувач у реальному житті.

Основи Use Case (варіанту використання)

Use Case — це сценарій взаємодії користувача з системою. Він включає актора, мету, передумови, основний потік, альтернативи, виключення.

КомпонентОпис
АкторХто використовує систему (користувач, адміністратор, інша система)
Мета (ціль)Що актор хоче зробити
ПередумовиЩо має бути виконано до початку
Основний потікКроки, які ведуть до успішного завершення
АльтернативиІнші варіанти виконання
ВиключенняЩо відбувається при помилці

Як проводиться Use Case Testing?

Крок 1: Збір use cases

Це може бути:

  • UML діаграми
  • Опис у вигляді тексту
  • Специфікація вимог

Наприклад, бізнес-аналітик створює документ із сценаріями, які повинен підтримувати продукт.

Крок 2: Аналіз варіантів використання

Визначаємо:

  • основні сценарії (успішне завершення)
  • альтернативні шляхи
  • виняткові ситуації (некоректні дії користувача, помилки системи)

Крок 3: Створення тест-кейсів

Для кожного сценарію створюються тест-кейси, які перевіряють:

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

Приклад

Use Case: Авторизація користувача

КомпонентДеталі
АкторКористувач
МетаУвійти в систему
ПередумоваКористувач має обліковий запис
Основний потік1. Користувач вводить логін і пароль
2. Натискає “Увійти”
3. Система перевіряє дані
4. Система впускає користувача
Альтернативний потікПароль неправильний — показати помилку
ВиключенняСервер не доступний — повідомлення про помилку з’єднання

Приклади тест-кейсів:

Test Case IDНазваКрокиОчікуваний результат
TC001Успішна авторизаціяВвести правильний логін/пароль, натиснути “Увійти”Вхід у систему
TC002Неправильний парольВвести логін + неправильний парольПовідомлення: “Невірний пароль”
TC003Порожнє поле логінаЗалишити поле логіна пустимПовідомлення: “Заповніть логін”
TC004Сервер недоступнийВвести дані, але сервер не відповідаєПовідомлення: “Сервер тимчасово недоступний”

Де це застосовується?

Use Case Testing застосовується при:

  • Функціональному тестуванні
  • Інтеграційному тестуванні
  • Системному тестуванні
  • User Acceptance Testing (UAT)

Чому це важливо?

ПеревагаПояснення
Орієнтація на користувачаТестування реальних сценаріїв використання
Покриття бізнес-логікиНе лише технічні аспекти, а саме бізнес-мета
Краще розуміння між командоюОдні й ті ж use cases використовуються BA, QA, Dev
Легше виявити інтеграційні помилкиUse cases часто охоплюють кілька модулів одночасно

Use Case Testing vs Інші типи тестування

Тип тестуванняОрієнтаціяПриклад
Use Case TestingБізнес-сценаріїВхід користувача, замовлення товару
Unit TestingОкрема функціяПеревірка функції login()
Functional TestingОкрема функція/екранПеревірка роботи форми логіну
Integration TestingЗв’язки між модулямиЛогін + перевірка прав доступу

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