МенеджментJunior

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 лежить те, що істинне для кожної історії (протестовано, переглянуто, задеплоєно), у критеріях — те, що істинне лише для цієї.

Ріжте вертикально, а не горизонтально

Це єдина навичка, від якої залежить, чи допоможуть історії взагалі. Вертикальний зріз проходить крізь усі шари — інтерфейс, логіка, сховище — і дає користувачеві щось, що він може зробити. Горизонтальний ріже за технічними шарами й не дає нічого придатного, доки не завершиться останній.

При горизонтальному поділі кожна історія — це один технічний шар: UI, API, доменна логіка, дані, — і ніщо не працює, доки не готовий останній шар, тож увесь зворотний зв’язок приходить наприкінці. При вертикальному поділі кожна історія проходить крізь усі шари й дає користувачеві щось, що він може зробити, тож кожен шматок можна випустити й дізнатися з нього.

Горизонтальний поділ спокусливий, бо збігається з тим, як часто організовані команди, і відчувається ефективним: людина з бази даних робить частину з базою даних, один раз і як слід. Він програє з причини, що не має стосунку до ефективності: ніщо не придатне до релізу, доки не завершено кожен шар, тож увесь зворотний зв’язок приходить наприкінці, до того жодну оцінку неможливо спростувати, а зрив на останньому шарі знецінює всі шари під ним.

Шість способів розділити завелику історію

Ділити заПриклад
Кроком сценарію«Оформити замовлення» стає: ввести адресу → обрати доставку → оплатити → лист-підтвердження. Спершу щасливий шлях; кожен наступний крок — окрема історія.
Бізнес-правиломЗнижки: підтримати простий відсоток зараз; обсягові рівні, терміни дії та правила складання стають ще трьома історіями.
Варіацією данихІмпорт: спершу 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 без часового боксу й без записаного висновку перетворюються на побічні проєкти.

Коли це застосовувати

Застосовуйте, коли

  • Роботу можна описати через те, що користувач зможе зробити.
  • Команда й замовник справді можуть говорити — розмова і є результатом.
  • Ви можете випускати малі шматки й вчитися з них.
  • Вимоги змінюватимуться, тож гнучкий формат кращий за фіксовану специфікацію.

Уникайте, коли

  • У роботи немає видимого користувачеві результату — оновлення бібліотеки це задача, а не історія.
  • Регулятор вимагає натомість формальну підписану специфікацію.
  • Немає з ким провести розмову — лишається найслабша третина формату.
  • Шаблон застосовують заради галочки в процесі, а не щоб прояснити потребу.

Було корисно?

Поділіться з тим, хто працює над тією ж задачею.