Введение в подходы к тестированию
Тестирование программного обеспечения не является универсальным. Различные подходы к тестированию предоставляют различные перспективы на качество, ловят различные типы багов и требуют различных наборов навыков. Понимание того, когда и как использовать тестирование black box, white box и grey box, является фундаментальным для построения эффективной стратегии тестирования.
Эти три подхода различаются прежде всего в одном измерении: насколько много знаний имеет тестировщик о внутреннем устройстве тестируемой системы. Это знание формирует то, какие техники могут использоваться, какие типы дефектов могут быть найдены, и кто лучше всего позиционирован для выполнения тестирования.
В этом всеобъемлющем руководстве мы исследуем все три подхода в глубину, рассмотрим конкретные техники для каждого, поймём, когда применять какой метод, и узнаем, как их комбинировать для максимальной эффективности тестов.
Black Box тестирование: тестирование снаружи
Что такое Black Box тестирование?
Определение: Black box тестирование рассматривает программное обеспечение как “чёрный ящик”—тестировщик не имеет знаний о внутренней реализации, структуре кода или дизайне. Тестирование полностью основано на требованиях, спецификациях и ожидаемом поведении. Для подробного руководства по конкретным техникам black box, смотрите нашу статью о тестировании чёрного ящика.
Ключевые характеристики:
- Фокус на что делает система, а не как она это делает
- Основано на требованиях и спецификациях
- Нет доступа к исходному коду
- Тестирует внешнее поведение и интерфейсы
- Независимо от технологического стека
Перспектива тестировщика:
Вход → [ЧЁРНЫЙ ЯЩИК] → Выход
(Неизвестно)
Тестировщик знает:
✓ Какие входы предоставлять
✓ Какие выходы ожидать
✗ Как система обрабатывает входы
✗ Внутреннюю логику или алгоритмы
✗ Структуру кода или архитектуру
Когда использовать Black Box тестирование
Идеальные сценарии:
- User acceptance testing: Валидация с перспективы пользователя
- System testing: Тестирование полной интегрированной системы
- Regression testing: Обеспечение того, что существующая функциональность продолжает работать
- Стороннее ПО: Когда у вас нет доступа к исходному коду
- Contract testing: Проверка соответствия спецификациям
- Раннее тестирование: Когда код ещё недоступен (тестирование на основе спецификаций)
Кто выполняет:
- QA тестировщики
- Бизнес-аналитики
- Конечные пользователи
- Независимые команды тестирования
- Любой без знания кодирования
Техники Black Box тестирования
1. Разбиение на классы эквивалентности
Концепция: Разделить входные данные на классы эквивалентности, где все значения в классе должны вести себя одинаково. Протестировать одно репрезентативное значение из каждой партиции.
Почему это работает: Если одно значение из партиции работает, теоретически все значения должны работать. Если одно не проходит, все должны не проходить.
Пример: Валидация возраста (должен быть 18-65)
Входные партиции:
1. Ниже минимума (возраст < 18): НЕВАЛИДНО
Тестовое значение: 17
2. Валидный диапазон (18 ≤ возраст ≤ 65): ВАЛИДНО
Тестовое значение: 30
3. Выше максимума (возраст > 65): НЕВАЛИДНО
Тестовое значение: 66
Вместо тестирования всех возможных возрастов (1-120),
мы тестируем 3 представительных значения: 17, 30, 66
Пример: Поле кода скидки
Партиции:
1. Пустая строка: НЕВАЛИДНО
Тест: ""
2. Валидный формат (8 алфавитно-цифровых символов): ВАЛИДНО
Тест: "SAVE2024"
3. Слишком короткий (< 8 символов): НЕВАЛИДНО
Тест: "ABC"
4. Слишком длинный (> 8 символов): НЕВАЛИДНО
Тест: "VERYLONGCODE"
5. Специальные символы: НЕВАЛИДНО
Тест: "SAVE@#$%"
6. Валидный, но истёкший код: НЕВАЛИДНО
Тест: "EXPIRED1"
7. Валидный, но уже использованный: НЕВАЛИДНО
Тест: "USED1234"
Лучшие практики:
- Идентифицировать все условия входа
- Разделить на валидные и невалидные партиции
- Обеспечить, чтобы партиции не перекрывались
- Обеспечить, чтобы партиции покрывали все возможности
- Тестировать каждую партицию как минимум один раз
- Документировать обоснование партиций
2. Анализ граничных значений (BVA)
Концепция: Ошибки часто возникают на границах между партициями эквивалентности. Тестировать значения на границах, прямо внутри границ и прямо вне границ.
Почему это работает: Ошибки off-by-one, ошибки операторов сравнения (< vs ≤) и граничные случаи часто проявляются на границах.
Пример: Валидация возраста (18-65)
Тестовые значения:
- Прямо ниже минимума: 17 (должно не пройти)
- Граница минимума: 18 (должно пройти)
- Прямо выше минимума: 19 (должно пройти)
- Средний диапазон: 42 (должно пройти)
- Прямо ниже максимума: 64 (должно пройти)
- Граница максимума: 65 (должно пройти)
- Прямо выше максимума: 66 (должно не пройти)
7 тестов вместо тестирования всех возрастов 1-120
Пример: Загрузка файла (макс 5MB)
Тестовые значения:
- 0 байт (граница)
- 1 байт (прямо выше минимума)
- 2.5 MB (средний диапазон)
- 4,999,999 байт (прямо ниже максимума)
- 5,000,000 байт (ровно максимум)
- 5,000,001 байт (прямо выше максимума)
Двумерный пример BVA: Размеры прямоугольника
Ширина: 1-100 пикселей
Высота: 1-100 пикселей
Тестовые комбинации:
(1, 1) - оба минимума
(1, 100) - мин ширина, макс высота
(100, 1) - макс ширина, мин высота
(100, 100) - оба максимума
(0, 50) - невалидная ширина
(50, 0) - невалидная высота
(101, 50) - ширина превышает
(50, 101) - высота превышает
Лучшие практики:
- Тестировать минимум, максимум и прямо вне обоих
- Для диапазонов, тестировать оба конца
- Комбинировать с разбиением на классы эквивалентности
- Рассматривать многомерные границы
- Тестировать null, пустые и бланковые значения
3. Тестирование таблицы решений
Концепция: Представить сложную бизнес-логику с комбинациями условий и соответствующими действиями в табличном формате.
Когда использовать:
- Множественные условия влияют на результаты
- Сложные бизнес-правила
- Разные комбинации производят разные результаты
- Необходимо проверить все комбинации
Пример: Система одобрения кредита
Условия:
C1: Кредитный рейтинг >= 700
C2: Доход >= $50,000
C3: Соотношение долг-доход < 40%
C4: Занятость > 2 лет
Действия:
A1: Одобрить кредит
A2: Отклонить кредит
A3: Требуется ручной обзор
Таблица решений:
Правило | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
--------|---|---|---|---|---|---|---|---|
C1 | И | И | И | И | Л | Л | Л | Л |
C2 | И | И | Л | Л | И | И | Л | Л |
C3 | И | Л | И | Л | И | Л | И | Л |
C4 | И | Л | И | Л | И | Л | И | Л |
--------|---|---|---|---|---|---|---|---|
A1 | X | | | | | | | |
A2 | | | | X | | | | X |
A3 | | X | X | | X | X | X | |
Правило 1: Все условия выполнены → Одобрить
Правило 2: Хороший кредит, но высокий долг → Ручной обзор
Правило 3: Хороший кредит, низкий долг, но низкий доход → Ручной обзор
Правило 4: Только кредитный рейтинг хорош → Отклонить
...и так далее
Лучшие практики:
- Идентифицировать все условия и действия
- Перечислить все комбинации (или сократить с эквивалентностью)
- Обеспечить полноту (все случаи покрыты)
- Искать избыточные или невозможные комбинации
- Приоритизировать общие сценарии
4. Тестирование переходов состояний
Концепция: Тестировать, как система переходит между различными состояниями на основе входов и событий.
Когда использовать:
- Системы с отличными состояниями
- Поведение, зависящее от состояния
- Рабочие процессы и процессы
- Транзакционные системы
Пример: Жизненный цикл заказа
Состояния:
- Новый
- Оплачен
- Отправлен
- Доставлен
- Отменён
Переходы:
Новый → Оплачен (событие: платёж получен)
Новый → Отменён (событие: клиент отменяет)
Оплачен → Отправлен (событие: заказ отправлен)
Оплачен → Отменён (событие: платёж возвращён)
Отправлен → Доставлен (событие: доставка подтверждена)
Отправлен → Отменён (событие: потерян при транспортировке)
Невалидные переходы:
Новый → Отправлен (нельзя отправить неоплаченный заказ)
Доставлен → Оплачен (нельзя оплатить после доставки)
Отменён → Отправлен (нельзя отправить отменённый заказ)
Тест-кейсы:
1. Новый → Оплачен → Отправлен → Доставлен (счастливый путь)
2. Новый → Отменён (ранняя отмена)
3. Оплачен → Отменён (сценарий возврата)
4. Попытка Новый → Отправлен (должно не пройти)
5. Попытка Доставлен → Отменён (должно не пройти или частичный возврат)
Лучшие практики:
- Создать диаграмму переходов состояний
- Тестировать все валидные переходы
- Тестировать невалидные переходы (должны быть отклонены)
- Тестировать последовательности переходов
- Проверить, что данные состояния сохраняются корректно
5. Тестирование по случаям использования
Концепция: Тестировать сценарии, основанные на том, как пользователи на самом деле будут использовать систему. Фокусироваться на end-to-end рабочих процессах пользователя.
Структура случая использования:
Случай использования: Сделать заказ
Актор: Клиент
Предусловия:
- Пользователь авторизован
- Товары есть в наличии
- Метод оплаты настроен
Основной поток:
1. Пользователь добавляет товары в корзину
2. Пользователь просматривает корзину
3. Пользователь переходит к оформлению
4. Пользователь подтверждает адрес доставки
5. Пользователь выбирает метод оплаты
6. Пользователь просматривает заказ
7. Пользователь размещает заказ
8. Система обрабатывает платёж
9. Система подтверждает заказ
10. Пользователь получает подтверждающий email
Альтернативные потоки:
- 2a. Пользователь применяет код скидки
- 6a. Пользователь редактирует адрес доставки
- 8a. Платёж не проходит → Пользователь пробует другой метод оплаты
Потоки исключений:
- 1a. Товар отсутствует → Пользователь уведомлён
- 8a. Платёжный шлюз не работает → Пользователь видит ошибку, заказ сохранён
Постусловия:
- Заказ создан в базе данных
- Инвентарь обновлён
- Подтверждающий email отправлен
- Платёж зарегистрирован
Лучшие практики:
- Основывать на реальных пользовательских сценариях
- Включать счастливые пути и альтернативные потоки
- Тестировать сценарии исключений
- Проверять предусловия и постусловия
- Документировать ожидаемое поведение системы
6. Угадывание ошибок
Концепция: Использовать опыт тестировщика для угадывания, где вероятно возникновение ошибок.
Общие области, подверженные ошибкам:
Ввод данных:
- Пустые поля
- Специальные символы (!@#$%^&*)
- Очень длинные входы
- Попытки SQL-инъекции
- Попытки XSS
Вычисления:
- Деление на ноль
- Отрицательные числа
- Очень большие числа
- Проблемы с точностью десятичных знаков
Даты и время:
- 29 февраля (високосный год)
- Различия формата даты
- Изменения часового пояса
- Переход на летнее время
- Проблема 2038 года
Параллелизм:
- Два пользователя редактируют ту же запись
- Быстрые клики
- Множественные вкладки/окна
- Race conditions
Лимиты ресурсов:
- Загрузка макс размера файла
- Максимальные записи
- Лимиты подключения к базе данных
- Исчерпание памяти
Лучшие практики:
- Документировать известные проблемные области
- Учиться на прошлых багах
- Делиться знаниями в команде
- Комбинировать с формальными техниками
- Поддерживать базу данных дефектов для паттернов
Black Box тестирование: преимущества и недостатки
Преимущества:
✓ Не требуется знание программирования
✓ Беспристрастное тестирование (не зависит от кода)
✓ Ориентированная на пользователя перспектива
✓ Может начаться рано (до написания кода)
✓ Чёткое разделение ролей (dev vs test)
✓ Эффективно для больших систем
✓ Фокусируется на покрытии требований
Недостатки:
✗ Не может тестировать внутреннюю логику напрямую
✗ Может пропустить скрытую функциональность
✗ Сложно идентифицировать причину сбоев
✗ Не может измерить покрытие кода
✗ Потенциально избыточные тесты
✗ Может не поймать архитектурные проблемы
✗ Ограничено тем, что определяют спецификации
White Box тестирование: тестирование изнутри
Что такое White Box тестирование?
Определение: White box тестирование (также называемое glass box, clear box или структурное тестирование) исследует внутреннюю структуру, дизайн и код программного обеспечения. Тестировщик имеет полную видимость реализации. Для углубления в техники white box, смотрите нашу статью о тестировании белого ящика.
Ключевые характеристики:
- Фокус на как работает система внутренне
- Основано на структуре кода и логике
- Полный доступ к исходному коду
- Тестирует внутренние пути, условия, циклы
- Требует знания программирования
Перспектива тестировщика:
Вход → [ПРОЗРАЧНЫЙ ЯЩИК] → Выход
(Код виден)
Тестировщик знает:
✓ Исходный код
✓ Внутренние алгоритмы
✓ Структуру кода
✓ Схему базы данных
✓ Архитектуру
✓ Зависимости
Когда использовать White Box тестирование
Идеальные сценарии:
- Unit testing: Тестирование индивидуальных функций/методов
- Integration testing: Тестирование взаимодействий модулей
- Оптимизация кода: Поиск узких мест производительности
- Security testing: Идентификация уязвимостей
- Code review: Обеспечение стандартов качества
- Сложные алгоритмы: Проверка корректности логики
Кто выполняет:
- Разработчики
- SDET (Software Development Engineers in Test)
- Технический QA с навыками кодирования
- Специалисты по безопасности
- Инженеры по производительности
Техники White Box тестирования
1. Покрытие операторов
Цель: Выполнить каждый оператор в коде как минимум один раз.
Формула: Покрытие операторов = (Выполненных операторов / Всего операторов) × 100%
Пример:
function calculateDiscount(price, isPremium, quantity) {
let discount = 0; // Оператор 1
if (isPremium) { // Оператор 2
discount = 0.20; // Оператор 3
}
if (quantity > 10) { // Оператор 4
discount += 0.10; // Оператор 5
}
const finalPrice = price * (1 - discount); // Оператор 6
return finalPrice; // Оператор 7
}
Всего операторов: 7
Тест-кейс 1: calculateDiscount(100, true, 15)
Выполняет: 1, 2, 3, 4, 5, 6, 7 (все 7 операторов)
Покрытие: 100%
Также можно достичь 100% с:
Тест-кейс 2: calculateDiscount(100, false, 5)
Выполняет: 1, 2, 4, 6, 7 (пропускает 3 и 5)
Тест-кейс 3: calculateDiscount(100, true, 15)
Выполняет: 1, 2, 3, 4, 5, 6, 7
Оба тест-кейса вместе: 100% покрытие операторов
Ограничения:
- Не гарантирует, что все пути протестированы
- Не тестирует все условия
- 100% покрытие операторов ≠ код без багов
2. Покрытие ветвей (покрытие решений)
Цель: Выполнить каждую ветвь (истина и ложь) каждой точки решения.
Формула: Покрытие ветвей = (Выполненных ветвей / Всего ветвей) × 100%
Пример:
function validateAge(age) {
if (age < 0) { // Решение 1: Ветвь A (истина) / Ветвь B (ложь)
return "Невалидный возраст";
}
if (age < 18) { // Решение 2: Ветвь C (истина) / Ветвь D (ложь)
return "Несовершеннолетний";
}
return "Взрослый";
}
Всего ветвей: 4 (A, B, C, D)
Тест-кейс 1: validateAge(-5)
Путь: A → return
Покрытые ветви: A
Покрытие: 25%
Тест-кейс 2: validateAge(15)
Путь: B → C → return
Покрытые ветви: B, C
Покрытие: 50%
Тест-кейс 3: validateAge(25)
Путь: B → D → return
Покрытые ветви: B, D
Покрытие: 50%
Тест-кейсы 1, 2, 3 вместе:
Покрытые ветви: A, B, C, D
Покрытие: 100%
Покрытие ветвей включает покрытие операторов: 100% покрытие ветвей гарантирует 100% покрытие операторов, но не наоборот.
3. Покрытие условий
Цель: Тестировать каждое условие в решении независимо для истинных и ложных результатов.
Пример:
function canApprove(age, income, creditScore) {
// Решение с 3 условиями
if (age >= 18 && income >= 50000 && creditScore >= 700) {
return "Одобрено";
}
return "Отклонено";
}
Условия:
C1: age >= 18
C2: income >= 50000
C3: creditScore >= 700
Для 100% покрытия условий, необходимо:
- C1 истина и C1 ложь
- C2 истина и C2 ложь
- C3 истина и C3 ложь
Тест-кейсы:
TC1: (25, 60000, 750) → C1=И, C2=И, C3=И → Одобрено
TC2: (16, 60000, 750) → C1=Л, C2=И, C3=И → Отклонено
TC3: (25, 40000, 750) → C1=И, C2=Л, C3=И → Отклонено
TC4: (25, 60000, 650) → C1=И, C2=И, C3=Л → Отклонено
Все условия протестированы для истины и лжи: 100% покрытие условий
4. Покрытие множественных условий (MCC)
Цель: Протестировать все возможные комбинации условий.
Пример:
if (A && B) {
// сделать что-то
}
Необходимые комбинации:
A=И, B=И → истина && истина = истина
A=И, B=Л → истина && ложь = ложь
A=Л, B=И → ложь && истина = ложь
A=Л, B=Л → ложь && ложь = ложь
4 тест-кейса для 2 условий
Для 3 условий: 2³ = 8 комбинаций
Для 4 условий: 2⁴ = 16 комбинаций
Вызов: Экспоненциальный рост с числом условий делает это непрактичным для сложных решений.
Modified Condition/Decision Coverage (MC/DC): Более практичная альтернатива, которая тестирует независимое влияние каждого условия на результат. Требуется для критичного по безопасности ПО (авиация, медицина).
5. Покрытие путей
Цель: Выполнить каждый возможный путь через код.
Пример:
function processOrder(quantity, isPremium) {
let discount = 0;
if (quantity > 10) { // Точка решения 1
discount = 0.10;
}
if (isPremium) { // Точка решения 2
discount += 0.15;
}
return calculatePrice(quantity, discount);
}
Возможные пути:
Путь 1: D1=Л, D2=Л (quantity≤10, не premium)
Путь 2: D1=Л, D2=И (quantity≤10, premium)
Путь 3: D1=И, D2=Л (quantity>10, не premium)
Путь 4: D1=И, D2=И (quantity>10, premium)
Тест-кейсы для 100% покрытия путей:
TC1: (5, false) → Путь 1
TC2: (5, true) → Путь 2
TC3: (15, false) → Путь 3
TC4: (15, true) → Путь 4
С циклами:
for (let i = 0; i < n; i++) {
// тело цикла
}
Возможные пути:
- n = 0: Пропустить цикл полностью
- n = 1: Выполнить один раз
- n = 2: Выполнить дважды
- ...
- n = бесконечность: Теоретически бесконечные пути
Практический подход:
- Ноль итераций
- Одна итерация
- Множественные итерации
- Максимальные итерации (если определено)
Покрытие путей часто невозможно для реальных приложений из-за циклов и рекурсивных вызовов, создающих бесконечные пути.
6. Тестирование циклов
Фокус на циклах конкретно:
Простые циклы (один цикл):
for (let i = 0; i < n; i++) {
// обработка
}
Тест-кейсы:
1. Пропустить цикл (n = 0)
2. Одна итерация (n = 1)
3. Две итерации (n = 2)
4. Типичные итерации (n = среднее значение)
5. Максимум-1 итераций (n = max-1)
6. Максимальные итерации (n = max)
7. Превысить максимум (n = max+1)
Вложенные циклы:
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
// обработка
}
}
Тест-кейсы:
- Внутренний цикл с внешним на минимум/типичное/максимум
- Внешний цикл с внутренним на минимум/типичное/максимум
- Оба на границах
Конкатенированные циклы (независимые циклы в последовательности):
for (let i = 0; i < m; i++) {
// обработка
}
for (let j = 0; j < n; j++) {
// обработка
}
Тестировать каждый цикл независимо, используя тесты простого цикла
Инструменты покрытия кода
Популярные инструменты:
JavaScript/TypeScript:
- Istanbul/nyc
- Jest (встроенное покрытие)
- Codecov
Java:
- JaCoCo
- Cobertura
- Clover
Python:
- Coverage.py
- pytest-cov
C#/.NET:
- OpenCover
- dotCover
- Coverlet
.NET Core/C++:
- gcov/lcov
- Bullseye Coverage
Пример: Отчёт покрытия Jest:
npm test -- --coverage
File | % Stmts | % Branch | % Funcs | % Lines |
---------------|---------|----------|---------|---------|
calculator.js | 94.44 | 83.33 | 100 | 93.75 |
validator.js | 100 | 100 | 100 | 100 |
utils.js | 88.89 | 75 | 90 | 88.24 |
---------------|---------|----------|---------|---------|
All files | 93.52 | 85.19 | 96.67 | 92.86 |
White Box тестирование: преимущества и недостатки
Преимущества:
✓ Находит скрытые ошибки
✓ Оптимизирует код
✓ Измеряет полноту тестирования (метрики покрытия)
✓ Тщательно тестирует сложную логику
✓ Находит мёртвый код
✓ Позволяет автоматизацию тестов
✓ Улучшает качество кода
Недостатки:
✗ Требует навыки программирования
✗ Времязатратно
✗ Изменения кода ломают тесты
✗ Может пропустить отсутствующую функциональность
✗ Не может начаться до существования кода
✗ Потенциально предвзято (разработчик тестирует свой код)
✗ Высокое обслуживание
Grey Box тестирование: лучшее из обоих миров
Что такое Grey Box тестирование?
Определение: Grey box тестирование комбинирует подходы black box и white box. Тестировщик имеет частичное знание внутренней структуры—достаточно для разработки лучших тестов, но всё ещё тестирует с внешней перспективы. Для получения дополнительной информации о grey box тестировании, смотрите нашу статью о тестировании серого ящика.
Ключевые характеристики:
- Частичное знание внутренностей
- Фокус на интеграции между компонентами
- Тестирует с пользовательской перспективы с внутренним пониманием
- Доступ к архитектурным диаграммам, схемам баз данных, алгоритмам
- Ограниченный или только для чтения доступ к коду
Перспектива тестировщика:
Вход → [СЕРЫЙ ЯЩИК] → Выход
(Частичное знание)
Тестировщик знает:
✓ Высокоуровневую архитектуру
✓ Схему базы данных
✓ API контракты
✓ Поток данных
✗ Детали реализации
✗ Полный исходный код
Когда использовать Grey Box тестирование
Идеальные сценарии:
- Integration testing: Тестирование взаимодействий компонентов
- Penetration testing: Тестирование безопасности с архитектурным знанием
- End-to-end testing: С знанием границ системы
- Database testing: Валидация целостности данных
- API testing: С знанием backend структуры
- Performance testing: Понимание узких мест
Кто выполняет:
- Опытные QA инженеры
- SDET (Software Development Engineers in Test)
- DevOps инженеры
- Тестировщики безопасности
- Любой с техническим знанием, но внешней перспективой
Техники Grey Box тестирования
1. Матричное тестирование
Определить комбинации состояния и входов на основе внутреннего знания управления состоянием.
Пример: Корзина покупок
Знание из архитектуры:
- Корзина хранится в сессии
- Товары хранятся в базе данных
- Цены вычисляются на сервере
Тестовая матрица:
Состояние пользователя | Действие | Ожидаемый результат
-----------------------|----------------|---------------------
Гость | Добавить товар | Корзина сессии создана
Гость | Просмотреть | Корзина сессии показана
Гость | Checkout | Перенаправить на login
Авторизован | Добавить товар | Корзина БД обновлена
Авторизован | Просмотреть | Корзина БД показана
Авторизован | Checkout | Перейти к оплате
Истёкший | Добавить товар | Сессия обновлена
Истёкший | Просмотреть | Пере-аутентификация
2. Тестирование паттернов
Использовать знание общих паттернов проектирования для фокусировки тестирования.
Пример: Зная, что система использует паттерн Repository
Области фокуса тестирования:
- Согласованность CRUD операций
- Обработка транзакций
- Обработка исключений в repository
- Connection pooling
- Поведение кэширования
Вместо слепого тестирования всех операций,
фокусироваться на проблемах, специфичных для паттерна.
3. Тестирование ортогонального массива
Разработать эффективные комбинации тестов используя знание взаимодействий параметров.
Пример: Веб-приложение с множественными переменными
Переменные (из знания архитектуры):
- Браузер: Chrome, Firefox, Safari
- ОС: Windows, Mac, Linux
- База данных: MySQL, PostgreSQL
- Кэш: On, Off
Полная комбинация: 3 × 3 × 2 × 2 = 36 тестов
Используя ортогональный массив (L9):
Тест | Браузер | ОС | БД | Кэш
-----|---------|---------|-------|-------
1 | Chrome | Windows | MySQL | On
2 | Chrome | Mac | Postgres | Off
3 | Chrome | Linux | MySQL | Off
4 | Firefox | Windows | Postgres | On
5 | Firefox | Mac | MySQL | Off
6 | Firefox | Linux | Postgres | On
7 | Safari | Windows | MySQL | Off
8 | Safari | Mac | Postgres | On
9 | Safari | Linux | MySQL | On
9 тестов вместо 36, с хорошим покрытием взаимодействий
Grey Box тестирование: преимущества и недостатки
Преимущества:
✓ Лучший дизайн тестов, чем чистый black box
✓ Более эффективно, чем чистый white box
✓ Находит проблемы интеграции
✓ Реалистичные сценарии тестирования
✓ Сбалансированный подход
✓ Хорош для тестирования безопасности
✓ Идентифицирует архитектурные проблемы
Недостатки:
✗ Требует технического знания
✗ Более сложный дизайн тестов
✗ Может всё ещё пропускать внутренние баги
✗ Требует доступа к архитектурным документам
✗ Может быть непоследовательным (зависит от того, сколько известно)
Выбор правильного подхода
Рамочная структура решения
Использовать Black Box когда:
✓ Тестирование с перспективы пользователя
✓ Тестировщики не имеют навыков кодирования
✓ Тестирование стороннего ПО
✓ Код ещё недоступен
✓ Тестирование на основе требований
✓ Acceptance testing
✓ Высокоуровневое system testing
Использовать White Box когда:
✓ Unit testing функций/методов
✓ Поиск уязвимостей безопасности
✓ Оптимизация производительности
✓ Тестирование сложных алгоритмов
✓ Необходимость метрик покрытия кода
✓ Developer testing
✓ Поиск мёртвого кода
Использовать Grey Box когда:
✓ Integration testing
✓ API testing
✓ Database testing
✓ Security/penetration testing
✓ End-to-end testing с техническим пониманием
✓ Тестирование распределённых систем
✓ Microservices testing
Комбинирование подходов: пирамида
▲
╱ ╲
╱ ╲ Ручное исследовательское (Grey/Black)
╱ ╲
╱───────╲
╱ ╲
╱ E2E тесты ╲ (Grey/Black Box)
╱ (UI/API) ╲
╱───────────────╲
╱ ╲
╱ Интеграционные ╲ (Grey Box)
╱ тесты ╲
╱───────────────────────╲
╱ ╲
╱ Юнит-тесты ╲ (White Box)
╱ ╲
╱───────────────────────────────╲
База: Много быстрых white box юнит-тестов
Середина: Grey box интеграционные тесты
Верх: Меньше black/grey box E2E тестов
Вершина: Ручное исследовательское тестирование
Пример из реального мира: Checkout E-commerce
Black box тестирование:
Тестовые сценарии:
- Поток checkout гостя
- Checkout зарегистрированного пользователя
- Применить код купона
- Изменить адрес доставки
- Невалидная платёжная карта
- Email подтверждения заказа
Фокус: Рабочие процессы пользователя
Перспектива: Внешняя
Техники: Тестирование по случаям использования, анализ граничных значений
White box тестирование:
Тестовые сценарии:
- Алгоритм расчёта цены
- Логика расчёта налогов
- Порядок применения скидки
- Обработка ошибок обработки платежа
- Откат транзакции базы данных
- Время вычета инвентаря
Фокус: Внутренняя логика
Перспектива: Уровень кода
Техники: Покрытие операторов, покрытие ветвей, тестирование путей
Grey box тестирование:
Тестовые сценарии:
- Интеграция платёжного шлюза
- Переходы состояния заказа в базе данных
- Инвалидация кэша при изменении цен
- Очередь сообщений для обработки заказа
- Нарушения ограничений базы данных
- Потоки аутентификации API
Фокус: Взаимодействия компонентов
Перспектива: Архитектурная
Техники: Integration testing, API testing, database testing
Лучшие практики для всех подходов
1. Использовать правильный инструмент для работы
✓ Не заставлять один подход для всего
✓ Комбинировать подходы стратегически
✓ Соответствовать технике с тем, что тестируете
✓ Учитывать навыки тестировщика и ограничения проекта
2. Автоматизировать соответствующе
White box юнит-тесты: Сильно автоматизированы
Grey box интеграционные тесты: В основном автоматизированы
Black box E2E тесты: Селективно автоматизированы
Исследовательское black/grey box: Ручное
3. Измерять то, что важно
Black box метрики:
- Покрытие требований
- Покрытие пользовательских сценариев
- Частота обнаружения дефектов
White box метрики:
- Покрытие кода (операторов, ветвей)
- Циклическая сложность
- Code churn
Grey box метрики:
- Покрытие точек интеграции
- Покрытие API endpoint
- Покрытие потока данных
4. Документировать ваше тестирование
Black box:
- Тест-кейсы связаны с требованиями
- Ожидаемые vs фактические результаты
- Пользовательские сценарии
White box:
- Отчёты покрытия
- Протестированные пути кода
- Непротестированные области и почему
Grey box:
- Сценарии интеграционных тестов
- Диаграммы взаимодействия компонентов
- Карты потока данных
5. Непрерывное улучшение
✓ Пересматривать эффективность тестов
✓ Анализировать упущенные дефекты
✓ Улучшать техники
✓ Делиться знаниями в команде
✓ Обновлять стратегию тестирования по мере эволюции системы
Общие ошибки, которых следует избегать
Ошибки black box:
✗ Чрезмерная зависимость без рассмотрения внутренностей
✗ Избыточные тесты из-за отсутствия знания кода
✗ Пропуск критических внутренних сценариев
✗ Слабое граничное тестирование
✗ Игнорирование условий ошибок
Ошибки white box:
✗ Погоня за 100% покрытием без качества
✗ Хрупкие тесты, которые ломаются при рефакторинге
✗ Тестирование реализации вместо поведения
✗ Предвзятость разработчика (тестирование для прохождения)
✗ Пренебрежение перспективой пользователя
Ошибки grey box:
✗ Непоследовательное знание среди тестировщиков
✗ Чрезмерное усложнение простых тестовых сценариев
✗ Доступ к коду соблазняет white box подход
✗ Отсутствие чётких границ
✗ Предположение, что архитектурное знание актуально
Заключение
Black box, white box и grey box тестирование—это не конкурирующие подходы—это взаимодополняющие перспективы, которые, при использовании вместе, создают всеобъемлющую стратегию тестирования.
Помните:
- Black box обеспечивает, что система делает то, что нужно пользователям
- White box обеспечивает, что система делает это правильно внутренне
- Grey box обеспечивает, что компоненты работают вместе должным образом
Самые эффективные стратегии тестирования комбинируют все три подхода, применяя каждый там, где он предоставляет наибольшую ценность. Начните с прочного фундамента white box юнит-тестов, постройте grey box интеграционные тесты, которые проверяют взаимодействия компонентов, добавьте black box системные тесты, которые валидируют пользовательские сценарии, и увенчайте ручным исследовательским тестированием, которое использует креативность и интуицию.
Понимая, когда и как использовать каждый подход, вы построите программное обеспечение, которое не только функционально корректно, но и робастно, производительно, безопасно и приятно в использовании.
Дополнительное чтение
- “Software Testing Techniques” Бориса Бейзера
- “The Art of Software Testing” Гленфорда Майерса
- “How Google Tests Software” Джеймса Уиттакера
- Программа ISTQB разделы о техниках тестирования
- Стандарт IEEE 829 для документации тестирования ПО