Как писать user story: шаблон и 10 примеров с типовыми ошибками
User story — самый частый формат требований в командах, которые работают по Agile. Формулировка короткая, шаблон учится за пять минут, и именно поэтому истории пишут плохо: шаблон соблюдён, а разработчик всё равно приходит с вопросами.
Разберём, из чего состоит рабочая история, как к ней прикрутить критерии приёмки, и пройдём по десяти примерам «до и после» — с теми ошибками, которые ревьюер находит первыми.
Что такое user story и чем она не является
User story — это описание нужды пользователя, а не задание разработчику. Её смысл: зафиксировать, кому и зачем нужно изменение, чтобы команда могла обсуждать решение, а не угадывать намерение.
Отсюда два практических следствия:
- 💡 История — приглашение к разговору, а не спецификация целиком. Детали живут в критериях приёмки, макетах и правилах.
- ⚠️ История не должна диктовать реализацию. «Добавить чекбокс в модальное окно» — это уже решение, причём принятое в одиночку и без обсуждения.
Формально история задаёт три вещи: роль, действие, ценность. И держится на трёх «C»: Card (короткая формулировка), Conversation (обсуждение с командой), Confirmation (критерии приёмки, по которым проверяют результат). Если из трёх есть только первое — история не готова.
Шаблон
Классический шаблон Connextra — по нему пишут в большинстве команд:
Как <роль>, я хочу <действие или возможность>, чтобы <ценность>.
Пример на нашем сквозном кейсе — платная подписка на сервис:
Как подписчик, я хочу видеть дату следующего списания в личном кабинете, чтобы заранее пополнить карту и не потерять доступ.
Проверь три части по отдельности:
| Часть | Вопрос к себе | Плохо | Хорошо |
|---|---|---|---|
| Роль | Это конкретный тип пользователя? | «Как пользователь» | «Как подписчик с истёкшей картой» |
| Действие | Это нужда, а не UI-решение? | «Как пользователь, я хочу чекбокс» | «…я хочу отказаться от автопродления» |
| Ценность | Понятно, что человек получит? | «…чтобы было удобно» | «…чтобы не платить за месяц, который не буду использовать» |
🔤 Роль — не должность в компании, а тип пользователя в системе с отличающимся поведением. «Новый клиент» и «повторный клиент» — разные роли, если сценарий для них разный.
Критерии приёмки: где живёт вся конкретика
Сама история намеренно расплывчата. Точность в неё приносят критерии приёмки (acceptance criteria) — условия, при которых работу можно считать сделанной. Удобный формат — Given / When / Then:
- Given — исходное состояние («дана активная подписка с оплатой до 5 сентября»),
- When — действие («подписчик открывает страницу «Подписка»»),
- Then — ожидаемый результат («видит дату 5 сентября и сумму 490 ₽»).
К истории про дату списания:
Сценарий 1. Активная подписка
Given у подписчика активная подписка, следующее списание 5 сентября, сумма 490 ₽
When он открывает раздел «Подписка»
Then он видит «Следующее списание: 5 сентября, 490 ₽»
Сценарий 2. Автопродление отключено
Given подписчик отключил автопродление, доступ действует до 5 сентября
When он открывает раздел «Подписка»
Then он видит «Доступ до 5 сентября, продление отключено», без суммы
Сценарий 3. Данные о списании недоступны
Given сервис биллинга не отвечает
When подписчик открывает раздел «Подписка»
Then он видит статус подписки и сообщение «Дата следующего списания временно недоступна»
Третий сценарий — то, что новички забывают почти всегда. Счастливый путь описывают все; отличает хорошего аналитика привычка сразу спрашивать: «а если данных нет, ответ не пришёл, значение пустое?». Тестировщик всё равно задаст этот вопрос — лучше ответить на него до разработки, а не после.
Сколько критериев нужно: столько, чтобы разработчик и тестировщик поняли историю одинаково. Обычно это 2–5 сценариев. Если их получается пятнадцать — история слишком большая, её пора делить.
INVEST: быстрая проверка истории
Мнемоника, по которой историю проверяют перед взятием в спринт:
| Буква | Значит | Как проверить |
|---|---|---|
| Independent | Независима | Можно ли сделать её, не дожидаясь другой истории? |
| Negotiable | Обсуждаема | Осталось ли пространство для выбора решения? |
| Valuable | Ценна | Кто-то заметит результат? Кто именно? |
| Estimable | Оценима | Команда понимает объём или задаст пять вопросов? |
| Small | Мала | Влезает в один спринт (обычно — в 1–3 дня работы)? |
| Testable | Проверяема | Можно написать тест, дающий однозначный ответ «да/нет»? |
Самый частый провал — T. «Страница должна работать быстро» проверить нельзя. «Страница «Подписка» отвечает за 1 секунду для 95% запросов при 100 пользователях одновременно» — можно.
10 примеров: до и после
Ниже — формулировки, которые в разных вариациях встречаются в реальных бэклогах постоянно. Для каждой: как было, что не так, как переписать.
1. Роль-заглушка
До: Как пользователь, я хочу оплатить подписку, чтобы пользоваться сервисом. Диагноз: «Пользователь» — это все и никто. Новый клиент, продлевающий и вернувшийся после отмены проходят разные сценарии. После: Как новый клиент без сохранённой карты, я хочу оплатить первый месяц подписки, чтобы получить доступ сразу после оплаты.
2. Реализация вместо нужды
До: Как администратор, я хочу выпадающий список статусов в таблице заказов. Диагноз: Выбрано решение, а задача не названа. Может, нужен не список, а фильтр или массовое действие. После: Как оператор поддержки, я хочу менять статус заказа из списка заказов, чтобы не открывать карточку каждого заказа при разборе очереди.
3. Ценность «чтобы было удобно»
До: Как подписчик, я хочу видеть историю платежей, чтобы было удобнее. Диагноз: Ценность не названа — значит, приоритет обосновать нечем. После: Как подписчик, я хочу видеть историю платежей с суммами и чеками, чтобы отчитаться за расходы в бухгалтерии и проверить спорное списание.
4. Две истории в одной
До: Как подписчик, я хочу управлять подпиской: менять тариф, отключать автопродление и удалять карту. Диагноз: Три независимые нужды, три разных сценария и объём на несколько спринтов. После: Три отдельные истории. Одна — про смену тарифа, вторая — про автопродление, третья — про удаление карты. Каждую можно выпустить отдельно.
5. Нетестируемое требование
До: Как подписчик, я хочу, чтобы страница оплаты работала стабильно. Диагноз: «Стабильно» нельзя проверить, значит нельзя и принять работу. После: Как подписчик, я хочу получить понятный ответ об исходе оплаты не дольше 15 секунд, чтобы не платить второй раз из-за неопределённости. Критерий: Given платёж отправлен; When ответ банка не пришёл за 15 секунд; Then показывается статус «Платёж в обработке» и запрет на повторную оплату той же подписки.
6. Только счастливый путь
До: Как подписчик, я хочу оплатить подписку картой, чтобы получить доступ. Диагноз: Формально всё правильно, но обработка отказов не описана — и разработчик придумает её сам. После: История та же, но с критериями на отказ банка, недостаток средств, таймаут и повторное нажатие «Оплатить». Само правило простое: на каждый внешний вызов — минимум три сценария (успех, отказ, нет ответа).
7. История «для системы»
До: Как система, я хочу отправлять webhook в сервис аналитики. Диагноз: У системы нет нужд. Ценность есть у человека за системой — иначе задача бессмысленна. После: Как аналитик продукта, я хочу получать событие об успешной оплате в аналитику не позже минуты, чтобы считать конверсию за текущий день. (Это техническая задача — и её нормально оформить именно задачей, а не историей: не всё в бэклоге обязано притворяться user story.)
8. Гигантская история-эпик
До: Как клиент, я хочу личный кабинет. Диагноз: Это эпик на кварталы, оценить нельзя. После: Эпик «Личный кабинет» → истории: «увидеть статус подписки», «скачать чек», «отключить автопродление», «сменить карту». Признак нормального размера: историю можно закончить и показать за спринт.
9. Пропущены правила данных
До: Как клиент, я хочу ввести промокод при оплате, чтобы получить скидку. Диагноз: Ни слова о правилах: сколько кодов сразу, что делать с просроченным, суммируется ли скидка с другой акцией, учитывается ли регистр букв. После: История та же плюс явные правила: один код на заказ; истёкший код — ошибка «Срок действия кода истёк»; регистр не учитывается; скидка считается от цены без учёта других акций.
10. Ценность подменена мотивацией бизнеса
До: Как маркетолог, я хочу всплывающее окно со скидкой, чтобы увеличить конверсию. Диагноз: Названа цель бизнеса, а не нужда пользователя. Так рождаются интерфейсы, которые раздражают. После: Как сомневающийся посетитель, я хочу узнать, что первые блоки курса открыты бесплатно, чтобы попробовать без оплаты и решить, подходит ли мне формат. (Метрика конверсии остаётся — но живёт в описании гипотезы, а не в тексте истории.)
Общий знаменатель девяти ошибок из десяти: история описывает что сделать в интерфейсе, а не какую нужду закрыть. Как только формулировка съезжает в решение, обсуждение прекращается — команда обсуждает вёрстку, а не задачу.
Чек-лист перед сдачей истории
Прогони каждую историю по списку — это ровно те замечания, которые ревьюер оставит первыми:
- Роль — конкретный тип пользователя, не «пользователь».
- Действие — нужда, а не элемент интерфейса.
- Ценность отвечает на вопрос «что человек получит», без «чтобы было удобно».
- Есть критерии приёмки, и каждый проверяем однозначно.
- Описан не только успех: отказ, пустые данные, таймаут, повтор действия.
- Названы правила данных: обязательность, форматы, границы, регистр.
- История влезает в спринт; если нет — разбита.
- Нефункциональные ожидания (время ответа, объёмы) выражены числом.
- Разработчик может начать без дополнительных вопросов — проверь, спросив его.
Последний пункт — единственный честный тест качества. Пока историю не прочитал тот, кто будет её делать, ты не знаешь, понятна ли она.
Что почитать и куда двигаться дальше
User story не живёт в вакууме: она вырастает из процесса. Сначала ты понимаешь, как устроен процесс целиком, потом выделяешь в нём шаги, которые нужно поддержать системой, и только потом пишешь истории. Поэтому логичный порядок освоения — сначала схемы процессов, затем требования: как рисовать процесс, разобрано в статье «BPMN для начинающих». Если ты ещё выбираешь между двумя ролями и не уверен, кто из них вообще пишет истории, посмотри «Бизнес-аналитик vs системный аналитик» — там разделены зоны ответственности.
Дальше по теме требований стоит освоить три вещи: критерии приёмки в связке с тест-кейсами (взгляд QA), статусные модели (что происходит с сущностью между состояниями) и трассируемость «требование → диаграмма → спецификация». Ровно в этом порядке мы даём требования в курсе «Аналитик.Про»: ты пишешь истории на один сквозной проект, получаешь эталонный разбор и сравниваешь со своим — на практике эта обратная связь работает лучше, чем ещё десять прочитанных примеров.