core code helper

Тест-дизайн: класи еквівалентності та граничні значення

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

0 імпортували Імпортувати собі

Протестувати «все» неможливо: навіть поле для віку приймає мільярди різних рядків. Тест-дизайн відповідає на питання які саме перевірки дадуть максимум користі за мінімум зусиль. Дві техніки, з яких варто почати, — класи еквівалентності та аналіз граничних значень.

Класи еквівалентності

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

Приклад. Поле «Вік» у формі реєстрації страхового полісу. Вимога: приймаються цілі числа від 18 до 65 включно.

Клас Опис Приклад Очікування
E1 Допустимий вік 30 Прийнято
E2 Менше мінімуму 10 Помилка «Мінімальний вік — 18»
E3 Більше максимуму 80 Помилка «Максимальний вік — 65»
E4 Не число abc Помилка формату
E5 Дробове число 25.5 Помилка формату
E6 Порожнє поле — Помилка «Обов'язкове поле»

Шість тестів замість нескінченності — і кожен перевіряє окрему гілку логіки.

Порада

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

Граничні значення

Розробники часто помиляються саме на межах: < замість <=, зсув на одиницю в циклі, неправильне округлення. Тому для кожної межі перевіряють значення на межі і поруч з нею.

Для діапазону 18–65:

Межа Значення для перевірки
Нижня 17 (невалідне), 18 (валідне), 19
Верхня 64, 65 (валідне), 66 (невалідне)
Увага

Межі бувають не лише в числах. Довжина рядка (0, 1, max, max+1 символів), кількість елементів у кошику, дати (29 лютого, перехід на літній час, 31 грудня → 1 січня), розмір файлу (рівно 10 МБ, якщо ліміт 10 МБ).

Комбінуємо: повний набір для поля

TC-01  вік = 18        → прийнято        (нижня межа)
TC-02  вік = 17        → помилка мінімуму
TC-03  вік = 65        → прийнято        (верхня межа)
TC-04  вік = 66        → помилка максимуму
TC-05  вік = 30        → прийнято        (типове значення)
TC-06  вік = "abc"     → помилка формату
TC-07  вік = 25.5      → помилка формату
TC-08  вік = ""        → обов'язкове поле
TC-09  вік = " 30 "    → ? (уточнити вимогу: обрізати пробіли чи ні)
TC-10  вік = -1        → помилка мінімуму

Зверніть увагу на TC-09: тест-дизайн часто знаходить не баги, а прогалини у вимогах. Таке питання краще поставити аналітику до того, як код написано.

Коли класів кілька одночасно

Форма розрахунку доставки: вага (0.1–30 кг) і тип доставки (кур'єр, відділення, поштомат; поштомат — до 15 кг). Тут межі залежать одна від одної:

Тип Вага Очікування
Поштомат 15 Прийнято
Поштомат 15.01 «Для поштомата максимум 15 кг»
Відділення 15.01 Прийнято
Відділення 30.01 «Максимальна вага — 30 кг»
Кур'єр 0.1 Прийнято
Кур'єр 0.09 «Мінімальна вага — 0.1 кг»

Для складних комбінацій багатьох параметрів допоможуть таблиці рішень і попарне тестування (pairwise) — але це тема окремої статті.

Як це автоматизувати

Класи й межі чудово лягають на параметризовані тести:

import pytest

@pytest.mark.parametrize("age, ok", [
    (17, False), (18, True), (19, True),
    (64, True), (65, True), (66, False),
    (-1, False), (30, True),
])
def test_age_range(age, ok):
    assert validate_age(age).is_valid is ok

@pytest.mark.parametrize("raw", ["abc", "25.5", "", None])
def test_age_format(raw):
    assert validate_age(raw).error == "format"

Типові помилки

  • Перевіряти лише одну сторону межі. 18 пройшло — а 17 ніхто не перевірив.
  • Плутати клас з прикладом. «Перевірити 20, 30 і 40» — це три тести одного класу, які нічого нового не дають.
  • Не питати про невизначене. Пробіли, ведучі нулі (018), Unicode-цифри — якщо вимога мовчить, поведінку треба зафіксувати.
Поле приймає пароль довжиною від 8 до 64 символів. Які довжини обов'язково перевірити за граничними значеннями?

7 і 8 для нижньої межі, 64 і 65 для верхньої. Корисно також перевірити 0 (порожній пароль) і щось типове посередині, наприклад 12.

Збережіть статтю собі

Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.

Увійти через Google Інші способи входу