Статьи

BDD: думай как актер

Сцена справа

Не скучайте по этому поводу, BDD не легко! Это на самом деле чертовски верно, и требует времени, чтобы освоить и сделать это правильно. К счастью, преимущества намного перевешивают первоначальные затраты. Если вы решили практиковать BDD, то вы уже приняли сознательное решение прервать цикл «сожги и почистить» , и это действительно мудрый выбор!

Тем не менее одних благих намерений не всегда достаточно. Многие разработчики разочаровываются и разочаровываются в процессе, который, кажется, не работает для них. В этой статье я хотел бы исследовать некоторые из наиболее распространенных препятствий и ловушек, с которыми сталкиваются новички в BDD, и предложить несколько советов, которые помогут преодолеть их.

Я предполагаю, что, как и большинство разработчиков Ruby BDD, вы используете Cucumber для своей реализации. Если вы используете другой инструмент или даже другой язык, не паникуйте: принципы, описанные здесь, остаются неизменными, независимо от вашего выбора инструментов.

В начале было … Определение системы!

«С чего мне начать? Как мне определить поведение? »

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

При запуске нового проекта всегда — и я имею в виду всегда — определяйте, что находится внутри вашей системы, а что за ее пределами.

SP-система 1

Круг в центре — это наша система. Это то, что мы моделируем, проектируем и собираемся развивать. Маленькие фигурки, связанные с нашей системой, являются актерами . Если мы хотим начать хорошо, нам нужно начать думать, как они.

Что такое «актер»?

Ну, конечно, не Адам Сэндлер, LOL! (примечание для редактора: мы собираемся получить иск за это ??). Традиционно, возвращаясь туда, где возник термин , субъект — это внешняя по отношению к нашей системе сущность, которая взаимодействует с -или действует на нашу систему. Итак, наши конечные пользователи, системные администраторы и сторонние API-интерфейсы являются действующими лицами.

Теперь я собираюсь быть настолько смелым, чтобы расширить это определение, особенно для BDD:

Актер — это внешняя сущность, которая имеет личную заинтересованность или долю в системе и имеет право защищать эту заинтересованность, диктуя поведение системы.

Обратите внимание, что здесь я вообще не упоминаю взаимодействие. Это потому, что поведение системы может быть продиктовано сущностями, которые никогда не касались вашей системы, никогда не взаимодействовали с ней напрямую. Владелец или директора вашей компании — все действующие лица в вашей системе, поскольку они заинтересованы в ней. Как и ваш менеджер по продажам и кто-либо еще, кто имеет право ожидать определенного поведения от вашей системы.

На самом деле, многие из ваших нефункциональных функций (безопасность, производительность и т. Д.) Исходят от этих «пассивных» актеров, поэтому знайте их важность и не стоит их недооценивать.

Совет: обобщите ваши актеры

Некоторые актеры, как правило, играют разные роли, в зависимости от того, как они взаимодействуют с нашей системой. Например, в системе обмена сообщениями или чата конечным пользователем будет либо издатель, либо подписчик, часто оба. Использование общего имени актера (например, пользователя) упрощает схемы и краткие описания. Использование конкретного имени актера (например, издателя или подписчика) помогает конкретизировать конкретное поведение, которое не всегда очевидно при взгляде на него с общей точки зрения.

Совет: «Внешний» означает именно это

Допустим, у нас есть база данных, в которую наша система должна читать / записывать. Если эта база данных находится под нашим контролем (то есть мы создали ее, поддерживаем ее и т. Д.), То она является частью нашей системы и является внутренней для нее. Если у нас нет никакого контроля над ним, кроме как только чтение или запись в него, тогда база данных является внешней по отношению к нашей системе и должна рассматриваться как субъект .

Давайте посмотрим, как теперь должна выглядеть наша диаграмма, принимая во внимание обобщения и «пассивные» действующие лица.

SP-система 2

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

Вот как мы собираемся это сделать.

Каждая функция должна рассказывать историю.

Не просто любая старая история. История в определенном формате :

As an [Actor] I want [some System Behavior] So that I can [have a tangible benefit] 

Если Актер в первом утверждении отсутствует на вашей системной диаграмме, спросите себя, должны ли они быть. Если ответ «да», добавьте их в диаграмму. Могут быть и другие функции, которыми управляет этот актер. Если вы вообще не знаете, где актер, вы никогда не узнаете.

Заявление «Так что ..» должно указывать на ощутимую выгоду для Актера, который управляет этой функцией. Если это не так, перефразируйте его или отклоните.

пример

 Feature: User Presence As the Web-User, I want to see if other users are logged in, so that I can know if my friends are present. 

Ну, а вы теперь мистер веб-пользователь? Какая ощутимая выгода для вас, кроме удовлетворения вашего любопытства по поводу привычек ваших друзей в Интернете? В настоящее время история этой функции не оправдывает ее обоснованность. Этот, однако, делает:

 Feature: User Presence As the Web-User, I want to see if other users are logged in, so that I can contact them. 

Увидеть разницу? Первая история приводит к прихоти, вторая — к солидной, действенной выгоде.

Почему это должно меня волновать?

Для начала, вторая история приводит к открытию дополнительного поведения / функции. Первый нет. Можете ли вы угадать, что такое дополнительная функция?

Что еще более важно, наличие действительной пользовательской истории для нашей функции помогает нам понять и определить, что такое функция. Учти это:

 Feature: Account Profile As a New User, I want to create an account profile, so that I can register with the system. 

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

 Feature: Account Profile As a New User, I want to create an account profile, so that I can be allowed to use the system. 

Хорошо, теперь у нас есть ощутимая выгода для нашего актера. Тем не менее, что-то не так. Чтобы пользователю было разрешено использовать систему, ему нужно сделать гораздо больше, чем просто создать профиль учетной записи. Ей нужно будет создать учетные данные, подтвердить свой адрес электронной почты и так далее. Другими словами, ей придется пройти через набор системных поведений, чтобы достичь своей цели. Этот набор поведений — это особенность, которая нужна нашей системе . Поэтому описание функции должно читаться так:

 Feature: Account Creation As a New User, I want to create an account, so that I can be allowed to use the system. 

Индивидуальные действия (учетные данные, профиль учетной записи, подтверждение по электронной почте и т. Д.) Будут учитываться в сценариях нашей функции. Они не гарантируют отдельную Особенность для каждого, поскольку они индивидуально не в состоянии понять цель Актера. Хорошая игровая история помогает нам увидеть лес за деревьями.

Говорить на языке актера

Язык это забавная вещь. Одно и то же слово может иметь разное значение в зависимости от того, когда, где или кем оно было произнесено. Я слышал слово «сессия», относящееся к трем различным вещам трех разных людей в одной беседе (владелец продукта, разработчик и сетевой инженер). При написании Особенностей мы всегда принимаем язык Актера. Если наш актер считает, что «сессия» — это быстрое общение с друзьями за чашкой кофе, то мы относимся к этому так же, как в нашей функции. Написание глоссария двусмысленных терминов, которые каждый может найти, может быть очень полезным.

Актеры заботятся о «что», а не «как»

Дело в том, что актеры заботятся только о результатах. Ваш конечный пользователь хочет видеть свой банковский баланс на экране. Ваш системный администратор хочет увидеть некоторые системные журналы. Ваш сторонний API хочет видеть некоторые данные в определенном формате. Они не заботятся о том, как система производит баланс банка, файл журнала или полезную нагрузку, если она производит это правильно.

Вопрос : что не так со следующим сценарием?

 Feature: Logging in (..story omitted for brevity) Scenario: Valid login Given I am on the "login" screen When I enter "[email protected]" in "email" field And I enter "password1" in "password" field And I click the "login" button Then the message "you are logged in" appears 

Ответ : это было написано разработчиком, а не актером. Все дело в «как», а не в «что». Если мы снимаем шляпу разработчика, надеваем шляпу актера и переписываем эту функцию, мы должны получить что-то вроде этого:

 Feature: Logging in (..story omitted for brevity) Scenario: Valid login Given I have an authorized account Then I can login 

Да, я слышу, что думают некоторые из вас:

«Ну и что? Разве не нормально использовать стандартные веб-методы пользовательского интерфейса, когда мы указываем веб-систему ?! «

Ну нет, это вроде не хорошо, не когда мы пишем наши Особенности. Во-первых, наш переписанный сценарий гораздо более читабелен, он не увяз в случайных деталях. Во-вторых, очень вероятно, что в ближайшем будущем метод входа в систему изменится и потребует сканирования радужной оболочки или какой-либо другой новой и замечательной техники. Мы не хотим менять наши Сценарии функций каждый раз, когда меняется их реализация. Вот для чего нужны наши определения шагов. «Как» входит в наши шаги, «Что» остается в наших функциях.

Другой способ взглянуть на это с точки зрения императивов и декларативных перспектив. Как разработчики мы любим императивный стиль: если A, то B, затем C и т. Д. Актеры, с другой стороны, думают декларативно: B (A): — C (A). И теперь мы знаем, как мыслить как актеры , верно?

Резюме

BDD предлагает огромные награды тем, кто может справиться с этим. Следуя определенным принципам и придерживаясь определенной ментальной модели, мы можем написать стабильные, ценные и читаемые функции. На тот момент мы выиграли половину битвы, прежде чем она уже началась. Другая половина думает о наших определениях шагов. Но это уже другая тема в другой раз 🙂