Тест-дизайн: класи еквівалентності та граничні значення
Дві базові техніки, які допомагають написати мало тестів, але знайти більшість помилок у валідації та розрахунках. З прикладами, таблицями і типовими пастками.
Протестувати «все» неможливо: навіть поле для віку приймає мільярди різних рядків. Тест-дизайн відповідає на питання які саме перевірки дадуть максимум користі за мінімум зусиль. Дві техніки, з яких варто почати, — класи еквівалентності та аналіз граничних значень.
Класи еквівалентності
Ідея: розбити всі можливі вхідні дані на групи, всередині яких система поводиться однаково. Якщо одне значення з групи працює правильно, ймовірно, працюватимуть і інші. Тож з кожного класу достатньо одного представника.
Приклад. Поле «Вік» у формі реєстрації страхового полісу. Вимога: приймаються цілі числа від 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 Інші способи входу