User Story: полный гайд по написанию без ошибок

Материал подготовлен в рамках курса «Системный аналитик»

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

Я Tech Lead и руководитель направления Java | Kotlin разработки в FinTech, а также преподаю на курсах разработки и архитектуры в OTUS. Через мои руки прошли десятки проектов, и я точно знаю: корень большинства проблем не в кривых руках разработчиков, а в том, как была сформулирована пользовательская история. Точнее — как она не была сформулирована.

Мы разберём живые примеры, вспомним реальные кейсы, посмотрим на типичные грабли и соберём работающие Best Practices, которые применяют лучшие команды. И да, я покажу пару схем — они помогут увидеть систему, а не просто набор советов.

User Story — это не три строчки по шаблону

Шаблон все знают наизусть: «Как <роль>, я хочу <действие>, чтобы <ценность>». Загвоздка в том, что многие команды воспринимают его как ритуальную формулу: заполнил три поля — история готова. На деле эта конструкция лишь каркас. Настоящая User Story начинается с разговора.

Когда я только начинал работать с требованиями, я сам попадал в ловушку «идеальной формулировки». У нас была история:

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

Звучит отлично, правда? Мы реализовали за два дня. А через неделю получили шквал звонков от клиентов, которые пытались оплатить покупки, а терминал говорил «недостаточно средств». Оказалось, мы показали баланс «на счету», а не «доступный для трат». Разница — заблокированные суммы, pending‑транзакции, суточные лимиты. Всё это не было проговорено в критериях приёмки. Мы сделали ровно то, что написано, и получили ровно то, что не нужно бизнесу.

С тех пор я держу в голове правило: User Story — это обещание о будущем разговоре, а не техническое задание в миниатюре. И именно с этого понимания начинается путь к зрелым историям.

Типичные ошибки, которые переезжают из проекта в проект

Давайте разберем частые ошибки.

Ошибка 1. История без контекста. 

Команда получает: «Как пользователь, я хочу загрузить документы». Всё. Ни слова о том, зачем это нужно, какие форматы, есть ли ограничения по размеру, требуется ли предпросмотр, куда эти документы потом денутся. Разработчики дорисовывают картину сами, и в 90% случаев — мимо.

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

Ошибка 2. Гигантские истории, которые живут неделями. 

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

Ошибка 3. Отсутствие критериев приёмки. 

История: «Как клиент, я хочу восстановить пароль, чтобы войти в систему». Вроде понятно. Но что делать, если пользователь запросил сброс дважды? Как долго живёт ссылка? Инвалидируется ли предыдущий токен? Если эти вопросы не снять на этапе написания истории, они вылезут в продакшене. Я требую, чтобы каждая история имела Acceptance Criteria, записанные в формате Given/When/Then.

Ошибка 4. Желание уместить всё в одну историю ради «полной ценности для пользователя».

Звучит благородно, но приводит к тому, что история становится неподъёмной и непроверяемой. Я за вертикальные срезы, но тонкие. Лучше три истории на один экран, чем одна — на три экрана.

Ошибка 5. Игнорирование нефункциональных требований. 

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

Вот тут наглядно помогают схемы — они дисциплинируют мышление. Я подготовил первую: она показывает, как сырая идея превращается в зрелую User Story через серию уточняющих шагов (рис. 1).

Рис 1. Процесс уточнения User Story от идеи до готового элемента бэклога

Рис 1. Процесс уточнения User Story от идеи до готового элемента бэклога

Любая User Story начинается не с шаблона, а с сырой идеи, которую кто‑то принёс. Первый же вопрос, который я задаю себе или продакту: «Понятна ли ценность?» Если нет — не иду дальше, пока не выясню «Зачем? Кто? Почему?». Потому что без ответа на эти три вопроса история рискует оказаться решением несуществующей проблемы.

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

Когда INVEST пройден, наступает этап, который пропускают чаще всего: явное определение Acceptance Criteria в формате Given/When/Then и добавление нефункциональных требований — производительность, безопасность, ограничения. Только после этого история попадает в бэклог как «готовая». Схема — это не бюрократия, а страховка от иллюзии понятности. Она заставляет остановиться и задать нужные вопросы до того, как разработчик напишет первую строчку кода.

Best Practices, которые я подсмотрел у сильных команд

Я много общаюсь с коллегами из других компаний, смотрю, как устроены процессы на курсах OTUS, и собираю практики, которые реально работают.

  1. Три амиго (Three Amigos). Перед взятием истории в спринт аналитик, разработчик и тестировщик вместе за 10–15 минут проходят по ней и синхронизируют понимание. Это убирает эффект «я думал, ты другое имел в виду». Я внедрял такую практику в одной финтех‑команде, и количество дефектов, связанных с недопониманием требований, упало примерно на 40% за три месяца.

  2. Спецификация по примерам (Specification by Example). Чем сложнее логика, тем полезнее прямо в критериях приёмки привести конкретный пример данных на входе и ожидаемый результат. Например, не просто «система отклоняет перевод при превышении лимита», а «клиент с дневным лимитом 100 000 ₽ пытается отправить 101 000 ₽, система показывает ошибку „Превышен суточный лимит“„. Это разом снимает споры „а какой именно лимит, а какая ошибка“.“»

  3. INVEST как фильтр, а не как ритуал. Я применяю его неформально. Independent? Если две истории жёстко связаны, я не буду их насильно разделять, но пойму, что это риск. Negotiable? История не должна читаться как готовая инструкция к реализации — оставьте разработчику пространство для решений. Valuable — самый частый провал: если ценность нельзя объяснить одной фразой, историю нужно переписать.

  4. DoR (Definition of Ready). В ряде команд я настоял на простом чек‑листе: перед тем как история попадёт в спринт, у неё должны быть заголовок, роль, действие, ценность, Acceptance Criteria, оценка, отсутствие внешних блокировок. Это дисциплинирует, и со временем перестаёт быть бюрократией и становится привычкой.

Урок, который стоил денег: реальная история

В 2012 году компания BBC понесла серьёзные репутационные и финансовые потери из‑за провала проекта Digital Media Initiative (DMI). Это была амбициозная программа по созданию единой платформы для управления всем медиаконтентом: от съёмок до архива. Бюджет превысил 100 миллионов фунтов, проект закрыли, не получив работающей системы.

В независимом отчёте (National Audit Office, 2014) среди ключевых причин назывались: отсутствие чётких приоритетов, размытые требования и слабая связь между бизнес‑целями и тем, что реально разрабатывалось. Другими словами, команда годами реализовывала «истории», которые были слишком большими, не имели проверяемых критериев успеха и не подвергались жёсткой приоритизации. Это классическая ловушка «мы пишем User Story, но не проверяем, приносят ли они ценность прямо сейчас».

После краха DMI BBC кардинально пересмотрела подход к управлению требованиями: в новых программах внедрили строгие стандарты приёмки, сократили длительность циклов обратной связи и перешли к поставке маленькими вертикальными срезами с обязательным подтверждением бизнес‑результата на каждом этапе. Это не спасло прошлые деньги, но уберегло следующие проекты.

Я вспоминаю эту историю каждый раз, когда слышу аргумент «давайте просто закодим, а требования додумаем». Недодуманная User Story может стать первой костяшкой в домино, которое обрушит весь проект.

Как выглядит зрелая User Story: живой пример

Приведу пример истории, которую как‑то обсуждал с командой, но в обезличенном виде:

Заголовок: Просмотр доступного баланса с учётом холдов.

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

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

AC1: отображение доступного баланса при нулевых холдах.
Дано: у клиента баланс 50 000 ₽, нет заблокированных средств.
Когда: он открывает главный экран.
Тогда: отображается сумма «Доступно 50 000,00 ₽».

AC2: отображение с учётом заблокированной суммы.
Дано: баланс 50 000 ₽, есть холд на 12 000 ₽.
Когда: клиент открывает главный экран.
Тогда: отображается «Доступно 38 000,00 ₽», а также показывается пояснение. «Заблокировано 12 000,00 ₽».

AC3: обновление холдов в реальном времени.
Дано: холд снят (например, покупка отменена).
Когда: клиент тянет экран вниз для обновления.
Тогда: доступный баланс увеличивается на сумму снятого холда в течение 2 секунд.

Нефункциональные требования:

  • Загрузка данных не должна превышать 1 секунду (p95).

  • Не кешировать данные более 30 секунд, чтобы не вводить клиента в заблуждение.

Видите разницу? Здесь не осталось пространства для интерпретаций. Разработчик понимает, ЧТО делать, тестировщик — КАК проверять, владелец продукта — КАКУЮ ценность мы поставим. Именно такие истории я называю «зрелыми».

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

Рис 2. Принципиальная схема зрелой User Story

Рис 2. Принципиальная схема зрелой User Story

На схеме видно, что зрелая история — это не только шаблон «Как, Я хочу, Чтобы», но ещё три обязательных слоя: проверка по INVEST, критерии приёмки с примерами и нефункциональные требования. Если хотя бы один слой отсутствует, история незрелая!

Заключение: не пишите «правильные» истории — создавайте зрелые

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

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

Если эта тема для вас актуальна и вы хотите не просто почитать, а системно прокачать навык работы с требованиями, приглашаю вас на открытые уроки в OTUS. Они пройдут в рамках курса «Системный аналитик». Мы разберём живые кейсы и покажем, как выстроить процесс, который не оставляет места для «я думал, вы другое имели в виду».

  • 5 мая в 20:00. «Как не допустить ошибок при написании пользовательских историй?». Записаться

  • 13 мая в 18:00. «Обзор нотации BPMN 2.0». Записаться

  • 19 мая в 20:00. «Диаграмма последовательности — швейцарский нож системного аналитика». Записаться

Участие бесплатное, нужно только зарегистрироваться.

Автор: sproshchaev

Источник

Оставить комментарий