Всем привет! Меня зовут Максим, и я работаю бизнес-аналитиком на проекте Швейцарских Железных Дорог. За последние пять лет я описал больше четырех сотен пользовательских историй, экспериментируя со структурой и форматом. Под катом рассказ о том, какие проблемы у меня возникали, и как их удалось решить.

Один из поездов Швейцарских ЖД
Один из поездов Швейцарских ЖД

Важность и проблематика

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

Проблемы на этапе рефаймента

У разработчиков появляется множество вопросов, что приводит к долгому обсуждению и разному представлению в отношении трудозатрат. Если команда активная и грамотно фасилитирует встречу, то такая история отправляется обратно в анализ. Если нет — историю принимают на выполнение и проблемы переносятся на следующий этап.

Проблемы на этапе разработки

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

Проблемы на этапе поддержки

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

Относительные затраты на исправление программных дефектов. Источник: исследование IBM Systems Sciences Institute.
Относительные затраты на исправление программных дефектов. Источник: исследование IBM Systems Sciences Institute.

Таким образом, можно уверенно сказать, что качественно написанная пользовательская история:

  1. Сэкономит много времени и нервов команде разработки

  2. Не снизит мотивацию разработчиков

  3. Существенно сэкономит бюджет проекта

Развитие описания пользовательской истории в моих проектах

6 лет назад проект, в котором я тогда работал, решил перейти с Вотерфола на Скрам. Изучив методологию, было решено новые требования писать в виде пользовательских историй.

Начали мы с классического описания. Приведу вымышленный пример для понимания того, как это выглядело:

Пример первых пользовательских историй

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

Первая реакция была — "Хмм, чего-то не хватает.." И действительно, методология Скрам предлагает писать истории простыми и лаконичными предложениями. В дополнении к этому необходимо написать критерии приемки, чтобы команда знала, как владелец продукта будет понимать, что история выполнена. Плюс можно расписать карточки пользователя, чтобы команда точнее понимала особенности и потребности пользователя (про карточки в контексте выглядит лишним, и их нет в примере). Ну хорошо, давайте добавим:

Пример доработанной пользовательской истории

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

Критерии приемки

  • Пользователь может изменить свой почтовый адрес

*представитель цифрового поколения

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

Описание функциональных требований

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

Пример пользовательской истории с функциональными требованиями

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

Системный дизайн

FR.NAME.123.01 Система должна предоставлять возможность пользователю менять свой почтовый адрес

  • Новая кнопка "сменить адрес доставки" должна быть добавлена на форме информации о пользователе

FR.NAME.123.02 Система должна предоставлять возможность хранить адрес доставки заказа отдельно от текущего адреса пользователя

  • Новый атрибут "адрес" должен быть добавлен на объектный тип Заказ

  • Когда курьер забирает заказ, система должна копировать адрес пользователя в Заказ.адрес. 

Критерии приемки

  • Пользователь может изменить свой почтовый адрес

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

Для того чтобы не запутаться и удобнее было обсуждать требования вводятся идентификаторы.

  • FR означает функциональное требование (также можно использовать NFR - нефункциональное).

  • NAME - название системы. Если в истории задействовано несколько систем, то они описываются по очереди, перед каждой группой требований тогда вводится заголовок с наименованием конкретной системы.

  • 123 - номер проблемы в джире, имея который можно найти всю историю.

  • 01 - порядковый номер требования

Истории-энейблеры

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

Пример неудачной пользовательской истории-энейблера

Как владелец продукта, я хочу мигрировать базу данных заказов, чтобы поддерживать разные типы заказов.

Описание бизнес-предпосылок

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

Пример описания бизнес-предпосылок

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

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

Разработка через поведение

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

Для того чтобы справиться с возникшей проблемой, мы решили попробовать разработку через поведение, в оригинале — Behavior-driven development. ВDD - это набор практик, помогающих резко сократить количество дефектов за счет трехстороннего анализа дизайна представителями бизнеса, разработки и тестирования, а также использования разработки через тестирование, в оригинале — Test-driven development. Практики эти очень интересные, и я рекомендую их отдельно изучить. В этой же статье рассмотрим только часть BDD, связанную с анализом сценариев и описанием пользовательских историй.

Смысл подхода заключается в том, чтобы в понятной для всех сторон форме описать поведение системы. Фокус именно на поведении, а не на требованиях и бэкграунде позволяет определить те редкие сценарии, которые упускались ранее при обычном анализе и рефайменте. Работает это довольно просто: сначала аналитик (владелец продукта или член команды разработки, анализирующий историю) определяет бизнес-правила, которые применимы к описываемой функциональности. После чего покрывает эти правила примерами использования. А затем организует встречу трех друзей (Tres Amigos), на которой каждый из представителей бизнеса, разработки и тестирования оценивает правила и примеры со своей точки зрения. Владелец продукта убеждается, что все бизнес- потребности закрыты или отклоняет примеры с заведомо нерелевантными бизнесу сценариями. Разработчик убеждается в том, что все примеры применимы к текущей реализации системы и выбранному решению. Тестировщик же накидывает самые неочевидные сценарии, тем самым избавляя историю от пробелов в дизайне.

Три друга. Церемония по выявлению поведения системы.
Три друга. Церемония по выявлению поведения системы.

В итоге в структуру пользовательской истории добавляется новый раздел с системным поведением.

Пример пользовательской истории с системным поведением

Бизнес-бэкграунд

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

Системное поведение

BR.NAME.123.01 Система позволяет сменить адрес, если заказ еще не в доставке

  • EX.NAME123.01.01 Тот, в котором пользователь успешно меняет адрес, если заказ еще не у курьера

  • EX.NAME123.01.02 Тот, в котором пользователь не может изменить адрес, так как заказ уже у курьера

BR.NAME.123.01 Новый адрес должен быть в зоне доставки

  • EX.NAME123.02.01 Тот, в котором система разрешает изменить адрес, так как он в зоне доставки

  • EX.NAME123.02.02 Тот, в котором система запрещает изменение адреса, так как он вне зоны доставки

 Системный дизайн

FR.NAME.123.01 Система должна предоставлять возможность пользователю изменять свой почтовый адрес

  • Новая кнопка "сменить адрес доставки" должна быть добавлена на форме информации о пользователе 

FR.NAME.123.02 Система должна предоставлять возможность хранить адрес доставки заказа отдельно от текущего адреса пользователя

  • Новый атрибут "адрес" должен быть добавлен на объектный тип Заказ

  • Когда курьер забирает заказ, система должна копировать адрес пользователя в Заказ.адрес.

 FR.NAME.123.XX ...*

*После встречи трех друзей новые сценарии поведения покрываются требованиями.

 Критерии приемки

  • Пользователь может изменить свой почтовый адрес

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

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

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

Ориентирование на клиента

Новая структура зарекомендовала себя, и мы решили поделиться результатами применения нового подхода с другими командами в проекте на ближайшем общем аджайл-митапе. Опыт использования нового формата был представлен в рамках доклада о культуре рефаймента и ее развитии. В результате оживленной дискуссии, один из наших швейцарских коллег указал на очевидный минус такого подхода — слабую реализацию принципа ориентирования на клиента (customer centricity). Подобная структура истории, хоть и вполне выполняет свои функции, не имеет описания со стороны клиента. Не показывает его проблемы, боли и желания. И как следствие, на дает разработчику возможности понять особенности ситуации глазами пользователя.

Чтобы устранить проблему слабого описания со стороны клиента необходимо "вернуться на круги своя" и добавить в существующий формат изначально удаленное нами классическое описание пользовательской истории.

Пример истории с учетом ориентирования на клиента

История использования

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

Бизнес-бэкграунд

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

Системное поведение

BR.NAME.123.01 Система позволяет сменить адрес, если заказ еще не в доставке

  • EX.NAME123.01.01 Тот, в котором пользователь успешно меняет адрес, если заказ еще не у курьера

  • EX.NAME123.01.02 Тот, в котором пользователь не может изменить адрес, так как заказ уже у курьера

BR.NAME.123.01 Новый адрес должен быть в зоне доставки

  • EX.NAME123.02.01 Тот, в котором система разрешает изменить адрес, так как он в зоне доставки

  • EX.NAME123.02.02 Тот, в котором система запрещает изменение адреса, так как он вне зоны доставки  

Системный дизайн

FR.NAME.123.01 Система должна предоставлять возможность пользователю изменять свой почтовый адрес

  • Новая кнопка "сменить адрес доставки" должна быть добавлена на форме информации о пользователе

FR.NAME.123.02 Система должна предоставлять возможность хранить адрес доставки заказа отдельно от текущего адреса пользователя

  • Новый аттрибут "адрес" должен быть добавлен на объектный тип Заказ

  • Когда курьер забирает заказ система должна копировать адрес пользователя в Заказ.адрес.

FR.NAME.123.XX ...

Критерии приемки

  • Пользователь может изменить свой почтовый адрес

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

Выводы

За все время экспериментов с форматом пользовательских историй я сделал для себя несколько выводов.

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

Во-вторых, поддержка команды — критична. История является артефактом многих командных процессов Скрама. Поэтому прежде, чем что-то менять, заручитесь поддержкой остальных членов команды. У каждого человека должно быть понимание, зачем в процессы и артефакты вносятся те или иные изменения.

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

Желаю всем успехов в написании пользовательских историй! Если у вашей команды есть интересные практики и техники описания — буду рад увидеть их в комментариях.

Комментарии (3)


  1. Vzaripova
    29.12.2021 19:10

    Спасибо за то что поделились опытом.

    У меня есть два вопроса:

    Хотелось бы уточнить что мешает совместить раздел Системного поведения и критериев приёмки? По сути, если проблема лежала именно в сфере "обнаружили баги" и это очевидно "баги постановки" это говорит о том что критерии приёмки недостаточно прописаны. В приведённом вами примере критерии приёмки выполняют роль некоего рудимента, о котором необходимо помнить, но в который никто не смотрит, поскольку все очевидно из BR и FR.

    И ещё вопрос: ведёте ли вы отдельно базу BR и FR? Опять же из текущего примера не совсем понятно, поскольку везде используется один номер задачи 123, что оставляет за кадром проблему выявления неполноты требований, их перекрестного влияния и разрастания такой базы до размеров, когда с ней становится невозможно работать.


    1. voodoo113 Автор
      29.12.2021 19:33

      Всегда пожалуйста.

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

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

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

      Что касается базы данных BR и FR. Мы практикуем создание матрицы прослеживаемости (traceability matrix) для каждой истории. В Enterprise Architect (инструмент для моделирования) на каждый спринт мы создаем несколько диаграм, по числу пользовательских историй. На каждой из диаграм на матрице отображаются отдельными элементами требования и артефакты. Матрица состоит из столбцов и строк. Столбцы описывают:

      • бизнес-требования

      • функциональные и (не-) требования

      • артефакты: активности, которые были изменены из-за реализации требования. Могут быть также интерфейсы, объекты дата-модели и так далее. Все они есть на других диаграммах как часть технической документации

      • тесты: названия или ссылки на конфлюенс с конкретными геркин-сценариями

      Строками описываются разные системы. Мы стараемся делить стори, в которых затронуты несколько систем, но не всегда это имеет смысл. Если история влияет на несколько систем, то они описываются в разных строчках.

      Между элементами диаграммы проставляются ассоциации. Они помогают понять какое бизнес требование породило те или иные функциональные требования, и как функциональные требования повлияли на конкретные активности или данные.

      Соответственно, если элемент из колонки слева не имеет связи хотя бы на один элемент из следующей колонки - то появляется гэп, пробел в требованиях или реализации.

      Enterprise Architect также позволяет находить в каких спринтах и из-за каких требований менялась активность на диаграмме. Очень удобно.


  1. YgReEk
    30.12.2021 16:16

    Мне кажется, или вы начали модифицировать User story, а в итоге реализовали Use case?