Перейти к основному содержимому

6.08. Классификация тестирования

Тестировщику Разработчику Аналитику

Классификация тестирования

Тестирование можно классифицировать по различным признакам: по уровню доступа к внутренней структуре системы, по целям, по стадиям жизненного цикла разработки и по степени автоматизации. Наиболее фундаментальной является классификация по уровню доступа к коду, которая определяет парадигму подхода к проектированию тестов.

White-box, Black-box и Gray-box тестирование

Black-box тестирование («тестирование чёрного ящика») рассматривает систему как неделимую сущность, поведение которой определяется только входными данными и ожидаемыми выходными результатами. Внутренняя структура, алгоритмы и реализация остаются скрытыми от тестировщика. Такой подход характерен для системного и приёмочного тестирования, а также для большинства видов функционального тестирования. Основное преимущество — независимость от реализации: если логика изменится, но поведение останется прежним, тесты не потребуют переработки.

White-box тестирование («тестирование белого ящика») основано на знании внутренней архитектуры и исходного кода. Тестировщик проектирует сценарии, направленные на проверку конкретных путей выполнения, ветвлений, циклов, исключений и покрытия строк кода. Этот тип тестирования применяется преимущественно на уровне модульного (unit) и интеграционного тестирования и часто реализуется самими разработчиками. Метрики, такие как statement coverage, branch coverage или path coverage, используются для оценки полноты white-box тестов.

Gray-box тестирование представляет собой гибрид: тестировщик обладает частичной информацией о внутреннем устройстве системы (например, знает архитектурную схему или интерфейсы модулей), но не имеет доступа к полному коду. Такой подход часто используется при интеграционном тестировании или при тестировании API, где знание структуры данных и протоколов взаимодействия повышает эффективность проектирования тест-кейсов, но детали реализации остаются вне зоны ответственности тестировщика.


Уровни тестирования в жизненном цикле разработки

Тестирование проводится на различных уровнях абстракции, каждый из которых соответствует определённой стадии сборки и интеграции программного продукта.

Модульное (unit) тестирование

Модульное тестирование фокусируется на проверке отдельных компонентов — функций, методов, классов или модулей — в изоляции от остальной системы. Ключевые требования к unit-тестам определяются принципом FIRST:

  • Fast — выполняются быстро (обычно в миллисекундах);
  • Independent — не зависят друг от друга и могут запускаться в любом порядке;
  • Repeatable — дают одинаковые результаты при каждом запуске в одинаковых условиях;
  • Self-Validating — автоматически определяют успех или провал без ручного анализа;
  • Timely — пишутся своевременно, желательно до или параллельно с реализацией кода (в духе TDD).

Unit-тесты, как правило, реализуются разработчиками с использованием фреймворков, таких как JUnit (Java), pytest или unittest (Python), Jest, Mocha, Jasmine (JavaScript/TypeScript). Они обеспечивают базовую защиту от регрессий и служат документацией поведения кода.

Интеграционное тестирование

Интеграционное тестирование проверяет взаимодействие между модулями, подсистемами или внешними сервисами. Здесь уже недостаточно изолировать компоненты — необходимо убедиться, что они корректно обмениваются данными, соблюдают контракты интерфейсов и корректно обрабатывают ошибки взаимодействия (например, таймауты или отказы сторонних API). Для таких тестов часто используются моки (mocks) и заглушки (stubs), но в стратегии integration-first предпочтение отдаётся реальным зависимостям.

Системное тестирование

Системное тестирование проводится над полностью собранной системой в среде, максимально приближенной к боевой. Оно охватывает как функциональные, так и нефункциональные аспекты и служит финальной верификацией перед передачей продукта на приёмку. На этом этапе применяются техники black-box тестирования, а тест-кейсы проектируются на основе спецификаций и пользовательских сценариев.

Приёмочное тестирование (UAT)

Приёмочное тестирование выполняется конечным пользователем или представителем заказчика и направлено на подтверждение того, что система решает реальную бизнес-задачу. В отличие от системного тестирования, UAT не проверяет соответствие техническим требованиям, а оценивает пригодность продукта для использования в реальных условиях. Часто такие тесты проводятся в форме сценариев, описанных в терминах предметной области.

Вспомогательные виды тестирования на уровне жизненного цикла

  • Дымовое тестирование (Smoke Testing) — минимальный набор проверок, подтверждающий, что критически важные функции системы работоспособны после сборки. Используется как «ворота» перед запуском более глубокого тестирования.
  • Тестирование критического пути (Critical Path Testing) — фокус на сценариях, без которых система теряет основную ценность (например, оплата в интернет-магазине, авторизация в корпоративной системе).
  • Регрессионное тестирование — повторное выполнение ранее прошедших тестов после внесения изменений, с целью выявления непреднамеренных побочных эффектов.

Жизненный цикл дефекта

Для эффективного управления качеством важно различать три связанных, но не тождественных понятия:

  • Ошибка (Mistake) — это человеческое упущение, допущенное на этапе анализа, проектирования или кодирования. Ошибка является причиной.
  • Дефект (Defect/Bug) — следствие ошибки: некорректный фрагмент требования, архитектуры или кода, который ещё не проявил себя в работе системы. Дефект существует в артефактах проекта.
  • Сбой (Failure) — наблюдаемое отклонение от ожидаемого поведения во время выполнения программы. Сбой возникает тогда, когда дефект активируется при определённых условиях выполнения.

Таким образом, не каждый дефект приводит к сбою (например, если код никогда не выполняется), и не каждый сбой вызван программным дефектом (возможны аппаратные сбои, ошибки конфигурации и т.п.). Однако в контексте тестирования основной фокус — на выявлении дефектов до того, как они спровоцируют сбои в эксплуатации.

Дефект проходит определённый жизненный цикл:

  1. Обнаружение — тестировщик фиксирует несоответствие.
  2. Регистрация — создаётся отчёт (bug report) с описанием, шагами воспроизведения, окружением и приоритетом.
  3. Подтверждение/Триаж — команда решает, является ли это реальным дефектом и насколько он критичен.
  4. Назначение — дефект передаётся ответственному разработчику.
  5. Исправление — внесение изменений в код или документацию.
  6. Верификация — повторное тестирование для подтверждения устранения проблемы.
  7. Закрытие — дефект помечается как resolved/verified.

На всех этапах важна точность формулировок, воспроизводимость и прозрачность — особенно в распределённых командах.


Влияние модели жизненного цикла разработки (SDLC) на тестирование

Выбор модели разработки определяет, когда, как и в каком объёме проводится тестирование.

  • Водопадная модель предполагает последовательное выполнение фаз: требования → проектирование → реализация → тестирование → эксплуатация. В такой модели тестирование начинается только после завершения кодирования, что увеличивает стоимость исправления дефектов и снижает гибкость. Однако она подходит для проектов с чётко фиксированными и стабильными требованиями (например, в регулируемых отраслях).

  • V-Model — модификация водопада, где каждой фазе разработки сопоставляется соответствующая фаза тестирования (например, анализ требований ↔ приёмочное тестирование, проектирование системы ↔ системное тестирование). Это делает тестирование более структурированным и позволяет начать проектирование тестов уже на этапе анализа.

  • Итеративные и спиральные модели вводят цикличность: каждая итерация включает в себя свои подциклы анализа, проектирования, реализации и тестирования. Это позволяет выявлять дефекты раньше и корректировать курс проекта на основе обратной связи.

  • Agile (Scrum, Kanban) — наиболее распространённый современный подход, в котором тестирование интегрировано в каждый спринт. Тестировщики работают в тесной связке с разработчиками и аналитиками с самого начала итерации. Практики, такие как непрерывная интеграция (CI), тестирование на ранних этапах (shift-left testing) и автоматизация регрессионных проверок, становятся нормой. Здесь особенно важна культура совместной ответственности за качество («Quality is everyone’s job»).

Во всех современных подходах подчёркивается принцип раннего тестирования: чем раньше начат анализ требований и проектирование тестов, тем ниже стоимость исправления дефектов и выше общее качество продукта. Согласно исследованиям, исправление дефекта на этапе эксплуатации может быть в 10–100 раз дороже, чем на этапе проектирования.