Добрый день, Хаброчитатели!
В своей рубрике IT (Interesting Testing) я постараюсь рассказывать вам о разных интересных подходах к тестированию и полезных инструментах, делающих процесс поиска ошибок захватывающим.
Сегодня я расскажу вам о:
- BFT – Business Flow Testing, что это?
- На простых примерах покажу как этим пользоваться
- Какие есть преимуществах у такого подхода
- Где его можно применить
- И что будет дальше
Потоковое тестирование (BFT — BusinessFlowTesting)
BFT – это подход к тестированию, где вы смотрите на продукт не с точки зрения конкретных кейсов, а с точки зрения поведения системы в каждой ее точке.
Подход является объединением таких концепций, как Data Driven Testing и Behaviour Driven Testing, примененным к бизнес-моделям, хорошо описываемым графами движения данных.
Вы не тестируете отдельные тест-кейсы, а проверяете работоспособность системы, тест-кейсы получаются сами по себе
Образно говоря, у вас есть:
- Набор разнообразных входных бизнес данных
- Система, разбитая на важные для тестирования состояния бизнес-сущностей, которые надо проверить
- Правила перехода между состояниями
У вас нет тест-кейсов. Тест-кейсы генерируются на основании входных данных сами.
Больше не надо спорить, как назвать тест-кейсы правильно. Название тест-кейса – это набор определяющих его входных данных и путь по которым они пройдут. Название получается длинное, но полностью описывающее данный тест. И к тому же вы не тратите на него ни секунды — оно создается само.
BFT Framework
Как же устроен BFT фреймворк и как его сделать самому? Рассмотрим простой пример
Допустим, ваше приложение – магазин, продающий товары. Основными Приемочными тестами будут тесты на то, как пользователь приобретает этот товар и что с ним может случится дальше.
Бизнес-сущности:
- Пользователь (ФИО, тип оплаты (банковская карта, наличные, электронные деньги и прочее), дисконтная карта, история покупок, промо-код и пр.)
- Товар (название, номер, цена исходная, цена итоговая, количество, акции, в которых участвует и пр.)
- Покупка-Корзина (Список товаров, цена корзины, итоговая цена покупки, состояние покупки)
Состояния заказа:
- Сформирован (Created)
- Утвержден (Registered)
- Оплачен (Paid)
- Доставляется (Delivering)
- Доставлен (Delivered)
- Доставка отклонена (Delivering Rejected)
- В Архиве (In Archive)
Граф перемещения товара
У вас есть диаграмма, которая, скорее всего, предоставлена бизнесом. Если нет, то можно составить самим, что принесет массу пользы само по себе.
Для тестирования этой Диаграммы тестировщик описывает каждое состояние.
Для описания состояния нужно указать:
- Checks. Что проверять в этом состоянии
- Transitions. Куда и как можно перейти из этого состояния
P.S. И Checks, и Transitions являются функцией от Context, т.е. набора данных, пришедших в состояние, и пройденного пути (необязательно)
Каждый тест — это линейный путь в этом графе, который характеризуется входными данными.
Входные данные могут быть нескольких типов:
- Бизнес-данные (пользователь, товар, корзина и прочее)
- Влияют на проверки в состояниях
- Могут влиять на путь в графе (к примеру, Зарегистрированный пользователь пропускает идентификацию и перемещается сразу в Paid)
- Управляющие данные (к примеру, сделать возврат после оплаты или вернуть заказ из Архива)
Написание тестов
Базовый простой тест
У нас есть бизнес модель-граф. Для этого графа мы создаем тестовый код, который описывает, уже на языке программирования, то что надо проверять в каждом состоянии и куда идти дальше.
Итог: у нас описан тестовый граф (граф вначале не обязательно описывать полностью, допустим, вначале описан только позитивный сценарий, все остальные состояния и переходы можно добавлять по мере необходимости).
Первый тест – это обычно главный позитивный тест, который проходит от начала бизнес потока и до конца без ошибок.
Формируем входные данные для позитивного теста.
Сам тест будет выглядеть примерно так:
var SimpleScenario = BusinessGraph.GetScenario(CorrectSimpleData, DefaultControllData);
BFTFramework.Run(SimpleScenario, CorrectSimpleData);
BusinessGraph по входным данным CorrectSimpleData построит линейный путь-сценарий (по умолчанию DefaultControllData) в графе на выходе получаем SimpleScenario.
BFTFramework исполнит этот сценарий со входными данными CorrectSimpleData.
Остальные тесты
Теперь, если мы хотим проверить много разных позитивных данных, то просто передаем другие наборы CorrectOtherData.
Если нам нужно добавить, допустим, негативные тесты (к примеру, возврат покупки):
- Мы добавляем новое Состояние Rejected Delivering в BusinessGraph (проверки, которые надо сделать при переходе в это состояние, и возможные пути из него, если нужно)
- Добавляем пути переходов в это новое состояние из других состояний (в нашем случае это стрелка Delivering -> Rejected Delivering)
- Передаем в наш тест набор не корректных данных DeliveringRejectedData
И так далее, постепенно наращивая наш граф новыми путями, а тесты новыми наборами данных.
Если вы решили сделать новую проверку на каком-либо шаге, вам не надо думать, в каких тестах это встречается. Вы просто добавляете это в соответствующее Состояние, и все тесты, которые через него проходят, будут откорректированы.
Появилось новое состояние, через которое надо пройти нашему товару,— просто добавляете его в граф, и все тесты, которые его затрагивают, будут перенаправлены по новому пути.
Вы правите код тестов локально, только там, где это необходимо.
Итого:
- Мы получаем разделение тестового кода на: данные, «тестовый интерфейс приложения» (состояния графа и Checks) и пути перемещения данных (дуги графа Transistions)
- Новые тесты не надо писать каждый раз с нуля. Мы добавляем только то, что действительно ново, максимально переиспользуя то, что уже написано и избегая дублирования кода
- Так как все наши тесты перемещаются по графу, мы можем использовать метрики для покрытия функционала тестами. К примеру, «каждый путь пройден хотя бы один раз», или «каждое состояние посещено хотя бы один раз», или более сложные — вроде посещения циклов в графе не менее двух раз и прочее
- Мы получаем дополнительную цельную документацию системы на уровне конкретных важных проверок.
Зачастую, даже если в начале проекта есть бизнес граф, с добавлением новых UserStory он теряет свою актуальность. Тесты всегда актуальны. К тому же бизнес описание не включает в себя понимания, что же конкретно важно в этих состояниях, либо эта информация разбросана по разным UserStory. Взглянув на BFT граф, вы всегда можете сказать, что проверяется на данном шаге, куда из него можно перейти и каким способом - Тестирование при помощи BFT можно сочетать с любыми другими тестами, которые не очень легко ложатся в схему или сильно ее загромождают. Думайте, что и для чего вы используете
- При правильном написании BFT Framework в каждый момент времени в тесте вы можете узнать весь сценарий (Состояния и переходы) и то, на каком шаге вы сейчас находитесь. Этот сценарий легко вывести в лог в случае ошибки или передать разработчику, когда он вас спрашивает, «а что этот SimpleTest вообще делает?»
- Так как вы знаете весь сценарий, то вы можете выводить в лог переход в каждое новое состояние автоматически, без дополнительных затрат тестировщика (а обычно в таких случаях логирование просто игнорируется из-за нехватки времени)
- При движении в графе мы используем тестовый контекст, который содержит всю информацию о тесте:
- Все входные данные
- Текущий сценарий
- Текущий шаг
- Дополнительные переменные, которые мы сохранили в процессе теста
- Мы легко можем вывести все эти данные в лог в случае падения теста или передать разработчику, не запуская тест по новой в дебаге
Область применения
Прежде чем использовать что-то подумайте, подходит ли вам этот инструмент.
Данный подход применим для проектов, где легко можно выделить бизнес-сущности и состояния, в которых они живут.
Это могут быть:
- Всевозможные магазины. Продажа реальных товаров, контента, услуг и прочее
- Службы доставки
- Банковские проекты, платежи, переводы и другие проекты с транзакциями
- Тестирование интерфейсов (UI). Вы можете представить Пользователя в качестве Бизнес- сущности, страницы – состояниями, а действия пользователя в виде переходов между состояниями
В одном из отделов i-Free мы успешно применили этот подход, надеюсь, что и вам он тоже поможет сделать красивые, легко поддерживаемые, логируемые и наглядные тесты.
Что дальше?
В следующих статьях:
- я расскажу про генерацию входных наборов данных, построение пересечений и исключений для создания только важных тестов
- подробнее расскажу про метрики и то, как нужно строить процесс тестирования с BFT
- остановлюсь детально, с примерами «псевдо-кода», на описании состояний, проверок и переходов
- расскажу о подводных камнях и проблемах, которые могут возникнуть у вас при первом знакомстве с BFT
- постараюсь осветить вопросы, которые, я надеюсь, возникнут в комментариях
Автор: RomanYIovlev