Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 40 — User Stories và Acceptance Criteria

PMP Certification Preparation Bài 40/60

Mở đầu — vì sao bài này quan trọng

Nếu bạn từng chứng kiến một dự án phần mềm "chạy đúng như đặc tả" nhưng khách hàng vẫn lắc đầu vì "không phải cái tôi cần", thì bạn đã tận mắt thấy khoảng cách mà User Story sinh ra để lấp đầy. Trong thế giới Agile — và cả trong kỳ thi PMP mới (PMBOK 7 nhấn mạnh giá trị, kết quả và cách làm việc lặp — iterative), User Story là đơn vị công việc căn bản mà nhóm Agile dùng để mô tả nhu cầu của người dùng, còn Acceptance Criteria (tiêu chí chấp nhận) là ranh giới xác định "làm xong đến đâu thì gọi là đủ".

Với một Project Manager đang ôn PMP, hiểu User Story và Acceptance Criteria không chỉ để trả lời đúng vài câu trắc nghiệm. Đây là công cụ giúp bạn dịch những kỳ vọng mơ hồ của stakeholder thành công việc cụ thể, đo lường được, và quan trọng nhất — thành giá trị (value) mà PMBOK 7 đặt làm trung tâm. Trong đề thi PMP hiện nay, khoảng một nửa câu hỏi mang tính Agile/Hybrid, và người ta rất hay đặt tình huống dạng: "Product Owner nhận được yêu cầu mơ hồ, PM/Scrum Master nên làm gì?" hoặc "User Story thiếu điều gì để nhóm có thể bắt đầu?". Nếu bạn nắm chắc format chuẩn, tiêu chí INVEST và cách viết Acceptance Criteria, những câu đó gần như là điểm cho không.

Bài này tập trung riêng vào hai khái niệm đó — cách viết, cách kiểm tra chất lượng, và cách tránh những lỗi kinh điển. Chúng ta sẽ không đi sâu vào backlog refinement hay estimation (đã có bài riêng), mà xoáy vào việc: một User Story tốt trông như thế nào và làm sao biết nó đã "done".

Khái niệm cốt lõi

User Story là gì — và không là gì

User Story là một mô tả ngắn gọn về một tính năng hoặc nhu cầu, viết dưới góc nhìn của người sử dụng, bằng ngôn ngữ đời thường. Điểm mấu chốt: User Story không phải là bản đặc tả kỹ thuật chi tiết. Nó là lời mời để trò chuyện. Alistair Cockburn gọi User Story là "a promise for a conversation" — một lời hứa sẽ cùng nhau bàn kỹ hơn. Nghĩa là bạn không cần viết hết mọi thứ trong dòng chữ đó; những chi tiết còn lại sẽ được làm rõ qua đối thoại giữa nhóm phát triển và Product Owner.

Điều này khác hẳn tư duy Waterfall, nơi bạn cố gắng đóng băng toàn bộ yêu cầu vào một tài liệu SRS (Software Requirements Specification) dày cộp ngay từ đầu. Với Agile, ta chấp nhận rằng yêu cầu sẽ tiến hóa, nên ta ghi lại vừa đủ để nhớ cần bàn gì, rồi bàn sâu khi tới lúc làm.

Format chuẩn Connextra

Format phổ biến nhất, ra đời tại công ty Connextra (Anh) năm 2001, có cấu trúc:

> As a <persona>, I want <action> so that <value>. > > (Là một <vai trò/người dùng>, tôi muốn <hành động/tính năng> để <đạt được giá trị gì>.)

Ví dụ: "As a registered customer, I want to reset my password by email so that I can regain access without contacting support." — "Là một khách hàng đã đăng ký, tôi muốn đặt lại mật khẩu qua email để có thể lấy lại quyền truy cập mà không cần liên hệ bộ phận hỗ trợ."

Ba thành phần này không phải trang trí. Mỗi phần trả lời một câu hỏi sống còn:

  • As a (persona)Ai cần cái này? Việc gắn với một persona cụ thể (khách hàng đã đăng ký, quản trị viên, khách vãng lai...) buộc nhóm phải nghĩ đến người thật, ngữ cảnh thật. "As a user" chung chung là dấu hiệu của một story lười biếng.
  • I want (action) — Họ muốn làm gì? Đây là hành vi hoặc khả năng mà hệ thống cần cung cấp.
  • So that (value)Tại sao họ muốn điều đó? Đây là phần quan trọng nhất và cũng hay bị bỏ nhất. Nó cho biết giá trị kinh doanh, giúp Product Owner ưu tiên và giúp nhóm hiểu "tinh thần" của yêu cầu để đề xuất giải pháp tốt hơn.
Mẹo của tôi: khi review một story, hãy đọc ngược từ phần "so that". Nếu phần giá trị nghe yếu ("...so that I can use the feature") thì rất có thể story này chưa đáng làm, hoặc bạn chưa hiểu đúng nhu cầu thật.

Tiêu chí INVEST — thước đo chất lượng story

Bill Wake đề xuất bộ tiêu chí INVEST để kiểm tra một story có "khỏe" không. Đây là kiến thức rất dễ ra thi:

  • I – Independent (độc lập): Story nên tự đứng được, ít phụ thuộc chéo, để có thể ưu tiên và làm theo bất kỳ thứ tự nào.
  • N – Negotiable (có thể thương lượng): Không phải hợp đồng cứng nhắc; chi tiết còn mở để cùng bàn.
  • V – Valuable (có giá trị): Mỗi story phải mang lại giá trị cho người dùng hoặc khách hàng — không phải "công việc kỹ thuật thuần túy" mà end-user không thấy.
  • E – Estimable (ước lượng được): Nhóm phải hiểu đủ để ước lượng công sức. Nếu không ước lượng nổi, story còn quá mơ hồ hoặc quá lớn.
  • S – Small (đủ nhỏ): Vừa gọn để hoàn thành trong một sprint, lý tưởng là vài ngày.
  • T – Testable (kiểm thử được): Phải có cách xác minh nó đã xong — và đây chính là lúc Acceptance Criteria bước vào.

Acceptance Criteria — ranh giới của "Done"

Acceptance Criteria (AC — tiêu chí chấp nhận) là tập hợp các điều kiện mà một User Story phải thỏa mãn để được Product Owner chấp nhận là hoàn thành. Nếu User Story trả lời "cái gì và tại sao", thì AC trả lời "làm sao biết là đúng".

Lưu ý phân biệt quan trọng, hay bị nhầm trong thi:

  • Acceptance Criteria gắn với từng story cụ thể — điều kiện riêng của story đó.
  • Definition of Done (DoD) áp dụng cho mọi story trong nhóm — các chuẩn chung như: đã viết test, đã code review, đã cập nhật tài liệu, đã deploy lên môi trường test.
Một story chỉ thực sự "Done" khi thỏa mãn cả Acceptance Criteria riêng lẫn Definition of Done chung.

Có hai cách phổ biến để viết AC:

1. Dạng danh sách (checklist / scenario-based): liệt kê các điều kiện, ví dụ:

  • Người dùng nhập email đã đăng ký thì nhận được link đặt lại mật khẩu trong vòng 2 phút.
  • Link hết hạn sau 30 phút.
  • Nhập email chưa đăng ký thì hiển thị thông báo trung lập (không tiết lộ email có tồn tại hay không, vì lý do bảo mật).
2. Dạng Gherkin (Given-When-Then): cấu trúc hành vi, rất mạnh cho tự động hóa kiểm thử (BDD – Behavior Driven Development):

> Given khách hàng đang ở trang "Quên mật khẩu" > When họ nhập một email đã đăng ký và bấm "Gửi" > Then hệ thống gửi email chứa link đặt lại trong vòng 2 phút

"Given" mô tả bối cảnh, "When" là hành động, "Then" là kết quả mong đợi. Dạng này ép bạn nghĩ theo tình huống rõ ràng, giảm hiểu lầm và dễ chuyển thành test case tự động.

Tình huống thực tế

Tình huống 1 — Tiki và câu chuyện "so that" bị bỏ quên

Giả định một nhóm phát triển tại một sàn thương mại điện tử lớn ở Việt Nam (kiểu như Tiki) nhận yêu cầu: "Thêm bộ lọc theo thương hiệu vào trang danh mục." Lập trình viên viết vội story: "As a user, I want to filter by brand." — không persona rõ, không giá trị.

Nhóm làm xong bộ lọc brand đúng như câu chữ. Nhưng khi demo, Product Owner phát hiện: người dùng thật ở đây là khách mua mỹ phẩm đang tìm hàng chính hãng, và giá trị thật là "để chắc chắn mua đúng hàng authentic, không mua nhầm hàng nhái". Nếu story viết đủ — "As a beauty shopper, I want to filter products by official brand store so that I can be sure I'm buying authentic products" — nhóm đã hiểu rằng cần ưu tiên hiển thị badge "Chính hãng", tách gian hàng official khỏi gian hàng thường. Kết quả thực tế: họ phải làm lại, tốn thêm gần một sprint.

Bài học: Phần "so that" không phải thủ tục. Nó định hình cả giải pháp. Bỏ nó đi, bạn dễ làm đúng câu chữ nhưng sai nhu cầu.

Tình huống 2 — Ngân hàng số và Acceptance Criteria cứu một lỗ hổng

Một nhóm tại một ngân hàng số (giả định như Timo hoặc Cake) làm story: "As an app user, I want to transfer money to another account so that I can pay someone quickly." Nghe thì rõ. Nhưng khi ngồi viết Acceptance Criteria dạng Given-When-Then, tester đặt câu hỏi: điều gì xảy ra khi số dư không đủ? Khi vượt hạn mức giao dịch ngày? Khi mất kết nối giữa chừng?

Nhờ đó nhóm bổ sung các AC:

  • Given số dư nhỏ hơn số tiền chuyển, When người dùng xác nhận, Then hệ thống chặn giao dịch và báo "Số dư không đủ", không trừ tiền.
  • Given giao dịch vượt hạn mức 100 triệu/ngày, When người dùng xác nhận, Then hệ thống yêu cầu xác thực OTP bổ sung.
  • Given mất kết nối sau khi trừ tiền, Then giao dịch phải idempotent — không được chuyển hai lần khi người dùng thử lại.
AC cuối cùng chính là cái ngăn một lỗi tài chính nghiêm trọng. Nếu chỉ dựa vào dòng story ngắn ngủi, lập trình viên có thể đã bỏ sót các trường hợp biên (edge case) này.

Bài học: Acceptance Criteria không chỉ để "nghiệm thu". Quá trình viết ra nó chính là lúc nhóm phát hiện những rủi ro và trường hợp biên mà story không thể hiện. Đây là giá trị lớn nhất của AC.

Tình huống 3 — Story quá lớn tại một startup logistics

Một startup giao hàng ở TP.HCM có story: "As a customer, I want to track my order so that I know when it arrives." Nhóm ước lượng và... không ai đồng ý được con số, vì "track order" bao gồm quá nhiều thứ: bản đồ thời gian thực, thông báo push, lịch sử trạng thái, dự đoán giờ giao (ETA). Story này vi phạm chữ S (Small)E (Estimable) trong INVEST.

Product Owner tách nó (splitting) thành nhiều story nhỏ:

  • ...I want to see my order's current status (đã lấy hàng / đang giao / đã giao) so that...
  • ...I want to receive a push notification when status changes so that...
  • ...I want to see the courier's live location on a map so that...
  • ...I want to see an estimated delivery time so that...
Mỗi story giờ đây gọn, ước lượng được, và có thể giao giá trị độc lập. Story #1 lên production trước và đã đáp ứng phần lớn nhu cầu; bản đồ real-time (đắt nhất) được đẩy về sau.

Bài học: Một story không estimate nổi thường là do quá lớn (gọi là Epic). Việc chẻ nhỏ theo giá trị giúp giao hàng sớm và giảm rủi ro.

Hướng dẫn từng bước

Đây là quy trình tôi khuyên bạn dùng khi viết và hoàn thiện một User Story:

  • Xác định persona thật. Đừng viết "As a user". Hỏi: người này là ai, họ đang cố làm gì trong bối cảnh nào? Nếu bạn có persona hoặc user research, dùng nó.
  • Viết theo format Connextra. Điền đủ ba phần As a / I want / So that. Nếu bạn không viết nổi phần "so that", hãy dừng lại — có thể story này chưa đáng làm.
  • Kiểm tra bằng INVEST. Rà từng chữ cái. Đặc biệt hỏi: story này có đủ nhỏ để xong trong một sprint không? Có độc lập không? Có đo lường được (testable) không?
  • Chẻ nhỏ nếu cần (story splitting). Nếu vi phạm S hoặc E, tách theo trục giá trị: theo bước quy trình, theo loại dữ liệu, theo trường hợp đơn giản trước — phức tạp sau. Tránh chẻ theo tầng kỹ thuật (backend/frontend) vì mỗi mảnh sẽ không giao được giá trị độc lập.
  • Viết Acceptance Criteria. Chọn dạng checklist hoặc Given-When-Then. Bắt buộc phủ cả: đường thành công (happy path), các trường hợp lỗi, và trường hợp biên. Đây là bước hay lộ ra rủi ro nhất — hãy làm cùng cả nhóm (Three Amigos: Product Owner, Developer, Tester).
  • Đối chiếu Definition of Done. Nhớ rằng AC riêng chưa đủ; story còn phải qua chuẩn chung của nhóm (test, review, tài liệu...).
  • Trò chuyện, không tụng chữ. Nhớ triết lý "3C" của Ron Jeffries: Card (thẻ ghi story ngắn gọn), Conversation (cuộc trò chuyện làm rõ chi tiết), Confirmation (Acceptance Criteria xác nhận đã đạt). Card chỉ là điểm khởi đầu; giá trị nằm ở Conversation.

Lỗi thường gặp & mẹo

Lỗi 1 — Viết story như đặc tả kỹ thuật. Ví dụ: "As a developer, I want to add an index to the orders table." Đây là công việc kỹ thuật, không phải nhu cầu người dùng. Nó có thể là một task kỹ thuật trong story, nhưng đừng ngụy trang thành User Story. Mẹo: nếu end-user không thấy được giá trị, nó không phải User Story.

Lỗi 2 — Bỏ phần "so that". Như tình huống Tiki ở trên. Không có giá trị, Product Owner không ưu tiên được và nhóm dễ làm sai tinh thần yêu cầu.

Lỗi 3 — Acceptance Criteria mơ hồ, không đo được. "Trang phải tải nhanh" là AC tồi. "Trang tải xong trong dưới 2 giây với kết nối 3G" mới là AC đo được. Mẹo: mỗi AC phải trả lời được câu "làm sao tôi kiểm chứng điều này bằng một phép thử cụ thể?".

Lỗi 4 — Nhồi quá nhiều AC vào một story. Nếu một story có 15 tiêu chí chấp nhận, gần như chắc chắn nó là một Epic đội lốt. Hãy chẻ nhỏ.

Lỗi 5 — Lẫn lộn AC với Definition of Done. Nhớ: AC là riêng cho story, DoD là chung cho mọi story. Câu hỏi thi hay đánh vào điểm này.

Lỗi 6 — Product Owner viết AC một mình rồi ném cho nhóm. Sức mạnh của AC đến từ cuộc đối thoại Three Amigos. Viết một mình dễ bỏ sót trường hợp biên mà tester hoặc dev sẽ nhìn ra.

Mẹo ôn thi: Khi gặp câu hỏi PMP về Agile requirements, hãy nhớ chuỗi liên kết: Persona → nhu cầu (User Story) → giá trị (so that) → điều kiện nghiệm thu (Acceptance Criteria) → chuẩn chung (Definition of Done). Rất nhiều câu chỉ đơn giản kiểm tra bạn có phân biệt được các mắt xích này không.

Bài tập thực hành

  • Viết lại một story yếu. Cho story: "As a user, I want a dashboard." Hãy viết lại thành một story đầy đủ ba phần, với persona cụ thể và giá trị rõ ràng cho bối cảnh của chính bạn (ví dụ chủ shop online muốn xem doanh thu).
  • Chấm điểm INVEST. Lấy story bạn vừa viết, chấm từng chữ cái I-N-V-E-S-T (đạt/không đạt) và giải thích. Nếu có chữ nào "không đạt", hãy sửa.
  • Viết Acceptance Criteria dạng Given-When-Then. Cho story: "Là khách hàng, tôi muốn hủy đơn hàng trong vòng 30 phút sau khi đặt để không bị tính phí." Hãy viết ít nhất 3 kịch bản AC, bao gồm: happy path, một trường hợp lỗi, và một trường hợp biên (ví dụ: hủy sau đúng 30 phút thì sao?).
  • Chẻ một Epic. Cho Epic: "Là người dùng, tôi muốn quản lý hồ sơ cá nhân." Hãy tách thành ít nhất 3 User Story nhỏ, đảm bảo mỗi story giao được giá trị độc lập.
  • Phân biệt AC và DoD. Viết ra 3 mục thuộc Acceptance Criteria và 3 mục thuộc Definition of Done cho một story đăng nhập bằng số điện thoại + OTP. Giải thích vì sao mỗi mục thuộc nhóm nào.

Tóm tắt

  • User Story là mô tả ngắn về nhu cầu từ góc nhìn người dùng, theo format Connextra: As a <persona>, I want <action> so that <value>. Nó là "lời hứa cho một cuộc trò chuyện", không phải đặc tả kỹ thuật cứng.
  • Phần "so that" (giá trị) là quan trọng nhất — nó định hình giải pháp và giúp ưu tiên; đừng bao giờ bỏ.
  • INVEST (Independent, Negotiable, Valuable, Estimable, Small, Testable) là thước đo chất lượng story — rất hay ra thi.
  • Acceptance Criteria xác định điều kiện để story được chấp nhận là "Done"; viết dạng checklist hoặc Given-When-Then (Gherkin/BDD). Quá trình viết AC chính là lúc phát hiện rủi ro và trường hợp biên.
  • Phân biệt rõ: AC riêng cho từng story, còn Definition of Done áp dụng chung cho mọi story.
  • Triết lý 3C (Card – Conversation – Confirmation) nhắc rằng giá trị nằm ở đối thoại, không phải câu chữ trên thẻ.
  • Story quá lớn hoặc không estimate nổi là Epic — hãy chẻ nhỏ theo trục giá trị, không theo tầng kỹ thuật.
Nắm chắc những mắt xích này, bạn không chỉ tự tin với các câu Agile trong đề PMP mà còn có ngay một bộ công cụ dùng được trong công việc thật ngày mai.