воскресенье, 21 июля 2013 г.

BDD, Spec By Example или Как писать спецификации

Часто валидирую, переделываю, упрощаю спецификации, потому хочу описать HOW-TO как писать спецификации правильно на основе своего текущего понимания.

Зачем нужны спецификации?

Советую прочитать "Specification by Example How successful teams deliver the right software" от Гойко Аджича. Для нас это:
  • АС тесты 
  • способ передачи бизнес информации в разработку
  • живая документация и способ фиксирования знаний
Как АС тесты и способ донести информацию до разработчика - это оказалось очень мощной техникой. Если вы не пишите спеки и у вас проблемы с качеством, то советую попробовать. 

Спецификации мы пишем на  Cucumber, потому рассматриваю только Gherkin формат. 

Какие есть требования к спецификациям? Мое основное требование к спецификациям - это их эффективность.

И обычно проблема со стоимостью спеки. Стоимость - это трудозатраты на создание спеки, ее реализацию и поддержку в течение жизни продукта. Чем меньше придется переделывать спеку со временем, тем она дешевле.

Я переделываю чужие спеки не потому, что они не правильные - если разработчик может реализовать данную спеку, то она верна и имеет value. Я переделываю их, чтобы сделать более дешевыми и потому более эффективными.

Спека
"Пользователь авторизуется, заполняет форму, нажимает "Сохранить" и данные формы сохраняются"
возможна и полезна для продукта, но слишком дорога в поддержке. Потому не эффективна. Сейчас мы не пишем спецификации на GUI совсем. Это слишком дорого для нас. Вместо этого мы пишем
  • Спеки на логику
  • Unit тесты на View и Save 
  • Smoke GUI тесты  

Требования к спецификации

Мое главная требование к спеке:
  1. она должна покрывать одно небольшое атомарное действие (action). 
  2. Это то знание, что вы хотите зафиксировать для себя, для Заказчика, для продукта. Нет знания - нет спеки.
Основное правило для Gherkin формата. Мы описываем, что система находится в состоянии А, выполняется action, система переходит в состояние В.

Описывается это в Gherkin формате как 
  • GIVEN - Состояние А
  • WHEN - action 
  • THEN - Состояние В
Состояние А - это набор исходных параметров, которые влияют на action.

Состояние В - это описание результата в виде других параметров.

Action обычно не имеет параметров, это явное описание действия. Такое как - валидация, сохранение, сложение, проверка и тп. Но в ряде случаев для улучшения понимания возможно перенести часть параметров состояния А в WHEN и указать как параметры действия - action(param). Но лучше не надо!

Важно, что action должен быть как можно более атомарным, маленьким по времени. Представим такую спеку:
  • GIVEN пришел запрос на поиск данных
  • AND    система выполнила поиск и сформировала результат
  • WHEN система выполняет валидацию результата поиска 
  • THEN  результат содержит только идентификатор записи
Мы правильно выделили в WHEN, что нас интересует только процесс валидации результата поиска. Но информация о том, что пришел запрос и был выполнен поиск была лишней. Получается, что спека описывает промежуток времени от момента прихода запроса до момента когда мы валидируем результат поиска. Это может быть очень большой промежуток времени. В результате по данной спеке разработчик реализует именно то что описано:
  1. создаст запрос
  2. выполнит поиск
  3. получит результат
  4. выполнит валидацию результата 
  5. сравнит результат с ожиданием в THEN
При этом пункты 1 и 2 лишние для данной спеки. Эти делают ее дорогой в исполнении и поддержке. Нам это не нужно. Состояние А здесь - это момент когда мы уже всё нашли, у нас уже есть результат. Остальное к спеке не относится. Потому
  • GIVEN система сформировала результат поиска на запрос
  • WHEN система выполняет валидацию результата поиска 
  • THEN  результат содержит только идентификатор записи

Мета-шаблон спецификации 

При разработке спецификация мы со временем вырабатываем шаблоны, практики для сходных случаев. Они нужны аналитикам из PO support team на уровне Shu. К сожалению это не позволяет корректно действовать в новых, нетипичных ситуация. Потому хочется описать шаблон спецификаций для мета уровне, который можно использовать в большинстве количестве случаев.

Мы хотим описать некоторую логику "Аction", которую можно представить как черный ящик. Для этого логики есть входные параметры "А" и "В", которые влияют на нее. И один выход "result" как результат выполнения логики.

Что важно:
  1. Результат всегда один, хотя в результате можно быть набор параметров.
  2. Результат детерминирован. То есть на основе одних и тех же параметров, результат должен быть одинаков. Из-за большого количества примеров эта ошибка это может быть незаметна.  
  3. Удалить всё что не влияет на логику и результат напрямую
То есть неважно что именно вы описываете. Представьте черный ящик, данные, которые поступают в него, и результат, который из него выходит. И вся сложность именно в том чтобы из всего многообразия бизнес случаев спецификаций найти этот "черный ящик".

И потом разработчики будут вам сильно благодарны. Название данного черного ящика - это тот метод в коде, который должен быть провалидирован. Вы его явно указали для них.

Ниже ряд ошибок, которые встречаются при написании спецификаций:


Логика использование спецификаций как тесты и валидация результата

Спека на сложение 
  • GIVEN есть числа <a> и <b> 
  • WHEN сложение чисел
  • THEN результат <c> - <d> 
  • Examples 
  • | a | b | c | d             |
  • | 2 | 3 | 5 | верен      |
  • | 2 | 3 | 6 | не верен |
  • | 2 | 3 | 4 | не верен |
Спецификация - это не тест, это описание поведения системы. Потому более эффективной будет спека.   
  • GIVEN есть числа "2" и "3" 
  • WHEN сложение чисел
  • THEN результат "5" 
Нет смысла валидировать поведение системы - система детерминирована, любой другой результат кроме описанного невозможен.

Много лишней, ненужной информации

  • GIVEN Пользователль авторизовался как "user" 
  • AND     открыл форму и заполнил значения "2" и "3"
  • WHEN пользователь выполнит отправку форму 
  • THEN  видит результат "5"
Информация про логин и открытие формы никак не влияет на логику - их нужно удалить чтобы упростить спеку и сделать ее более понятно.

Логика поиска 

Часто нужно описать логику поиска значений. Для этого используется следующий шаблон:

  • GIVEN Есть список значений 
  •   | key | value |
  •   | 101 | москва |
  •   | 203 | самара |
  •   | 307 | тула |
  • WHEN выполняется поиск
  • THEN результатов поиска являются значения с идентификаторами "101, 203"
Важно 
  1. Следует перечислить все "edge cases" значения и те атрибуты, которые влияют на логику поиска
  2. Следует явно указать какие значения должны быть найдены 

Результатом логики является список значений

Есть 2 варианта (когда вам не достаточно просто указать идентификаторы значений как в примере выше).
Вариант А.

  • THEN в списке результатов присутствуют <key> и <value>
  • Example:
  • | key | value |
  • | 101 | москва |
  • | 203 | самара |
То есть вы указываете, что вам важно чтобы в списке результатов были следующие значения. Проблема может быть в том, что в списке результатов так же могут быть значения, которые вы не ожидаете там увидеть. И вы об этом не узнаете - спека будет зеленой. Тогда
Вариант В.
  • THEN список результатов равен
  • | key | value |
  • | 101 | москва |
  • | 203 | самара |
То есть вы явно указываете полный список результатов и любое лишнее значение в нем будет FAIL.

Предположения 

Вы указали спецификацию с примерами, но в общем виде. Разработчик в рамках общения с аналитиком понял о чем спека и дописал в коде свои предположения по тем данным, что отсутствовали в спеке.
Спека зеленая.
Но потом, пройдет время, и все предположения, что разработчик вписал в реализацию, отнимут кучу времени на анализ и нахождение проблем почему система ведет себя не так как было описано в спецификации. Потому в реализации должно быть зафиксировано лишь то, что написано русским языком в тексте спецификации. И если в такой виде спецификация не реализуема, то ее нужно править.

Использование частицы "Не"

Напишите спеку с описанием того что система не делает и отдайте это на разработку. Чаще всегда пустая реализация, то есть 0 строчек кода уже позволяют системе не делать кучу всего, в том числе и то, что указано в спеке.
Переписывайте спеку без частицы "Не".

Удачи!

Комментариев нет:

Отправка комментария