Format: Given-when-then criteria define clear, testable software behavior for shared understanding among team members.
Structure: Each scenario in the format includes context, the user action, and the expected outcome in plain language.
Best Practices: Focus on simplicity, collaboration, and detail to improve the clarity of acceptance criteria.
Common Mistakes: Avoid cramming scenarios together, writing technical details, and neglecting edge cases.
Given-when-then (GWT) acceptance criteria provide a simple, testable way to describe how software should behave so developers, testers, and stakeholders have a shared understanding. When acceptance criteria are vague, teams waste time debating requirements, building the wrong solution, and finding gaps late in development.
In this guide, I'll break down the given-when-then format, show real examples across common scenarios, compare it with other acceptance criteria approaches, and share the practices that help agile teams write clearer, more effective user stories.
What Is Given-When-Then Acceptance Criteria?
Given-when-then is a three-part template for writing acceptance criteria on a user story. Each scenario describes one slice of expected behavior in plain language that developers, testers, and stakeholders can all read.
Here’s how the structure works:
- Given states what must already be true before the end-user does anything.
- When introduces the action. It's what the user does or the event the system fires.
- Then reveals the outcome. It’s the result that proves the system responded correctly.
How to Write Given-When-Then Acceptance Criteria
How to write each clause so it holds up during development and software testing.
Given: Setting the Context and Preconditions
The given clause describes what must already be true. This includes system state, user role, data conditions, and environmental setup. Strong given statements are specific. Avoid writing "Given the user is logged in" when the scenario depends on role. Instead, write "Given a registered customer with a valid subscription is on the account settings page."
A few guidelines for writing the given clause:
- Name the user role or persona when it matters.
- State system conditions such as feature flags, data states, or connectivity.
- Combine multiple preconditions with "And" rather than cramming them into one clause.
When: Defining the Action or Trigger
The when clause captures the action or event that triggers the behavior you're testing. It should describe one user interaction or system event, not a sequence. Use active voice. Write "When the customer clicks 'Apply Coupon'" rather than "When the coupon button is clicked." This removes ambiguity about who performs the action.
Keep this clause tight. If you need more than one when statement, you're likely describing two separate scenarios. Split them.
Then: Specifying the Expected Outcome
The then clause states what the user should observe or what the system should do after the action. Describe observable results. "Then the dashboard loads" is weak. "Then the system displays the customer's dashboard within two seconds" is testable. Include specifics like error messages, redirect destinations, data changes, email triggers, or UI state changes.
Use And to chain multiple outcomes when a single action produces more than one observable result. For example, "Then the order confirmation page displays" And "the customer receives a confirmation email within 60 seconds."
Given-When-Then Examples
Here are some examples of given-when-then acceptance criteria across different domains.
User Login
Scenario 1: Successful login with valid credentials
Given a registered user is on the login page When the user enters a valid email and correct password and clicks "Log In" Then the system redirects the user to their account dashboard
The given clause here is intentionally lean because the scenario doesn't depend on subscription tier or account status. Notice the compound when clause: entering credentials and clicking a button is one logical action (submitting a login form), so I keep it together rather than splitting it into a separate scenario for each keystroke.
Scenario 2: Failed login with invalid credentials
Given a registered user is on the login page When the user enters a valid email and an incorrect password and clicks "Log In" Then the system displays the message "Invalid email or password" And the user remains on the login page
The Then clause specifies the exact error message text. The second And clause matters because it confirms the user isn't accidentally redirected somewhere else.
Shopping Cart and Checkout
Scenario 1: Adding an item to the cart
Given a customer is viewing a product detail page for an in-stock item When the customer clicks "Add to Cart" Then the cart icon updates to show one item And a confirmation message reads "Item added to cart"
The given clause includes "in-stock" because the behavior differs for out-of-stock items, and that's a separate scenario.
Scenario 2: Applying a valid discount code
Given a customer has two items in the cart totaling $80.00 When the customer enters the discount code "SAVE20" and clicks "Apply" Then the system applies a 20% discount And the cart total updates to $64.00
The specific dollar amounts make it impossible to misinterpret. This kind of discount scenario can help catch a rounding bug in production where a percentage discount on an odd total produced a price with three decimal places. The precision in the given clause ($80.00) and then clause ($64.00) is what makes the scenario valuable.
Password Recovery
Scenario 1: Requesting a password reset with a registered email
Given a user is on the login page When the user clicks "Forgot Password," enters a registered email address, and clicks "Submit" Then the system displays "A reset link has been sent to your email" And the system sends a password reset email within 60 seconds
The compound when here represents a single logical flow: requesting a reset. The 60-second time constraint in the then clause is critical. Without it, a reset email that arrives 20 minutes later technically "passes." Time-bound outcomes are one of the most commonly omitted details.
Scenario 2: Using an expired reset link
Given a user received a password reset email more than 24 hours ago When the user clicks the reset link in the email Then the system displays "This link has expired. Please request a new reset."
The given clause embeds a time condition, which forces a conversation about what the expiration window should be.
Form Validation
Scenario 1: Submitting a form with missing required fields
Given a user is on the registration form When the user leaves the "Email" field blank and clicks "Submit" Then the system displays an inline error message "Email is required" below the Email field And the form is not submitted
The then clause specifies where the error appears ("below the Email field"), not just that it appears.
Scenario 2: Exceeding the character limit on a text field
Given a user is filling out the "Bio" field with a 500-character limit When the user enters 501 characters Then the system prevents further input And a message reads "Maximum 500 characters allowed"
GWT vs. Checklists vs. Use Cases
Here are some other types of acceptance criteria and when you might use each one:
| Aspect | Given-When-Then | Rule-Oriented Checklist | Use Case |
|---|---|---|---|
| Structure | Given, When, Then | Bulleted list of rules | Numbered steps with flows |
| Best fit | Behavioral scenarios, BDD | Business rules, UI specs | Complex multi-flow features |
| Strengths | Testable, automatable, context-rich | Quick to write, easy to scan | Thorough, covers edge cases |
| Limitations | Verbose for simple changes | No scenario flow, hard to automate | Heavyweight, slow to maintain |
| Audience | Dev, QA, product | Product, design, stakeholders | External teams, compliance |
| Scope | Single behavior | Entire feature | Entire feature |
| Level of detail | Three clauses | Flexible | Preconditions, postconditions, triggers, and numbered steps |
I've found that use cases work best when you need to document a system for regulatory compliance or hand it off to an external vendor. For day-to-day sprint work, given-when-then is leaner and faster.
Given-When-Then Best Practices
Here are some best practices to help you use GWT effectively:
- Avoid vague or ambiguous language: Instead of “Then the page loads quickly, write “Then the search results page loads within two seconds.” Replace adjectives like “appropriate” or “relevant” with measurable values. If you can't test it, rewrite it.
- Keep scenarios simple and focused: Follow the one-behavior-per-scenario rule. Each scenario should test exactly one thing. When you combine multiple actions or outcomes, you create test cases that are hard to debug and maintain. If a scenario has more than two and statements under then, ask yourself whether you're testing one behavior or two.
- Hold a three-amigos session: A three-amigos session is a short, focused conversation where a product person (product owner or business analyst), a developer, and a tester review upcoming stories together before the sprint begins. They write or refine the GWT criteria as a group, which prevents rework.
- Maintain consistency in terminology and style: Pick standard terms and stick with them across every story. If you use "customer" in one scenario and "user" in another, you introduce confusion. Create a small glossary if needed. Use the same sentence structure in your clauses.
Five Common Anti-Patterns
Here are some common mistakes to avoid when writing given-when-then acceptance criteria:
- Writing implementation details instead of behavior: Scenarios like "Given the API call returns a 200 status code" describe technical implementation, not user behavior. Rewrite from the user's perspective: "Given the product catalog has loaded on the homepage." Save technical details for test automation code.
- Cramming multiple scenarios into one: A scenario that tests login, navigation, and checkout in a single block is an integration test, not an acceptance criterion. Break each behavior into its own scenario. You'll get clearer results and easier debugging.
- Skipping negative and edge-case scenarios: Agile development teams often write the happy path and forget what happens when things go wrong. For every successful scenario, ask: what if the input is invalid? What if the network drops? What if the data is missing? Write at least one negative scenario per story to catch issues before they reach production.
- Treating GWT as the only acceptable format: Use GWT for behavior, and use checklists for everything else. If you force every story into given-when-then, including button color changes, copy updates, and infrastructure configuration, you’ll end up with some absurd results (e.g. “Given the homepage exists, When the user views it, Then the header font is 16px.).
- Writing scenarios in isolation: Don’t write GWT criteria alone. The format's value comes from the conversation it provokes. If your scenarios aren't being discussed by at least two disciplines before software development starts, you're using GWT as a documentation format when its real power is as a collaboration format.
What’s Next?
Clear given-when-then acceptance criteria are only one part of delivering successful projects. Build on that foundation with a free DPM membership and get access to practical templates, expert resources, and proven frameworks that help turn well-defined requirements into smoother delivery and stronger results.
