User Stories
User story — це короткий опис потреби з погляду користувача, написаний, щоб почати розмову, а не замінити її. Шаблон — найменш важлива частина; справжня навичка полягає в нарізанні роботи так, щоб кожна історія давала користувачеві щось справді придатне до використання. На цій сторінці — три C, критерії приймання, шість способів розділити історію, story mapping, spike та призначення story points.
- Походження
- Extreme Programming
- Три C
- Card · Conversation · Confirmation
- Перевірка якості
- INVEST
Заготовка для розмови
Звичний шаблон — «Як [роль], я хочу [можливість], щоб [вигода]» — корисна заготовка, але сам собою він не є user story. В початковій ідеї його взагалі не було: історії з’явилися в Extreme Programming як картки з одним реченням, а шаблон вигадали пізніше в лондонській компанії Connextra як внутрішній стиль, який випадково розійшовся. Ви маєте право ним не користуватися.
Рон Джеффріс описав, чим історія є насправді, трьома словами: Card (короткий письмовий нагадувач), Conversation (де з’ясовується справжня вимога) і Confirmation (як ви зрозумієте, що зроблено). Потрібні всі три. Картка без розмови — це погано написана специфікація; розмова без підтвердження — це суперечка, що чекає на огляд.
Це формулювання має практичний наслідок. Історія навмисно недоописана: у ній рівно стільки, щоб пам’ятати, що і з ким обговорити. Команда, яка сприймає картку як повну специфікацію, винайшла заново документ вимог — з тією додатковою вадою, що тепер він має вміститися на картці.
Одна альтернатива, варта знання, — job story: «Коли [ситуація], я хочу [мотивація], щоб [очікуваний результат]». Вона замінює персону тригером, і це чесніше, коли ви не знаєте точно, хто користувач, зате точно знаєте, коли виникає потреба. Жоден формат не кращий за інший; обидва кращі за картку «Покращення пошуку».
Критерії приймання — третє C
Третє C пропускають найчастіше. Критерії приймання — це не бюрократія, а відповідь на питання «як ми зрозуміємо, що готово?», узгоджена до початку роботи, а не з’ясована в суперечці на огляді. Це також найдешевша можлива профілактика багів: більшість того, що тестувальник знаходить за першу годину, — це випадки, які ніхто не обговорював.
Два формати покривають майже все. Чекліст — це простий список умов, які мають виконуватися: швидко пишеться, легко читається і є правильним варіантом за замовчуванням для простих історій. Given/When/Then описує початковий стан, дію та очікуваний результат, змушує назвати передумову і безпосередньо перекладається в автоматизований тест.
Тримайте їх небагато. Три-сім критеріїв на історію — норма; п’ятнадцять означає, що історія насправді є двома-трьома, а список критеріїв став тим поділом, якого ви ще не зробили. Критерії також належать історії, а не Definition of Done: у Definition of Done лежить те, що істинне для кожної історії (протестовано, переглянуто, задеплоєно), у критеріях — те, що істинне лише для цієї.
Ріжте вертикально, а не горизонтально
Це єдина навичка, від якої залежить, чи допоможуть історії взагалі. Вертикальний зріз проходить крізь усі шари — інтерфейс, логіка, сховище — і дає користувачеві щось, що він може зробити. Горизонтальний ріже за технічними шарами й не дає нічого придатного, доки не завершиться останній.
Горизонтальний поділ спокусливий, бо збігається з тим, як часто організовані команди, і відчувається ефективним: людина з бази даних робить частину з базою даних, один раз і як слід. Він програє з причини, що не має стосунку до ефективності: ніщо не придатне до релізу, доки не завершено кожен шар, тож увесь зворотний зв’язок приходить наприкінці, до того жодну оцінку неможливо спростувати, а зрив на останньому шарі знецінює всі шари під ним.
Шість способів розділити завелику історію
| Ділити за | Приклад |
|---|---|
| Кроком сценарію | «Оформити замовлення» стає: ввести адресу → обрати доставку → оплатити → лист-підтвердження. Спершу щасливий шлях; кожен наступний крок — окрема історія. |
| Бізнес-правилом | Знижки: підтримати простий відсоток зараз; обсягові рівні, терміни дії та правила складання стають ще трьома історіями. |
| Варіацією даних | Імпорт: спершу CSV, потім Excel, потім банківський формат фіксованої ширини. Той самий флоу, по одному формату. |
| Складністю інтерфейсу | Проста робоча форма виходить зараз; версія з перетягуванням і живим прев’ю — окрема історія з власною цінністю. |
| Відкладеною якістю | Зробити звіт правильним на 100 рядках зараз; «показує 100 тис. рядків менш ніж за дві секунди» — окрема вимірювана історія. |
| Операціями над об’єктом | Не «керувати збереженими пошуками», а створити, потім переглянути, потім перейменувати, потім видалити. Кожна корисна окремо. |
Story mapping — побачити ціле
У пласкому беклозі з добре написаних історій є одна структурна вада: він губить форму користувацького шляху. Прочитайте п’ятдесят упорядкованих карток — і ви не скажете, чи складаються верхні двадцять у щось, що людина може довести до кінця. Story mapping Джеффа Паттона розв’язує це, розкладаючи історії у двох вимірах замість одного.
Угорі йде хребет: послідовність того, що робить користувач, зліва направо, у порядку виконання — переглянути, обрати, оплатити, відстежити. Під кожним пунктом висить колонка історій, упорядкованих згори вниз за необхідністю. Далі карту ріжуть горизонтально: верхній рядок через усі колонки — це найтонша версія шляху, яка працює від початку до кінця (walking skeleton), а кожен рядок нижче — пізніший реліз, що робить той самий шлях кращим.
Цінність — у тому, що форма робить очевидним. Прогалина в хребті — це крок, про який ніхто не подумав. Колонка з п’ятнадцятьма картками поруч із колонками по дві — це місце, де команда вклалася надміру. А перший реліз, обраний як верхній рядок, гарантовано придатний до використання, тоді як перший реліз із верхніх двадцяти пунктів плаского списку — зазвичай ні.
INVEST — чекліст, а не статут
| Літера | Означає | Порушено, коли |
|---|---|---|
| Independent | Можна зробити в будь-якому порядку | Не можна почати, доки не завершено три інші |
| Negotiable | «Як» ще відкрите | Картка диктує реалізацію |
| Valuable | Користувач чи бізнес щось отримує | «Налаштувати схему бази даних» |
| Estimable | Команда може оцінити обсяг | Забагато невідомого — потрібен спершу spike |
| Small | Вільно вміщається в одну ітерацію | Її вже двічі переносили |
| Testable | «Готово» однозначне | «Зробити застосунок інтуїтивним» |
INVEST — це тест на «запах», а не шлагбаум. Історія, що не проходить за однією літерою, варта другого погляду, а не автоматичної відмови: залежні історії існують, і іноді чесна відповідь — зробити їх по черзі. Літера, яку варто сприймати серйозно завжди, — Testable: якщо ніхто не може сказати, що доведе завершеність, переписування решти п’яти не врятує.
Коли історію неможливо оцінити: spike
Іноді команда справді не може оцінити історію, бо невідоме є технічним: чи витримає ця бібліотека наш обсяг, чи вміє API постачальника часткові повернення взагалі. Відповідь — spike: окремий обмежений у часі шматок дослідження, результатом якого є знання, а не робочий софт. Два дні, письмова відповідь — і початкова історія стає оцінюваною.
Два правила тримають spike чесними. Часовий бокс фіксується наперед і не подовжується: якщо двох днів не вистачило, це вже сам собою висновок. І spike має завершитися записаним рішенням, інакше те саме питання наступного кварталу досліджуватиме заново той, кому дістанеться код.
Points і те, для чого вони не потрібні
Story points — це відносний розмір, а не тривалість. Команда порівнює історію з тими, які вже зробила: ця приблизно вдвічі більша за ту, — і число несе в собі складність, невизначеність і обсяг роботи разом. Абстрактну одиницю використовують саме тому, що її неможливо прочитати як зобов’язання: три поінти не є трьома днями ні для кого.
Velocity — кількість поінтів за ітерацію — це вхідні дані для прогнозу тієї команди, яка їх зробила, і нічого більше. Вона не порівнюється між командами, бо шкала довільна й локальна. Вона не є мірою продуктивності, бо це власне число тієї команди, що оцінює: будь-яка команда, яку міряють по velocity, здатна подвоїти її за два спринти, не змінивши того, що постачає, — і кожна команда рано чи пізно це помічає.
Чесно буде сказати й те, що чимало досвідчених команд узагалі перестають оцінювати. Щойно історії стабільно нарізані малими, підрахунок їхньої кількості прогнозує приблизно так само добре, як сума поінтів, а година рефайнменту повертається в поділ замість суперечок, три це чи п’ять. Оцінювання — це засіб; якщо воно не покращує жодного рішення, це просто звичка.
Як це виявляється в реальній поставці
Найшвидший спосіб зрозуміти, чи пише команда справжні історії, — відкрити спринт і прочитати назви. Якщо там «Бекенд для пошуку», «UI пошуку», «Індексація пошуку», команда ріже горизонтально й наприкінці спринту виявить, що пошук не працює. Якщо там «Знайти товар за точною назвою», це можна віддати окремо — і все наступне буде покращенням, а не передумовою.
Друга діагностика — хто їх написав. Історії, повністю написані одним аналітиком і передані команді, за самою конструкцією пропустили Conversation, хоч якими б бездоганними були картки. Формат зберігся; механізм — ні.
Де вони вироджуються
- Шаблон, натягнутий на технічні задачі: «Як розробник, я хочу міграцію бази даних» нікого не обманює.
- Картки, розписані до дрібниць, — розмова так і не відбувається.
- Викинута частина «щоб» — зникає єдина причина, з якої історію можна обговорювати.
- Немає критеріїв приймання — «готово» узгоджують на огляді під тиском часу.
- П’ятнадцять критеріїв приймання на одній картці — це поділ, якого ніхто не зробив.
- Story points як показник продуктивності — це роздуває оцінки, а не результат.
- Spike без часового боксу й без записаного висновку перетворюються на побічні проєкти.
Коли це застосовувати
Застосовуйте, коли
- Роботу можна описати через те, що користувач зможе зробити.
- Команда й замовник справді можуть говорити — розмова і є результатом.
- Ви можете випускати малі шматки й вчитися з них.
- Вимоги змінюватимуться, тож гнучкий формат кращий за фіксовану специфікацію.
Уникайте, коли
- У роботи немає видимого користувачеві результату — оновлення бібліотеки це задача, а не історія.
- Регулятор вимагає натомість формальну підписану специфікацію.
- Немає з ким провести розмову — лишається найслабша третина формату.
- Шаблон застосовують заради галочки в процесі, а не щоб прояснити потребу.
Було корисно?
Поділіться з тим, хто працює над тією ж задачею.