Ответ
Анализ граничных значений (Boundary Value Analysis, BVA) — это техника тест-дизайна для проверки поведения системы на границах допустимых диапазонов. Вот системный подход:
1. Основная теория: Для диапазона [min, max] тестируем:
- min-1 (нижняя недопустимая граница)
- min (нижняя допустимая граница)
- min+1 (внутри диапазона, близко к границе)
- max-1 (внутри диапазона, близко к границе)
- max (верхняя допустимая граница)
- max+1 (верхняя недопустимая граница)
2. Практические примеры:
Пример 1: Поле возраста (18-65 лет)
import pytest
@pytest.mark.parametrize("age,expected_valid", [
(17, False), # Ниже минимума
(18, True), # Минимальное допустимое
(19, True), # Чуть выше минимума
(30, True), # Типичное значение
(64, True), # Чуть ниже максимума
(65, True), # Максимальное допустимое
(66, False), # Выше максимума
(0, False), # Экстремально низкое
(150, False), # Экстремально высокое
])
def test_age_validation(age, expected_valid):
result = validate_age(age)
assert result.is_valid == expected_valid
if not expected_valid:
# Проверяем сообщение об ошибке
assert "age must be between 18 and 65" in result.error_message
Пример 2: Поле длины строки (1-255 символов)
describe('String length validation', () => {
const testCases = [
{ input: '', expected: false }, // 0 символов
{ input: 'a', expected: true }, // 1 символ (min)
{ input: 'ab', expected: true }, // 2 символа (min+1)
{ input: 'a'.repeat(254), expected: true }, // 254 символа (max-1)
{ input: 'a'.repeat(255), expected: true }, // 255 символов (max)
{ input: 'a'.repeat(256), expected: false } // 256 символов (max+1)
];
testCases.forEach(({ input, expected }) => {
it(`validates "${input.length} chars" correctly`, () => {
expect(isValidString(input)).toBe(expected);
});
});
});
3. Особые случаи и расширения:
Эквивалентные классы с границами:
# Для поля "Количество товаров в корзине" (0-99)
test_cases = [
# Отрицательные значения
(-1, "error"),
(-100, "error"),
# Граница 0
(0, "success"), # Пустая корзина допустима
# Нормальные значения
(1, "success"),
(50, "success"),
# Верхняя граница
(99, "success"),
(100, "error"),
# Большие числа
(999, "error"),
]
4. Граничные значения для дат и времени:
from datetime import datetime, timedelta
# Тестирование скидки, действующей с 2024-01-01 по 2024-12-31
test_dates = [
(datetime(2023, 12, 31), False), # За день до начала
(datetime(2024, 1, 1), True), # Первый день акции
(datetime(2024, 1, 2), True), # Второй день
(datetime(2024, 12, 30), True), # Предпоследний день
(datetime(2024, 12, 31), True), # Последний день
(datetime(2025, 1, 1), False), # День после окончания
]
5. Интеграция с другими техниками:
- Попарное тестирование (Pairwise) для комбинаций нескольких полей с граничными значениями
- Таблицы решений для сложных бизнес-правил с граничными условиями
- Диаграммы переходов состояний для проверки граничных переходов
6. Автоматизация проверки граничных значений:
class BoundaryTester:
def __init__(self, min_val, max_val):
self.min = min_val
self.max = max_val
def generate_test_values(self):
"""Генерирует стандартный набор граничных значений"""
return [
self.min - 1,
self.min,
self.min + 1,
(self.min + self.max) // 2, # Среднее значение
self.max - 1,
self.max,
self.max + 1
]
def test_boundaries(self, validation_func):
"""Запускает тесты для всех граничных значений"""
for value in self.generate_test_values():
is_valid = self.min <= value <= self.max
result = validation_func(value)
assert result.is_valid == is_valid,
f"Failed for value {value}. Expected valid={is_valid}"
if not is_valid:
assert hasattr(result, 'error'),
f"Error message missing for invalid value {value}"
Ключевые принципы:
- 7 тест-кейсов на один диапазон (min-1, min, min+1, nominal, max-1, max, max+1)
- Обработка ошибок – система должна давать понятные сообщения
- Инклюзивность/эксклюзивность – четкое понимание, включены ли границы в диапазон
- Смежные диапазоны – особое внимание стыкам между диапазонами