Key takeaways
- Clear acceptance criteria turn a ticket into an atomic unit of work that can be completed without back-and-forth.
- A one-page ticket template that includes scope, steps, and measurable criteria reduces rework by up to 30% in practice.
- Running the ticket through a quick sanity check—scope, dependencies, and time estimate—catches most issue-writing errors before they reach the backlog.
You write a ticket once, your future self (or a teammate) will read it later. If the acceptance criteria are atomic, the ticket can be closed without clarification. The guide below shows you how to write good tickets step by step, with a copy-paste template and a short worked example.
1. Define the Problem in One Sentence
- Write a single sentence that states the user problem or system defect. 2. Output: a concise problem statement that fits on one line of a backlog view. Example: “Users cannot reset their password after the recent OAuth migration.”
2. List the Exact Behaviour Expected
- Draft the behaviour as a bulleted list of observable outcomes. 2. Output: three to five bullet points that a tester can verify without guessing. Example:
- The “Forgot password” link is visible on the login page.
- Clicking the link opens a modal with an email field.
- Submitting a registered email sends a reset link within 60 seconds.
- The reset link expires after 24 hours.
- The user can set a new password that meets the complexity policy.
3. Write Atomic Acceptance Criteria
- Turn each bullet into a “Given-When-Then” clause that can be satisfied independently. 2. Output: a list where each clause references only one system change. Example:
- Given a registered user, when they click “Forgot password”, then the modal appears.
- Given a valid email, when the form is submitted, then a reset email is sent within 60 seconds.
- Given an expired token, when the user follows the link, then an error page is shown.
4. Add a Minimal Reproduction Path
- Record the steps needed to trigger the issue or verify the fix. 2. Output: a numbered list that any developer can follow on a fresh branch. Example:
- Pull the latest master.
- Run
npm start. - Navigate to
https://app.example.com/login. - Click “Forgot password” and enter
test@example.com. - Check the inbox for the reset email.
5. Estimate Time and Flag Dependencies
- Use the team’s usual estimation unit (e.g., 2 h, 1 sp) and note any required upstream work. 2. Output: an estimate field and a dependency note. Example: “Estimate: 3 h. Depends on OAuth token refresh endpoint being merged.”
Ticket Template (Copy-Paste)
Title: [Short problem statement]
Problem: One-sentence description.
Behaviour: Bullet list of expected outcomes.
Acceptance Criteria:
- Given … When … Then …
- … Reproduction Steps:
- …
- … Estimate & Dependencies:
- Estimate: …
- Depends on: …
Use this template for every new ticket. It forces atomic criteria and prevents vague “works on my machine” comments.
What Usually Goes Wrong and How to Fix It
- Vague criteria – “The page loads fast.” Fix: replace with a measurable metric, e.g., “Page load time < 2 seconds on a 3G connection.”
- Multiple concerns in one ticket – mixing UI and backend changes. Fix: split into separate tickets, each with its own acceptance criteria.
- Missing dependencies – developers start and hit a blocker. Fix: add a “Depends on” line during step 5.
- No testable outcome – “Improve UX.” Fix: define a user-story metric, such as “Conversion rate increases by 5 % in A/B test.”
- Over-estimating scope – “Implement full password-reset flow.” Fix: start with a minimal viable flow and create follow-up tickets for enhancements.
When you catch these patterns early, the ticket moves straight to implementation. For a deeper look at breaking down features, see the post “Break Down a Feature Ticket with Engineering Planning.”
Putting It All Together – Worked Example
Problem: Users cannot reset their password after the recent OAuth migration.
Behaviour:
- “Forgot password” link appears.
- Modal opens with email field.
- Reset email sent within 60 seconds.
- Link expires after 24 hours.
- New password must meet policy.
Acceptance Criteria (atomic):
- Given a registered user, when they click the link, then the modal appears.
- Given a valid email, when submitted, then a reset email is sent within 60 seconds.
- Given an expired token, when used, then an error page shows.
Reproduction Steps:
- Pull master.
- Run
npm start. - Open login page.
- Click “Forgot password”.
- Submit
test@example.com. - Verify email receipt.
Estimate & Dependencies:
- Estimate: 3 h.
- Depends on: OAuth token refresh endpoint.
Paste the template, fill the fields, and the ticket is ready for the backlog.
FAQ
How do I make acceptance criteria atomic?
Write each criterion as a single Given-When-Then statement that can be verified without any other criterion. If it requires another change, split it into a separate ticket.
What should I include in a ticket template?
Title, one-sentence problem, bullet list of expected behaviour, atomic acceptance criteria, reproducible steps, estimate, and any dependencies.
Why does a vague “fast page load” fail?
‘Fast’ is subjective. Replace it with a concrete metric such as “load time < 2 seconds on a 3G connection” so testers can measure it.
Can I skip the dependency note if I think nothing is required?
No. Even a trivial change may rely on a library version or a shared API. Adding “None” explicitly avoids later surprise blockers.
Is a one-hour estimate realistic for a password-reset flow?
It depends on team velocity, but start with a small estimate and adjust after the first implementation. Over-estimation often hides hidden work.
Originally published on Syncflow. Syncflow breaks big goals into small ordered steps and shows you one at a time — try it free.
Top comments (0)