User Stories
Anatomy of a Great User Story
Master the INVEST criteria, acceptance criteria format, and the Definition of Done to write user stories developers love.
The INVEST Criteria
INVEST is an acronym coined by Bill Wake that describes the six properties of a well-formed user story. Every story you write should pass all six tests.
I — Independent
Stories should be self-contained and not depend on other stories. When stories are coupled, you cannot reorder them in the backlog, and implementing one without the other creates half-finished features.
- Bad: "As a user, I want to log in (requires registration to be done first)"
- Good: Each story stands alone. Registration and login are separate, independent stories.
N — Negotiable
Stories are not contracts. The details are subject to negotiation between the team and the stakeholders. The story captures intent, not implementation specifics. Write it loosely enough that the developer can ask questions and find better solutions.
V — Valuable
Every story must deliver value to a real user or the business. "Refactor the database layer" is not a user story — it is a technical task. If you cannot explain who benefits and how, the story should not exist yet.
E — Estimable
The team must be able to estimate how long the story will take. If a story is too vague to estimate, it needs more clarification. If it is too large to estimate precisely, it needs to be split.
S — Small
Stories should be completable within a single sprint (typically 1-2 weeks). A story that takes 3 sprints is actually an epic — it needs to be broken down into smaller stories.
T — Testable
There must be a clear way to verify that the story is complete. If you cannot write an acceptance criterion for it, the story is too vague to implement.
Acceptance Criteria in Given/When/Then
Given/When/Then (also called Gherkin syntax or BDD format) is the standard way to write acceptance criteria. Each criterion describes one observable behavior:
- Given — the starting state or precondition
- When — the action the user takes
- Then — the expected outcome
Five examples with increasing complexity:
Example 1: Simple button action
Given I am on the checkout page, when I click "Place Order", then an order confirmation email is sent to my email address.
Example 2: Validation
Given the email field is empty, when I click "Subscribe", then a validation error message "Email is required" appears below the field.
Example 3: State change
Given I am logged in as an admin, when I click "Deactivate User" on a user profile, then the user's status changes to "Inactive" and they can no longer log in.
Example 4: Multiple outcomes
Given I upload a file larger than 10MB, when I click "Upload", then the upload is rejected, an error message displays, and the file size limit is shown.
Example 5: Edge case
Given a search returns no results, when I view the search results page, then a "No results found" message and three suggested searches are displayed.
Story Points and Estimation
Story points are a relative measure of effort, complexity, and uncertainty. Teams commonly use the Fibonacci sequence: 1, 2, 3, 5, 8, 13, 21.
- 1 point: Trivially small. Change a label. Fix a typo.
- 2 points: Simple, well-understood. Style a button component.
- 3 points: Moderate effort. Build a form with validation.
- 5 points: Significant complexity. Implement user authentication.
- 8 points: Complex with uncertainties. Build a payment integration.
- 13+ points: Too big — split the story.
Planning poker: Team members each hold cards with Fibonacci numbers. When estimating, everyone reveals their card simultaneously. Outliers discuss their reasoning, and the team re-estimates until reaching consensus.
Rewriting Weak Stories
| Weak Story | Problem | Improved Story |
|---|---|---|
| "Users can search" | No role, no benefit | "As a user, I want to search articles by keyword so that I can quickly find relevant content" |
| "Admin manages users" | Too vague, too large | "As an admin, I want to deactivate a user account so that I can revoke access for former employees" |
| "Fix the login bug" | Not a story, is a bug | Convert to bug report. Or: "As a user, I want password validation errors to display inline so that I understand why my login failed" |
| "Make it faster" | Not testable | "As a user, I want search results to load within 500ms so that the app feels responsive" |
| "Add dark mode" | Missing acceptance criteria | Add GWT criteria for: toggle location, persistence across sessions, default behavior |
The Definition of Done
The Definition of Done (DoD) is a team agreement about what "complete" means for every story. It prevents stories from being marked done when only the happy path works. A typical DoD includes:
- Code written and peer-reviewed
- Unit tests written and passing
- Integration tests passing
- Deployed to staging environment
- Product owner accepted the story against acceptance criteria
- No new accessibility regressions
- Documentation updated if needed
Key Takeaways
- INVEST criteria: Independent, Negotiable, Valuable, Estimable, Small, Testable
- Acceptance criteria in Given/When/Then format make stories testable and unambiguous
- Story points use the Fibonacci scale to capture relative effort and uncertainty
- Weak stories lack a role, benefit, or testable criteria — always fix these before starting work
- The Definition of Done is a team contract that prevents "done but not really done"
Example
# INVEST Checklist
[ ] Independent - stands alone in the backlog
[ ] Negotiable - details can be discussed
[ ] Valuable - delivers user or business value
[ ] Estimable - team can estimate effort
[ ] Small - fits in one sprint
[ ] Testable - has clear pass/fail criteria
# Acceptance Criteria Template
Scenario: [descriptive name]
Given [precondition or starting state]
When [user action or system event]
Then [expected outcome]
And [additional outcome if needed]