Что такое анализ граничных значений?
Анализ граничных значений (Boundary Value Analysis, BVA) — это техника тест-дизайна чёрного ящика, которая фокусируется на тестировании значений на краях классов эквивалентности. Если эквивалентное разбиение говорит, какие группы тестировать, то BVA говорит, где внутри этих групп дефекты прячутся с наибольшей вероятностью.
Почему границы важны
Исследования последовательно показывают, что непропорционально большое количество дефектов ПО возникает на граничных значениях. Причина проста: разработчики пишут условия вроде if (age >= 18) или if (quantity <= 100), и ошибки на единицу (> вместо >=, < вместо <=) — одни из самых распространённых ошибок в коде.
# Намерение: принимать возраст от 18 и старше
if age > 18: # Баг! Отклоняет 18-летних
allow_access()
# Правильно:
if age >= 18:
allow_access()
Разница в один символ (> vs >=) вызывает дефект, который проявляется только на граничном значении 18. Тестирование с age=25 никогда бы его не обнаружило.
BVA с двумя значениями (стандартный)
Наиболее распространённый подход проверяет два значения на границу: саму границу и значение сразу за ней.
Для валидного диапазона от 1 до 100:
| Граница | Тестовые значения | Ожидаемый результат |
|---|---|---|
| Нижняя | 0 (сразу ниже) | Невалидно |
| Нижняя | 1 (граница) | Валидно |
| Верхняя | 100 (граница) | Валидно |
| Верхняя | 101 (сразу выше) | Невалидно |
4 тест-кейса покрывают обе границы.
BVA с тремя значениями (строгий)
Для систем с более высоким риском проверяют три значения на границу: сразу ниже, границу и сразу выше.
Для того же диапазона от 1 до 100:
| Граница | Тестовые значения | Ожидаемый результат |
|---|---|---|
| Нижняя | 0 | Невалидно |
| Нижняя | 1 | Валидно |
| Нижняя | 2 | Валидно |
| Верхняя | 99 | Валидно |
| Верхняя | 100 | Валидно |
| Верхняя | 101 | Невалидно |
6 тест-кейсов для более тщательного покрытия.
BVA для различных типов данных
Целые числа: Просто — граница ± 1.
- Диапазон 1-10: проверяем 0, 1, 10, 11
Числа с плавающей точкой: Используйте наименьший значимый инкремент.
- Диапазон 0.0-1.0: проверяем -0.01, 0.0, 1.0, 1.01
Строки (длина): Проверяем на границах длины.
- Username 3-20 символов: проверяем 2 символа, 3 символа, 20 символов, 21 символ
Даты: Проверяем на границах дат.
- Валидные даты 1 янв - 31 дек: проверяем 31 дек прошлого года, 1 янв, 31 дек, 1 янв следующего года
Коллекции (размер): Проверяем на границах количества.
- Товары в корзине 1-50: проверяем 0, 1, 50, 51
Комбинирование EP и BVA
Эти две техники — естественные партнёры. EP определяет разделы; BVA фокусируется на их границах.
Пример: Стоимость доставки по весу
| Вес (кг) | Доставка |
|---|---|
| 0.1 – 1.0 | $5 |
| 1.01 – 5.0 | $10 |
| 5.01 – 20.0 | $20 |
| > 20.0 | $35 |
Представители EP (середина каждого класса): 0.5, 3.0, 12.0, 25.0
Значения BVA (на границах): 0.09, 0.1, 1.0, 1.01, 5.0, 5.01, 20.0, 20.01
В комбинации получаем полное покрытие всего из 12 тест-кейсов.
Продвинутые техники BVA
Многомерные границы
Когда система имеет несколько взаимодействующих параметров, границы существуют в нескольких измерениях. Рассмотрим систему ценообразования:
- Количество: 1-1000
- Цена за единицу: $0.01-$9999.99
Интересные границы — не только отдельные параметры, но и комбинации:
| Тест | Количество | Цена за ед. | Итого | Почему |
|---|---|---|---|---|
| 1 | 1 | $0.01 | $0.01 | Минимально возможный итог |
| 2 | 1000 | $9999.99 | $9,999,990 | Максимально возможный итог |
| 3 | 1 | $9999.99 | $9999.99 | Макс цена, мин количество |
| 4 | 1000 | $0.01 | $10.00 | Мин цена, макс количество |
Внутренние границы
Не все границы находятся на краях валидных/невалидных диапазонов. Внутренние границы разделяют разные пути обработки внутри валидного диапазона:
def calculate_tax(income):
if income <= 10000:
return income * 0.10
elif income <= 50000:
return 1000 + (income - 10000) * 0.20
else:
return 9000 + (income - 50000) * 0.30
Внутренние границы на $10 000 и $50 000 так же важны, как и границы общего валидного диапазона. Проверяем: $9 999, $10 000, $10 001, $49 999, $50 000, $50 001.
Неявные границы
Некоторые границы не указаны в спецификации, но существуют в реализации:
- Переполнение целого числа: 2 147 483 647 (макс 32-битного int со знаком)
- Границы массивов: Коллекции с индексацией от 0 vs от 1
- Пустое/null: Граница между «что-то» и «ничего»
- Границы точности: Проблемы сравнения чисел с плавающей точкой при очень малых разницах
BVA для систем с временными параметрами
Временные границы особенно коварны:
| Сценарий | Граничные значения |
|---|---|
| Таймаут сессии (30 мин) | 29:59, 30:00, 30:01 |
| Ежедневный batch job (полночь) | 23:59:59, 00:00:00, 00:00:01 |
| Високосный год (28/29 фев) | 28 фев, 29 фев, 1 мар |
| Переход на летнее/зимнее время | 01:59, 02:00, 03:00 |
Упражнение: BVA для политики паролей
Сценарий: Система применяет следующую политику паролей:
- Длина: 8-64 символа
- Минимум 1 заглавная буква
- Минимум 1 цифра
- Минимум 1 спецсимвол (!@#$%^&*)
Задание: Определите все граничные значения для требования длины и спроектируйте тест-кейсы с BVA трёх значений. Затем определите, как требования к типам символов создают дополнительные границы.
Подсказка
Для длины границы — 8 (минимум) и 64 (максимум). BVA трёх значений означает проверку 7, 8, 9 на нижней границе и 63, 64, 65 на верхней.
Для типов символов граница находится между 0 и 1 вхождением каждого обязательного типа. Подумайте о пароле с ровно 0 заглавных букв и ровно 1.
Решение
BVA длины (три значения):
| # | Длина | Тестовое значение | Ожидаемый результат |
|---|---|---|---|
| 1 | 7 символов | Aa1!xyz | Отклонить (слишком короткий) |
| 2 | 8 символов | Aa1!xyzw | Принять (нижняя граница) |
| 3 | 9 символов | Aa1!xyzwq | Принять (чуть выше нижней) |
| 4 | 63 символа | Aa1! + 59 x | Принять (чуть ниже верхней) |
| 5 | 64 символа | Aa1! + 60 x | Принять (верхняя граница) |
| 6 | 65 символов | Aa1! + 61 x | Отклонить (слишком длинный) |
Границы типов символов:
| # | Тест | Ожидаемый результат |
|---|---|---|
| 7 | 0 заглавных: aa1!xyzw | Отклонить |
| 8 | 1 заглавная: Aa1!xyzw | Принять |
| 9 | 0 цифр: Aa!!xyzw | Отклонить |
| 10 | 1 цифра: Aa1!xyzw | Принять |
| 11 | 0 спецсимволов: Aa1bxyzw | Отклонить |
| 12 | 1 спецсимвол: Aa1!xyzw | Принять |
Итого: 12 тест-кейсов, покрывающих все границы длины и требований к типам символов.
Советы профессионала
- Всегда сочетайте BVA с EP. BVA без EP упускает общую картину; EP без BVA пропускает самые насыщенные дефектами области.
- Не забывайте ноль и пустое. Ноль элементов, строки нулевой длины и пустые коллекции — границы, выявляющие NullPointerException, деление на ноль и другие частые дефекты.
- Учитывайте минимальный инкремент. Для целых чисел это 1, для валюты может быть 0.01, для timestamp — 1 секунда или 1 миллисекунда.
- Проверяйте обе стороны каждой границы. У границы две стороны — валидная и невалидная. Пропуск любой оставляет дефекты непокрытыми.
- В API проверяйте граничные значения в параметрах запроса, заголовках и обработке ответов. Границы в пагинации API (page=0, page=1, page=maxInt) часто содержат баги.