User story и критерии приёмки
Как одна фраза из трёх частей превращает расплывчатое «нужен личный кабинет» в задачу, которую можно оценить, взять в спринт и честно проверить.
User story (пользовательская история) — короткое описание требования глазами того, кому оно нужно: кто пользователь, что он хочет сделать и какую ценность из этого получит. Это не спецификация на 40 страниц, а обещание разговора: карточка напоминает команде обсудить детали, а не заменяет обсуждение.
Зачем истории, если можно просто написать «сделать кнопку»
Задача «Добавить кнопку экспорта в отчёты» выглядит понятной ровно до момента, когда разработчик садится её делать. Экспорт куда — в CSV, Excel, PDF? Весь отчёт или только видимые строки? Что если строк миллион? Кому вообще эта кнопка нужна? Ответов в задаче нет, и дальше происходит одно из двух: разработчик угадывает (и в половине случаев угадывает мимо) или идёт спрашивать — но спрашивает уже посреди спринта, когда время потрачено.
Формулировка через историю заставляет автора задачи назвать человека и его выгоду. И тут внезапно выясняется, что кнопка нужна бухгалтеру, чтобы отдать выгрузку в 1С, — значит, нужен именно CSV с конкретными колонками и точкой с запятой в качестве разделителя, а PDF никому не сдался. Один вопрос «зачем» сэкономил неделю.
Вторая причина — приоритизация. Бэклог из пятидесяти «сделать кнопку» невозможно отсортировать: непонятно, что важнее. Бэклог из пятидесяти историй с явной ценностью сортируется за полчаса.
Формула
Канонический шаблон, придуманный в команде Extreme Programming и с тех пор ставший индустриальным стандартом, выглядит так:
Как <роль>,
я хочу <действие>,
чтобы <ценность>.
Три части — три разных вопроса, и каждая работает по-своему:
- Роль — не «пользователь», а конкретный типаж: «новый пользователь», «администратор магазина», «курьер в приложении». Абстрактный «пользователь» — красный флаг: он значит, что автор не думал о том, кто это.
- Действие — что человек хочет сделать в системе. Именно человек, а не система: «я хочу отменить заказ», а не «система должна отменять заказ».
- Ценность — зачем ему это. Самая ценная и самая часто пропускаемая часть. Если ценность не формулируется — возможно, задача не нужна.
Живой пример из интернет-магазина:
Как покупатель, оформивший заказ,
я хочу отменить его до момента отправки,
чтобы не платить за возврат и не ждать курьера зря.
Обратите внимание: из ценности сразу вытекает граница задачи. «До момента отправки» — значит, после отправки кнопки отмены быть не должно, а нужен уже другой сценарий (возврат). Это выяснилось из одной фразы, без ТЗ.
INVEST: шесть проверок на вменяемость истории
INVEST — мнемоника Билла Уэйка. Это чек-лист, по которому историю прогоняют перед тем, как брать в работу.
| Буква | Что значит | Как проверить |
| I — Independent | Независимая | Историю можно сделать отдельно, не дожидаясь трёх соседних. Если задачи связаны цепочкой «сначала А, потом Б, потом В» — их порядок в бэклоге жёстко зафиксирован, и планировать нечего. |
| N — Negotiable | Обсуждаемая | История описывает потребность, а не готовое решение. «Хочу выпадающий список с автодополнением» — не история, а дизайн, навязанный команде. |
| V — Valuable | Ценная | Ценность видна пользователю или бизнесу. «Отрефакторить сервис заказов» ценна разработчикам — такое лучше оформлять как техдолг, а не маскировать под историю. |
| E — Estimable | Оцениваемая | Команда может сказать «примерно столько». Если в ответ звучит «понятия не имеем» — не хватает информации или нужен отдельный research-спайк. |
| S — Small | Маленькая | Влезает в спринт с запасом. Хорошая планка: не больше пары дней работы на историю. |
| T — Testable | Проверяемая | Есть способ доказать, что сделано. Отсюда напрямую растут критерии приёмки. |
INVEST — не бюрократический ритуал, а быстрый фильтр. На груминге по нему проходятся за 20 секунд, и «эта история не Small» — совершенно нормальный вердикт, после которого историю режут на две.
Критерии приёмки: Given / When / Then
Критерии приёмки (acceptance criteria) — список условий, при выполнении которых история считается сделанной с точки зрения заказчика. Это ответ на вопрос «как мы поймём, что получилось».
Самый удобный формат — сценарии в стиле Given/When/Then (он же Gherkin, язык из BDD — Behavior-Driven Development):
- Given — исходное состояние («дано»);
- When — действие пользователя («когда»);
- Then — ожидаемый результат («тогда»).
Для нашей истории с отменой заказа критерии выглядят так:
Сценарий 1: отмена до отправки
Дано: заказ №1042 в статусе «Оплачен», не передан в доставку
Когда: покупатель нажимает «Отменить заказ» и подтверждает
Тогда: статус меняется на «Отменён»,
деньги ставятся в очередь на возврат,
покупателю уходит письмо об отмене
Сценарий 2: отмена после отправки невозможна
Дано: заказ №1042 в статусе «Передан курьеру»
Когда: покупатель открывает страницу заказа
Тогда: кнопки «Отменить заказ» нет,
показана ссылка «Оформить возврат»
Сценарий 3: повторная отмена
Дано: заказ №1042 уже в статусе «Отменён»
Когда: покупатель повторно отправляет запрос на отмену
Тогда: статус не меняется, второе письмо не отправляется
Три сценария — и половина будущих багов уже обсуждена на берегу. Сценарий 3 (повторный клик, гонка запросов) — классическая дыра, которую в формате «просто список требований» забывают, а в формате Given/When/Then он напрашивается сам.
Важная деталь: критерии приёмки пишет не тестировщик в одиночку и не аналитик в вакууме. Их формулируют вместе — владелец продукта приносит намерение, разработчик приносит вопросы про краевые случаи, тестировщик приносит подозрения. Эта встреча на троих в Agile-мире называется Three Amigos.
Плохая история и хорошая
Смотрим на реальную карточку, какие приносят в бэклог чаще всего:
ПЛОХО
Заголовок: Личный кабинет
Описание: Нужен личный кабинет как у конкурентов.
Сделать красиво. Срочно!
Оценка: ???
Что здесь не так: нет роли (кто именно и что там делает?), нет ценности (что человек не может сделать сегодня?), нет границ («личный кабинет» — это месяцы работы, не история), нет ни одного проверяемого условия. Слово «красиво» непроверяемо в принципе, а «срочно» — это не приоритет, это эмоция.
Та же потребность, разложенная нормально:
ХОРОШО
Заголовок: История заказов в личном кабинете
Как постоянный покупатель,
я хочу видеть список своих прошлых заказов с их статусами,
чтобы повторить покупку и не искать письмо в почте.
Критерии приёмки:
Дано: покупатель авторизован и у него есть 3 заказа
Когда: он открывает раздел «Мои заказы»
Тогда: заказы показаны от новых к старым,
у каждого — дата, сумма, статус, кнопка «Повторить»
Дано: у покупателя нет ни одного заказа
Когда: он открывает раздел «Мои заказы»
Тогда: показан пустой экран с текстом и ссылкой в каталог
Дано: заказов больше 20
Когда: покупатель прокручивает список вниз
Тогда: подгружается следующая страница по 20 штук
Вне рамок: отмена и возврат заказа (отдельные истории)
Оценка: 5
Разница не в объёме текста — хорошая карточка не длиннее плохой. Разница в том, что по ней можно начать работать сегодня, не назначая совещание. И отдельная строчка «вне рамок» — недооценённый приём: она защищает от расползания задачи прямо посреди спринта.
Как это работает
История живёт по циклу «три C» (формулировка Рона Джеффриса):
- Card (карточка) — короткий текст истории. Специально короткий: он должен помещаться на стикер, чтобы никто не соблазнился написать туда ТЗ.
- Conversation (разговор) — обсуждение деталей с владельцем продукта. Основная работа происходит здесь, а не в тексте.
- Confirmation (подтверждение) — критерии приёмки, зафиксированные по итогам разговора. Это то, что превращает договорённость в проверяемый факт.
Если история слишком большая, её называют эпиком (epic) и режут. Режут не по слоям («сделать бэкенд» + «сделать фронтенд» — так нельзя, ни один кусок сам по себе не даёт ценности), а по сценариям: сначала показ списка заказов, потом фильтры, потом повтор заказа. Каждый кусок можно выкатить и получить обратную связь.
И ещё: истории покрывают не всё. Требования вроде «страница открывается меньше чем за 2 секунды на 3G» или «интерфейс доступен с клавиатуры» — это нефункциональные требования. Их не размазывают по историям, а выносят в Definition of Done, о чём будет отдельный урок.
Частые ошибки
- Роль всегда «пользователь». Если во всех историях подряд стоит «Как пользователь…», формула превратилась в ритуал. Роль должна различать людей с разными потребностями: гость и постоянный покупатель хотят разного.
- Ценность-заглушка. «…чтобы пользоваться функцией отмены заказа» — это не ценность, это пересказ действия другими словами. Признак: если убрать третью часть, смысл не изменится, — значит, её и не было.
- История как техзадание. В карточку вписывают названия таблиц, эндпоинтов и имена CSS-классов. Тогда исчезает N из INVEST: команде нечего обсуждать, ей выдали решение. Как делать — решает команда, что и зачем — владелец продукта.
- Критерии приёмки вместо тест-кейсов. Обратная крайность: 30 сценариев Given/When/Then на одну историю, включая проверку каждого поля формы. Критерии — это ключевые условия приёмки, а не полный тест-план. Пять-семь сценариев — потолок; больше — сигнал, что историю пора резать.
- Критерии дописывают после разработки. Тогда они превращаются в описание того, что успели сделать, и теряют весь смысл. Критерии — это договор до, а не протокол после.
- Непроверяемые формулировки. «Удобно», «быстро», «интуитивно понятно» проверить нельзя. «Быстро» превращается в «ответ приходит быстрее 300 мс на 95-м перцентиле» — и вот это уже критерий.
Итоги
- User story описывает потребность человека, а не решение: Как <роль>, я хочу <действие>, чтобы <ценность>. Третья часть — самая важная и самая часто выбрасываемая.
- История — это приглашение к разговору (три C: Card, Conversation, Confirmation), а не документ, заменяющий разговор.
- INVEST — быстрый фильтр: независимая, обсуждаемая, ценная, оцениваемая, маленькая, проверяемая.
- Критерии приёмки в формате Given/When/Then делают историю проверяемой и вытаскивают краевые случаи до того, как они станут багами.
- Слишком большая история — это эпик; резать его надо по сценариям ценности, а не по слоям архитектуры.
- Нефункциональные требования (скорость, доступность, безопасность) живут не в историях, а в Definition of Done.