Как сквозные приемочные тесты должны разделять большую функцию на сценарии?
В своей статье " Что в рассказе"? Дэн Норт делает ряд отличных моментов. Три, в частности:
Название сценария должно сказать, что отличается
Вы должны быть в состоянии выстроить сценарии в ряд и описать, как они отличаются, используя только заголовок.
Сценарий должен быть описан в терминах событий, событий и результатов.
Это самый мощный поведенческий сдвиг, который я видел в командах, принимающих BDD. Просто заставляя бизнес-пользователей, аналитиков, тестировщиков и разработчиков принять этот словарь "дано / когда / потом", они обнаруживают, что мир двусмысленности исчезает.
Не все сценарии такие простые. Некоторые из них лучше всего представить в виде последовательности событий, описываемой как: заданный [некоторый контекст], когда [я что-то делаю], затем [это происходит], когда [я делаю что-то другое], затем [это новое происходит] и так далее. Примером является веб-сайт в стиле мастера, где вы проходите последовательность экранов, чтобы создать сложную модель данных. Вполне уместно смешивать последовательности событий и результатов, если вы привыкли мыслить в этих терминах.
История должна быть достаточно маленькой, чтобы соответствовать итерации
Нет жестких и быстрых правил о том, как вы это делаете, если вы разбиваете их на наглядные куски. В целом, если существует более пяти или шести сценариев, историю, вероятно, можно разбить, сгруппировав похожие сценарии вместе.
Теперь предположим, что кто-то пытается описать сквозные приемочные тесты для некоторой функции в стиле мастера (как он рассмотрел выше).
Естественно определять "сценарии" тем, как отличается состояние в самом начале использования функции мастера (действительно, это может соответствовать его пунктам № 1 и № 2 выше), но, конечно, неуместно перечислять все пути через мастера (от начала до конца) в полностью сериализованной форме для создания таких независимых сценариев? Мало того, что это приведет к большому количеству сценариев, но каждый из них будет состоять из множества этапов (вопреки пункту № 3 Дэна) - и многие из этих этапов будут дублироваться между сценариями просто для достижения состояния, в котором они расходятся!
Scenario: Make a successful booking Given that I am at the booking form When I do A Then I see B When I do C Then I see D When I try to book Then I see a successful message Scenario: Attempt to book, no availability Given that I am at the booking form When I do A Then I see B When I do C Then I see D When I try to book Then I see no availability
С другой стороны, было бы более эффективно определить один сценарий для каждого возможного состояния в начале каждой ветви решений в функции мастера - и
When
"событие" будет просто единственным шагом, который перенесет эту функцию в следующую ветвь принятия решения. Однако разве это не перемещает SUT вниз по стеку, поэтому мы больше не будем определять сквозные приемочные тесты, а скорее что-то более низкого порядка? Более того, гораздо менее естественно следовать и понимать критерии теста - что наверняка побеждает весь смысл BDD?Scenario: Do first step Given that I am at the booking form When I do A Then I see B Scenario: Do second step Given that I see B When I do C Then I see D Scenario: Make a successful booking Given that I see D When I try to book Then I see a successful message Scenario: Attempt to book, no availability Given that I see D When I try to book Then I see no availability
Если идти по этому пути, мне кажется более правильным разделить каждую ветвь принятия решений на отдельные функции; и тогда только те сценарии в каждой ветви будут рассматриваться в рамках одной функции - что только подчеркивает мою точку зрения о перемещении SUT вниз по стеку.
Возможно, эти сквозные приемочные испытания слишком подробны, и весь мастер должен (на данном этапе) рассматриваться скорее как черный ящик? Я не уверен, как это помогает заказчику понять, что он вводит в эксплуатацию, тем более что подробные шаги этой функции являются ключом к приемлемости всей системы.
Каков наиболее подходящий способ разделения такой функции на сценарии?
2 ответа
Проблемы большинства волшебников связаны с тем, как мы выражаем вещи. Когда функция исследует "как" что-то делается, она оказывается многословной. Мы должны сосредоточиться на том, почему мы делаем вещи.
Если мы думаем таким образом, мы можем полностью устранить проблему, заключив в себе одного волшебника. Например:
Feature: Fill in my tax form
Scenario: Fill in my tax form
When I fill in my tax form
Then my tax form should be filled in
Однако это, вероятно, "высокая" абстракция для чего-то столь же сложного, как это. Чтобы добавить больше деталей, вы должны разделить сценарий на части и найти причину для заполнения каждой части. Затем вы используете причину (почему), чтобы написать свои сценарии.
Если мы вернемся к налоговой форме и представим, что она содержит всего три части (для простоты): личность, доход, расходы.
Теперь мы можем написать такие вещи, как:
Feature: Tax indentification
As someoene who is taxed
I need to provide proper indentification
So I pay for my tax and not someone else's
Scenario: Provide indentification
Given I am filling in my tax form
When I provide indentification
Then I should be asked about my income
Мы можем исследовать печальные пути с такими вещами, как
When I provide insufficient identification
Then I should be asked for more indentification
и т.п.
Когда мы осуществим это, мы сможем написать
Feature: Tax - provide income details
...
Given I am filling in my tax form
And I have provided indentification
When I provide my income details
Then I should be asked about my expenses
и мы можем повторить процесс исследования печальных путей. Обратите внимание, что данное может быть реализовано с использованием тестовой функциональности, которую мы создали при реализации этапа идентификации.
Искусство всего этого состоит в том, чтобы выяснить, почему вы завершили каждый этап процесса и какие имена вы даете различным состояниям, в которые вы попадаете, когда вы совершаете свое путешествие по процессу. Также обратите внимание, что в этой функции нет упоминания о том, "как" вы делаете этот материал.
Наконец, это в значительной степени второй метод, о котором вы говорили, с дополнительным акцентом на "почему", а не на "как". Вы можете выбрать уровень абстракции (то есть, на сколько частей вы разбиваете это), и вы можете управлять именованием. Язык и наименование решают ваши проблемы с читабельностью, особенно если вы принимаете во внимание дополнительный контекст, который вы можете дать из таких вещей, как имя объекта и его положение в иерархии файлов.
ИМХО покрытие всех путей для каждого возможного состояния слишком детально. BDD помогает командам совместно определять и делать преднамеренные открытия. Поэтому вам следует сосредоточиться на ключевых примерах ( http://gojko.net/2014/05/05/focus-on-key-examples/).
Ваши автоматические тесты часто имеют несколько целей. Основой для этого являются модульные тесты, которые помогут вам убедиться в правильности сборки вашего продукта. Приемочные тесты выходят на следующий уровень и помогут вам создать правильный продукт.