Тестирование состояний и переходов: 5 практических примеров
Пройдите тест, узнайте какой профессии подходите
Для кого эта статья:
- специалисты в области тестирования программного обеспечения (QA-инженеры)
- разработчики программного обеспечения, интересующиеся улучшением качества кода
- студенты и начинающие специалисты, желающие получить знания о тестировании состояний и переходов
Погружаясь в мир тестирования ПО, мы часто сталкиваемся с приложениями, которые могут находиться в различных состояниях и переходить между ними по определённым правилам. Неверная обработка этих переходов — источник до 40% критических дефектов в продакшене. Освоение техник тестирования состояний и переходов даёт мощный инструмент для выявления скрытых багов, которые обычно ускользают от внимания при функциональном тестировании. В этой статье я представлю 5 практических примеров, как эффективно использовать эти методики и значительно повысить качество тестирования ваших проектов. 🧠💡
Хотите мастерски выявлять дефекты на стыке состояний системы? Курс «Инженер по тестированию» с нуля от Skypro предлагает детальное погружение в методологию тестирования состояний и переходов с практическими заданиями на реальных проектах. Вы научитесь строить эффективные диаграммы состояний, создавать исчерпывающие тест-кейсы и применять профессиональные инструменты для обнаружения сложнейших багов на стыке состояний системы.
Основы тестирования состояний и переходов
Тестирование состояний и переходов — это техника, которая фокусируется на проверке поведения системы при изменении её состояния. Данная методика базируется на представлении системы как конечного автомата (state machine), где:
- Состояния — это стабильные конфигурации системы
- Переходы — это события, вызывающие изменение состояния
- Условия переходов — ограничения, определяющие возможность перехода
- Действия — операции, выполняемые при переходе между состояниями
Тестирование состояний позволяет проверить следующие аспекты:
Аспект | Что проверяем | Типичные дефекты |
---|---|---|
Корректность состояний | Правильность внутреннего состояния системы | Несоответствие бизнес-правилам |
Валидность переходов | Допустимость переходов между состояниями | Недопустимые переходы, "мёртвые" состояния |
Обработка событий | Реакцию на внешние воздействия | Игнорирование событий, избыточная реакция |
Граничные условия | Поведение на границах состояний | Race conditions, таймауты |
Для эффективного тестирования состояний и переходов необходимо построить диаграмму состояний, которая визуализирует возможные состояния системы и переходы между ними. При этом важно:
- Определить все возможные состояния системы
- Идентифицировать все допустимые переходы
- Определить действия, которые должны выполняться при переходах
- Выявить условия, при которых происходят переходы
- Определить ожидаемое поведение при попытке недопустимого перехода
Тестирование состояний особенно эффективно для систем с чётко выраженной конечной логикой: платёжных шлюзов, процессов аутентификации, бизнес-процессов обработки заказов и других систем с множественными состояниями. 🔄

Пример 1: Тестирование авторизации пользователей
Алексей Петров, Lead QA Engineer
Когда наша команда тестировала новую систему авторизации для финтех-приложения, мы столкнулись с неочевидным багом. Система иногда блокировала легитимных пользователей после успешного входа с правильными учётными данными. Обычные функциональные тесты не выявляли проблему.
Мы решили применить тестирование состояний и смоделировали диаграмму с 6 состояниями: "Неавторизован", "Ввод учётных данных", "Проверка данных", "Двухфакторная аутентификация", "Авторизован", "Заблокирован". Тщательно проверяя переходы между состояниями, мы обнаружили race condition: если пользователь слишком быстро пытался получить доступ к защищённым данным после авторизации, система интерпретировала это как атаку и блокировала аккаунт.
Без применения тестирования состояний и переходов этот баг мог бы "дожить" до продакшена и вызвать массовые проблемы у пользователей.
Система авторизации — классический пример системы с конечным числом состояний. Рассмотрим, как применить тестирование состояний к этому кейсу:
Определение возможных состояний:
- Неавторизован
- Процесс ввода учётных данных
- Проверка учётных данных
- Двухфакторная аутентификация (2FA)
- Авторизован
- Временно заблокирован
- Постоянно заблокирован
Идентификация переходов и триггеров:
Состояние 1 | Событие | Состояние 2 | Ожидаемый результат |
---|---|---|---|
Неавторизован | Открытие формы логина | Процесс ввода данных | Отображается форма авторизации |
Процесс ввода данных | Отправка формы | Проверка учётных данных | Индикатор загрузки, блокировка формы |
Проверка учётных данных | Верные данные (2FA включен) | Двухфакторная аутентификация | Запрос 2FA кода |
Проверка учётных данных | Верные данные (2FA выключен) | Авторизован | Перенаправление на защищённую страницу |
Проверка учётных данных | Неверные данные (попытка 3+) | Временно заблокирован | Сообщение о блокировке на 30 минут |
- Составление тест-кейсов для проверки переходов:
- TC1: Неавторизованный пользователь → Успешная авторизация (без 2FA)
- TC2: Неавторизованный → Неудачная попытка (1) → Неудачная попытка (2) → Неудачная попытка (3) → Временная блокировка
- TC3: Неавторизованный → Успешная авторизация → Тайм-аут сессии → Неавторизован
- TC4: Временная блокировка → Ожидание 30+ минут → Успешная авторизация
- TC5: Авторизован → Нажатие "Выход" → Неавторизован
- Особое внимание к критическим аспектам:
- Состояние сессии при открытии нескольких вкладок
- Запоминание состояния "Временно заблокирован" даже при закрытии браузера
- Корректность обработки "вынужденного" перехода (например, прямой доступ к защищённому URL)
- Сохранение состояния при сбоях соединения во время переходов
Такой подход позволяет выявить множество сложных дефектов, включая проблемы с обработкой таймаутов, неправильные переходы при нестандартных сценариях и ошибки восстановления состояния после сетевых сбоев. 🔐
Пример 2: Проверка систем с конечным автоматом
Конечные автоматы (Finite State Machines, FSM) встречаются во многих программных системах — от микроконтроллеров до веб-интерфейсов. Рассмотрим, как тестировать такие системы на примере процесса оформления заказа в интернет-магазине.
Процесс оформления заказа типично включает следующие состояния:
- Корзина (начальное состояние)
- Ввод данных доставки
- Выбор способа оплаты
- Подтверждение заказа
- Оплата
- Заказ оформлен
- Ошибка оформления
Для эффективного тестирования конечного автомата используем два основных подхода:
- Метод "0-Switch" (тест состояний) — проверка каждого состояния в изоляции
- Метод "N-Switch" (тест переходов) — проверка последовательности переходов
Для метода "0-Switch" составим таблицу проверок для каждого состояния:
Состояние | Проверяемые аспекты | Ожидаемое поведение |
---|---|---|
Корзина | Содержимое, расчёт стоимости, возможность изменения | Корректное отображение товаров, возможность изменения количества, расчёт итоговой суммы |
Ввод данных доставки | Валидация полей, сохранение данных, доступные опции доставки | Валидация обязательных полей, расчёт стоимости доставки |
Выбор способа оплаты | Доступные методы, зависимость от местоположения | Отображение только доступных методов оплаты для адреса доставки |
Оплата | Интеграция с платёжными шлюзами, обработка ошибок, таймауты | Корректная передача данных платёжному шлюзу, обработка ответов |
Для метода "N-Switch" составим маршруты тестирования с различной глубиной (N):
- 1-Switch: Проверка всех прямых переходов между состояниями (например, Корзина → Ввод данных)
- 2-Switch: Проверка последовательностей из двух переходов (Корзина → Ввод данных → Выбор оплаты)
- 3-Switch и более: Более сложные комбинации для выявления дефектов, зависящих от предыстории
Ключевые сценарии для тестирования переходов в конечном автомате:
- Прямое последовательное прохождение всех шагов
- Возврат на предыдущие шаги с сохранением данных
- Прерывание и возобновление процесса (например, закрытие и повторное открытие браузера)
- Попытки "нелогичных" переходов (например, прямой переход к оплате, минуя выбор доставки)
- Обработка таймаутов на различных этапах
- Параллельные сессии с одинаковыми учётными данными
Автоматизация таких тестов может быть реализована с использованием графовых алгоритмов для генерации оптимальных тестовых маршрутов, покрывающих все состояния и переходы с минимальным количеством тестов. 📊
Пример 3: Тестирование переходов в мобильных приложениях
Мария Соколова, Senior Mobile QA Engineer
В прошлом году мы тестировали популярное приложение для фитнес-трекинга. Пользователи жаловались на потерю данных тренировок при переключении между разными экранами. В стандартных чек-листах этот кейс не был учтён, потому что проблема проявлялась только в определённой последовательности переходов.
Мы применили тестирование состояний, смоделировав 12 ключевых экранов приложения и все возможные переходы между ними. Для уязвимых мест (где происходила работа с данными) мы построили более детальные диаграммы состояний по принципу "чёрного ящика".
Наши тесты выявили, что при определённой последовательности действий — запись тренировки → переход на экран статистики → получение push-уведомления → переход в раздел достижений → возврат к тренировке — данные не сохранялись корректно из-за неправильной обработки жизненного цикла Activity. Используя модель состояний, мы обнаружили ещё 5 подобных проблем в других частях приложения до релиза.
Мобильные приложения предъявляют особые требования к тестированию состояний и переходов из-за специфики их жизненного цикла и взаимодействия с пользователем. Рассмотрим ключевые аспекты такого тестирования:
Особенности тестирования состояний в мобильных приложениях:
- Жизненный цикл Activity/Fragment (Android) и UIViewController (iOS)
- Переходы между экранами, включая анимацию и обработку жестов
- Сохранение и восстановление состояния при повороте устройства
- Обработка сворачивания/разворачивания приложения
- Реакция на системные события (входящие звонки, push-уведомления)
- Обработка различных состояний сетевого соединения
Примерный план тестирования переходов для типичного мобильного приложения:
- Построение диаграммы навигации приложения (карты экранов)
- Определение переходов между экранами и ожидаемого поведения
- Идентификация состояний, где хранятся важные данные
- Проверка стандартных навигационных паттернов (навигация назад, вверх, табы)
- Тестирование "глубоких ссылок" (deep links) и их влияние на состояние приложения
- Проверка обработки системных прерываний
Пример сценария тестирования для приложения электронной коммерции:
- Добавление товара в корзину → Проверка обновления счётчика корзины
- Переход к оформлению заказа → Поворот устройства → Проверка сохранения данных
- Во время заполнения адреса получение входящего звонка → Принятие звонка → Возврат в приложение → Проверка сохранения введённых данных
- Переход к оплате → Потеря сетевого соединения → Проверка корректного отображения ошибки и возможности повторить операцию
- Успешное оформление заказа → Получение push-уведомления → Переход по уведомлению → Проверка корректного открытия деталей заказа
Инструменты для эффективного тестирования состояний в мобильных приложениях:
- Средства записи и воспроизведения действий (Appium, Espresso, XCTest)
- Инструменты мониторинга жизненного цикла компонентов (Android Monitor, Xcode Instruments)
- Средства имитации системных событий (телефонные звонки, уведомления, изменение сетевого соединения)
- Инструменты анализа потоков навигации (Firebase Analytics с User Journey)
Важно помнить, что мобильные приложения часто работают в непредсказуемой среде с ограниченными ресурсами, что делает тестирование состояний особенно важным для обеспечения стабильности работы и положительного пользовательского опыта. 📱
Хотите освоить профессиональный подход к тестированию мобильных приложений и других сложных систем? Пройдите Тест на профориентацию от Skypro и узнайте, насколько карьера в QA соответствует вашим навыкам и предрасположенностям. Тест определит ваши сильные стороны и подскажет оптимальный путь развития в сфере тестирования — от функционального до работы со сложными состояниями и переходами систем.
Пример 4: Валидация переходов состояний в API
Тестирование API с точки зрения состояний и переходов — это важный, но часто недооцененный аспект валидации серверной части. Рассмотрим, как применять этот подход на примере REST API для управления заказами.
Основные состояния заказа в типичной системе:
- Created (Создан)
- Processing (В обработке)
- Approved (Подтвержден)
- Shipped (Отправлен)
- Delivered (Доставлен)
- Cancelled (Отменен)
- Refunded (Возврат)
При тестировании API необходимо проверять не только функциональность отдельных эндпоинтов, но и корректность обработки переходов между состояниями. Ключевые аспекты тестирования:
- Валидность переходов — проверка допустимых и недопустимых последовательностей изменения состояний
- Идемпотентность — повторные запросы не должны приводить к дублированию действий
- Транзакционность — обеспечение целостности данных при сбоях во время переходов
- Параллельные запросы — корректная обработка конкурентных изменений состояния
- Авторизация — проверка прав доступа для каждого перехода
Пример структуры тестов для проверки переходов состояний в API заказов:
Текущее состояние | Запрос API | Ожидаемое новое состояние | Сценарий проверки |
---|---|---|---|
Created | PUT /orders/{id}/process | Processing | Успешный переход при наличии товаров на складе |
Created | PUT /orders/{id}/cancel | Cancelled | Успешная отмена, проверка возврата резервации |
Processing | PUT /orders/{id}/approve | Approved | Успешное подтверждение при достаточном балансе |
Delivered | PUT /orders/{id}/cancel | Ошибка 400 | Невозможность отмены доставленного заказа |
Cancelled | PUT /orders/{id}/ship | Ошибка 400 | Невозможность отправки отмененного заказа |
Для автоматизации тестирования переходов состояний в API используются следующие подходы:
- Последовательное тестирование — прохождение стандартных последовательностей от создания до завершения
- Негативное тестирование — попытки выполнить недопустимые переходы
- Нагрузочное тестирование переходов — проверка параллельных изменений состояния
- Тестирование отказоустойчивости — симуляция сбоев во время критических переходов
Пример автоматизированного теста с использованием REST Assured:
@Test
public void testOrderStateTransitions() {
// Создание заказа
String orderId = given()
.contentType(ContentType.JSON)
.body(orderData)
.when()
.post("/api/orders")
.then()
.statusCode(201)
.extract().path("id");
// Проверка начального состояния
assertOrderState(orderId, "Created");
// Переход к обработке
given()
.when()
.put("/api/orders/" + orderId + "/process")
.then()
.statusCode(200);
assertOrderState(orderId, "Processing");
// Попытка недопустимого перехода
given()
.when()
.put("/api/orders/" + orderId + "/deliver")
.then()
.statusCode(400);
// Состояние не должно измениться
assertOrderState(orderId, "Processing");
}
Важный аспект тестирования API — проверка корректного отражения переходов в системах аудита, нотификации и интеграции с внешними сервисами. Например, при изменении статуса заказа на "Shipped" должно отправляться уведомление клиенту, а также обновляться информация в системе складского учёта. 🔄
Пример 5: Тестирование переходов состояний в API
Дополнительно к базовому тестированию API с позиции состояний, важно учитывать особенности, связанные с асинхронной обработкой и согласованностью данных. Рассмотрим более сложный сценарий для платёжного API.
В современных распределённых системах состояние часто изменяется асинхронно, через цепочки сервисов. Например, в платёжном API транзакция может проходить следующие состояния:
- Initiated (Инициирована)
- Authorizing (Авторизация)
- Authorized (Авторизована)
- Capturing (Списание средств)
- Captured (Списание выполнено)
- Failed (Ошибка)
- Refunding (Возврат в процессе)
- Refunded (Возвращена)
Особенности тестирования сложных переходов в API:
- Проверка конечной согласованности — система может временно находиться в противоречивом состоянии, но должна в итоге прийти к согласованному
- Тестирование webhook-уведомлений — проверка корректности и своевременности уведомлений о смене состояния
- Идемпотентность при повторных запросах — особенно важно для операций оплаты
- Обработка длительных процессов — тестирование промежуточных состояний и таймаутов
Пример стратегии тестирования платёжного API:
- Создание тестовых транзакций с различными параметрами
- Проверка последовательного прохождения всех состояний
- Имитация сбоев в различных точках потока (на стороне банка, в сети, в системе)
- Проверка корректности возврата к предыдущим состояниям при сбоях
- Тестирование обработки таймаутов от внешних систем
- Проверка корректности обработки параллельных операций над одним платежом
Для эффективного тестирования асинхронного API полезны следующие инструменты:
- Сервисы-имитаторы внешних платёжных систем с контролируемым поведением
- WebSocket-клиенты для отслеживания обновлений состояния в реальном времени
- Инструменты для настройки нестабильной сети (Network Link Conditioner, Chaos Monkey)
- Средства генерации параллельной нагрузки для выявления проблем согласованности
Пример тестового сценария для проверки обработки сбоев в платёжном API:
- Инициировать платёж (состояние Initiated)
- Дождаться перехода в состояние Authorizing
- Имитировать таймаут от банковской системы
- Проверить корректный переход в состояние Failed с соответствующим кодом ошибки
- Выполнить повторную попытку платежа
- Проверить успешное прохождение полного цикла до Captured
- Инициировать частичный возврат средств
- Проверить переход в состояние Partially Refunded
Особое внимание следует уделить взаимодействию с внешними системами, где часто возникают сложности с детерминированностью поведения. Использование макетов (mocks) и стабов (stubs) помогает создать контролируемую среду для проверки всех возможных переходов между состояниями. 📊
Тестирование состояний и переходов — фундаментальный навык, который разделяет начинающих тестировщиков от экспертов. Использование данного подхода позволяет выявлять до 30% критических дефектов, которые невозможно обнаружить другими методами. Начав с визуализации потоков состояний и переходов в системе, вы сможете создать эффективные стратегии тестирования, выявляющие неочевидные ошибки до того, как они достигнут пользователей. Систематическое тестирование переходов — это инвестиция в надёжность и предсказуемость вашего продукта, которая всегда окупается сниженным количеством инцидентов в продакшене.