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 — це важливий підхід до тестування з точки зору користувача, який дозволяє протестувати реальні сценарії використання та підвищує якість програмного забезпечення, бо орієнтований на цілі.

State Transition Testing

State Transition Testing (тестування переходів станів) — це техніка тестування програмного забезпечення, яка використовується для перевірки поведінки системи, що змінюється в залежності від її поточного стану та дії користувача чи зовнішнього середовища.

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

Ключова ідея

Уявімо, що програма — це як машина, яка може перебувати в різних станах (наприклад: “не ввійшов у систему”, “авторизований”, “заблокований” тощо). Залежно від того, в якому вона стані, одна й та сама дія може мати різні наслідки.

Наприклад:

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

Тобто, контекст (стан) має значення, і саме це ми тестуємо через State Transition Testing.

Основні поняття

ПоняттяПояснення
Стан (State)Це поточне положення системи, що впливає на її поведінку. Наприклад: “увійшов”, “заблокований”, “чекає дії”.
Подія (Event/Input)Це дія або вхідна інформація, що викликає зміну стану. Наприклад: введення пароля, натискання кнопки.
Перехід (Transition)Це рух системи з одного стану до іншого під впливом події. Наприклад: з “неавторизований” до “авторизований”.
Дія (Action)Це те, що система виконує у відповідь на подію: наприклад, показ повідомлення, блокування акаунта.

Коли варто застосовувати State Transition Testing?

Ця техніка доцільна, якщо:

  • Система має чітко визначені стани.
  • Поведінка системи змінюється в залежності від попередніх дій користувача.
  • Є умовні переходи, наприклад: лише після певної послідовності дій доступна певна функція.

Приклади систем, де це актуально:

  • Авторизація користувачів (введення логіну/паролю, блокування при помилках).
  • Автоматизовані системи (банкомати, автомати продажу квитків).
  • Ігри (стани гравця: живий, поранений, мертвий).
  • Веб-додатки з “мультисторінковим” введенням даних.

Приклад:

Сценарій: Банкомат (ATM) — тестування процесу авторизації користувача

Можливі стани:

  • S0: Очікування картки
  • S1: Введення PIN
  • S2: Авторизовано
  • S3: Заблоковано (після 3 неправильних PIN)

Можливі події / дії користувача:

  • Insert Card – вставити картку
  • Enter Correct PIN – правильний PIN
  • Enter Wrong PIN – неправильний PIN
  • Eject Card – витягнути картку

Таблиця переходів станів:

Поточний станВхідна подіяНаступний станКоментар
S0Insert CardS1Картку вставлено
S1Enter Correct PINS2Авторизація успішна
S2Eject CardS0Картку витягнуто
S0Insert CardS1Картку вставлено
S1Enter Wrong PIN (1x)S1Перша помилка PIN
S1Enter Correct PINS2Авторизація успішна
S2Eject CardS0Картку витягнуто
S0Insert CardS1Картку вставлено
S1Enter Wrong PIN (1x)S1Перша помилка PIN
S1Enter Wrong PIN (2x)S1Друга помилка PIN
S1Enter Correct PINS2Авторизація успішна
S2Eject CardS0Картку витягнуто
S0Insert CardS1Картку вставлено
S1Enter Wrong PIN (1x)S1Перша помилка PIN
S1Enter Wrong PIN (2x)S1Друга помилка PIN
S1Enter Wrong PIN (3x)S3Три помилки: блокування

Діаграма:

State Transition Testing Diagram

Типи покриття в State Transition Testing

Коли ми тестуємо переходи між станами, ми можемо будувати різні стратегії покриття, щоб перевірити всю логіку:

Тип покриттяЩо означає
Покриття станів (State coverage)Перевірити, що кожен можливий стан системи хоча б раз досягається.
Покриття переходів (Transition coverage)Перевірити, що кожен можливий перехід між станами був виконаний.
Покриття послідовностей переходівПеревірка кількох переходів підряд, як вони працюють у комбінації.
Негативне тестуванняПеревірка, як система реагує на неприпустимі дії в певних станах.

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

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

Позитивний сценарій

  • Передумова: Картка ще не вставлена.
  • Кроки:
    1. Вставити картку.
    2. Ввести правильний PIN.
    3. Обрати операцію.
    4. Завершити сесію.
  • Очікування: Транзакція проходить успішно, картка витягується.

Негативний сценарій

  • Передумова: Картка вставлена.
  • Кроки:
    1. Ввести 3 рази неправильний PIN.
  • Очікування: Акаунт блокується, транзакції недоступні.

Переваги State Transition Testing

Допомагає знайти:

  • логічні помилки в переходах;
  • помилки в обробці неправильних дій;
  • відсутність очікуваних переходів або станів.

Добре підходить для:

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

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