Writing Acceptance Criteria (AC)
Purpose
Acceptance criteria define the conditions that must be met for the software to be accepted by a user or stakeholder.
Each Product Backlog Item (PBI) must have acceptance criteria, which must be signed off by the Product Owner prior to work commencing.
Audience
Acceptance criteria should be captured for the benefit/use of all project stakeholders, including end users, the development team, and all other stakeholders.
Criteria should therefore avoid development-related technical terminology and should not be used to record implementation details or the tasks required to develop/test the feature. These can be recorded elsewhere as appropriate, e.g. in the developer notes, card description, testing tab, or as tasks.
Writing good acceptance criteria
Using the acceptance criteria, it should be feasible:
- To generate a test case with a clear success or failure outcome. The successful outcome of tests provides the quality assurance that the application works as intended.
- For an end user to utilize the acceptance criteria to define their own test (as part of User Acceptance Testing).
- To confirm what an application does and doesn’t do such that post-development issues can be clearly identified as either a bug (the functionality is not working) or a new feature request (existing functionality is working as originally defined in the acceptance criteria, but our needs have changed).
Styles of acceptance criteria
Historically, we have used two main styles for writing acceptance criteria: rule-oriented and scenario-oriented.
As we have refined our approach, we have convened around an agreed format that is a hybrid of both styles. This section first describes both approaches to illustrate how they differ, and then outlines how both should be combined to balance clarity with brevity.
An iterative approach to writing acceptance criteria
In some cases, especially where requirements definition is proving challenging, we switch approaches to help us look at requirements through a different lens. As an example, we might switch to use the scenario-oriented approach to help ensure we’re being meticulous and closing gaps in understanding. The requirements definition process might therefore look like this:
- Have an open discussion about requirements, without writing much down. Understand what led to this feature being needed, the ultimate aim, and how this benefits the business - so that contextual understanding is good.
- Capture the problem statement in the card’s description - focusing on the business problem to be solved, rather than jumping to a solution.
- Draw some wireframes on a board and agree the fundamentals of the user experience.
- Start writing some acceptance criteria using the rule-oriented style.
- Get stuck, and try writing criteria using the scenario-oriented style instead.
- Once a thorough understanding has been gleaned, refine criteria using the hybrid-style, such that it is more concise.
Rule-oriented style
The rule-oriented style simply sets out a number of conditions that can be met, presented as numbered bullet points.
Example:
1. The user will have the ability to set their username in the "Username" field.
1. The username is required i.e. it cannot be left blank.
1. The username has a maximum character length of 50 characters.
1. The username has a minimum character length of 2 characters.
1. There will be a "Submit" button on the form.
1. If the username is invalid and the user clicks "Submit", they will see an "Invalid password" message.
1. If the username is valid and the user clicks "Submit", they will see a "Username saved!" message.Scenario-oriented style (Gherkin syntax)
This approach utilises the Gherkin syntax.
This defines a “Given, When, Then” structure for writing requirements:
GIVEN [some precondition]
WHEN [I take a specific action]
THEN [I will see this outcome]“And” statements may be added as required:
GIVEN [some precondition]
AND [some other precondition]
WHEN [I take a specific action]
THEN [I will see this outcome]
AND [I will also see this other outcome]Examples:
GIVEN I am viewing the "Set username" page
AND I have not already set my username
WHEN I type characters in the "Username" field
THEN I will be prevented from typing more than 50 characters
GIVEN I am viewing the "Set username" page
AND I have not already set my username
AND I have not typed any characters in the "Username" field
WHEN I click "Submit"
THEN I will receive a validation error that states "The username cannot be blank"
AND I will remain on the current pageNote that this syntax is more verbose than the “rule-oriented” approach, but in some cases it encourages evaluation of all logic branches and may make it easier to derive test cases.
Hybrid-style - combining rule-oriented and scenario-oriented styles
This style is the agreed Audacia standard.
This example illustrates how we can combine the two styles to get the best of both worlds:
# Scenario 1: Username is a required field when setting username
**GIVEN** I am viewing the "Set username" page
**AND** I have not already set my username
**AND** I have not typed any characters in the "Username" field
**WHEN** I click "Submit"
**THEN**...
1. I will receive a validation error that states "The username cannot be blank".
1. The validation message will appear below the "Submit" button, within a static panel (as opposed to a toast message, since we don't want the message to disappear after a few seconds).
1. The validation message will appear within the already-established validation message panel i.e. light red background with a red exclamation mark icon to the left of the message text.
1. A red border will appear around the "Username" field to indicate that this is the field with the validation error.
1. I will remain on the current page.
Some things to observe:
- The scenario title is clearly defined. This helps us ensure we’re being meticulous and considering all logic branches, and it also helps a Product Owner or SME get oriented with the scenario quickly.
- Scenarios are numbered such that they can be easily referenced.
- The “Given, When, Then” structure is used initially to set the scene and define the scenario in a clear and structured way, making the pre-conditions and workflow very clear. At the same time, the nuance of the outcome is captured in the rule-oriented style, which allows for a more concise but still structured way of defining the acceptance criteria i.e. the “detail” is nested, rather than being interspersed with the “Given, When, Then” statements.
Common pitfalls to avoid
Defining events in the "Given" (pre-conditions)
The GIVEN clause describes the state of the world before the action takes place. The WHEN clause describes the triggering action — the thing the user does or the real-world event that occurs that causes the outcome. A common mistake is placing that triggering action in GIVEN instead of WHEN, which causes the WHEN to describe the system’s internal response rather than a user action.
Don’t do this:
GIVEN I click "Submit" on the registration form
WHEN the system processes my request
THEN I should receive a confirmation email
AND I should be redirected to the account dashboard“I click Submit” is the triggering event — it belongs in WHEN. As a result of moving it to GIVEN, the WHEN here ends up describing an internal system behaviour rather than a user action, which makes the scenario harder to turn into a test case.
Do this instead:
GIVEN I have completed the registration form with valid details
WHEN I click "Submit"
THEN I will receive a confirmation email
AND I will be redirected to the account dashboardThe pre-condition describes the state of the world (“the form is filled in with valid details”), and the WHEN describes the single user action that triggers the outcome.
Defining pre-conditions in the "When" (the event/action)
The WHEN clause should describe a single action or event that triggers the outcome. Background context and state should be moved into GIVEN.
Don’t do this:
GIVEN I am viewing the "Create Order" page
WHEN I have selected a customer, filled in the order lines, and I click "Submit"
THEN the order should be savedThe WHEN clause here conflates multiple pre-conditions (selecting a customer, filling in order lines) with the triggering action (clicking “Submit”).
Do this instead:
GIVEN I am viewing the "Create Order" page
AND I have selected a customer
AND I have added at least one order line
WHEN I click "Submit"
THEN the order should be savedEach pre-condition is isolated in a GIVEN or AND clause, and the WHEN describes only the single action that triggers the outcome.
Capturing too many cases under a single scenario
Each scenario should test one specific situation. Bundling multiple distinct cases into a single scenario makes it harder to pinpoint failures and easier to miss logic branches.
Don’t do this:
GIVEN I am viewing the "Create Order" page
WHEN I click "Submit"
THEN if I haven't selected a customer I should see a validation error
AND if I haven't added any order lines I should see a different validation error
AND if everything is valid the order should be saved and I should be redirectedThis scenario tries to cover three distinct situations — missing customer, missing order lines, and a fully valid submission — each of which has different pre-conditions and outcomes.
Do this instead — write a separate scenario for each case:
# Scenario 1: Customer is required when submitting an order
**GIVEN** I am viewing the "Create Order" page
**AND** I have not selected a customer
**WHEN** I click "Submit"
**THEN**...
1. I will receive a validation error stating "A customer must be selected".
# Scenario 2: At least one order line is required when submitting an order
**GIVEN** I am viewing the "Create Order" page
**AND** I have selected a customer
**AND** I have not added any order lines
**WHEN** I click "Submit"
**THEN**...
1. I will receive a validation error stating "At least one order line is required".
# Scenario 3: Order is saved successfully when all required fields are provided
**GIVEN** I am viewing the "Create Order" page
**AND** I have selected a customer
**AND** I have added at least one order line
**WHEN** I click "Submit"
**THEN**...
1. The order will be saved.
1. I will be redirected to the order confirmation page.Each scenario now has a clear title, a distinct set of pre-conditions, and an unambiguous outcome — making it straightforward to generate a test case for each.
Writing procedural steps instead of describing behaviour (imperative vs. declarative)
A common mistake — especially for those coming from a traditional test-case background — is to write scenarios as a sequence of low-level UI instructions rather than expressing the intended behaviour at a higher level. Scenarios written this way are brittle: any change to the UI (a button label, a field name, a page layout) requires every affected scenario to be updated, but you’ll need to use discretion to decide how specific to be.
Where applicable, don’t do this:
# Scenario: User can log in with valid credentials
**GIVEN** I am on the login page
**WHEN** I type "alice@example.com" into the "Email address" field
**AND** I type "P@ssword1" into the "Password" field
**AND** I click the "Sign in" button
**THEN**...
1. I am taken to the dashboard page.If the purpose of this card is not to define what a valid username/password is and is instead about implementing the login flow, do this instead:
# Scenario: User can log in with valid credentials
**GIVEN** I have a valid account
**WHEN** I log in with my credentials
**THEN**...
1. I am taken to the dashboard page.Vague or untestable "Then" outcomes
The THEN clause is where the verifiable outcome of the scenario is defined. If it is written vaguely — using words like “correctly”, “appropriately”, “as expected”, or “works” — then it is impossible to know whether the scenario has passed or failed, and the acceptance criteria provides no real quality assurance value.
Don’t do this:
# Scenario: Form validation works correctly
**GIVEN** I am viewing the "Create Account" form
**WHEN** I submit the form with invalid data
**THEN**...
1. The form should behave correctly.
1. The user should be informed appropriately.Neither outcome can be turned into a concrete test case — “correctly” and “appropriately” are subjective.
Do this instead:
# Scenario: Validation error is shown when email address is missing
**GIVEN** I am viewing the "Create Account" form
**AND** I have not entered an email address
**WHEN** I click "Submit"
**THEN**...
1. I will remain on the "Create Account" form.
1. I will see a validation error stating "Email address is required".
1. The "Email address" field will be highlighted with a red border.Each outcome is now specific, observable, and directly testable.
A note on usage of the "Developer Notes", "Questions and Clarifications" and "Discussion" sections of the card
- The “Developer Notes” section should not be used to capture criteria that may be considered acceptance criteria. If an implementation detail results in a new requirement being raised, this should be captured in the acceptance criteria and not hidden away in the developer notes. The acceptance criteria, in combination with any non-functional requirements established for the project, should provide sufficient information for a developer to understand what the desired outcome in full, and for test engineers or user acceptance testers to test the item in full and without ambiguity.
- The “Questions and Clarifications” section is a temporary holding place. Once a question has been answered that impacts the requirements, the acceptance criteria should be updated to reflect this and the question should be removed from the “Questions and Clarifications” section. This is to ensure that all requirements are captured in one place (the acceptance criteria) and that there is no ambiguity about where to look for the most up-to-date requirements.
- Similarly, the “Discussion” section is not a source of truth for requirements. If a potential requirement appears in the “Discussion” section but not “Acceptance Criteria”, then it is not a confirmed requirement and should not be considered as such. Requirements must be captured in the “Acceptance Criteria” section to be considered a signed-off requirement.
The INVEST mnemonic
We use the INVEST mnemonic) to confirm that items are:
- Independent - The PBI should be self-contained, in a way that there is no inherent dependency on another PBI.
- Negotiable - PBIs are not explicit contracts and should leave space for discussion.
- Valuable - A PBI must deliver value to the stakeholders.
- Estimable - You must always be able to estimate the size of a PBI.
- Small - PBIs should not be so big as to become impossible to plan/task/prioritize within a level of accuracy.
- Testable - The PBI or its related description must provide the necessary information to make test development possible.
Rules
The following rules should be followed when writing acceptance criteria. These will be split into 3 categories; Must, Should and Avoid. They are categorised under the AC ruleset for easy reference.
Use Numbers · AC-01 · MUST
Using enumerated AC must be done as it enables easy reference to a specific point.
This can include sub numbers. For example, 1.a.ii.
Do this
- New navigation menu item for Users
Don’t do this
- New navigation menu item for Users
Avoid Implementation Details · AC-02 · MUST
Criteria should be written from the perspective of the end user who gets value from the feature.
In most cases, the developer of a work item will be free to implement the feature as they see fit, so technical implementation details will generally be avoided in the acceptance criteria.
Do this
Given I am logged in as an administrator, when I go to the user management page, I can add a user
Don’t do this
- Add a new class called AddUserService in the Services/Users folder
There may be cases where this is unavoidable. For example, an implementation detail for which a decision has already been made might align with a specific element in the acceptance criteria. In these cases, this aspect should be clearly marked. An example:
- Given I am viewing the documents form, when I click then ”+” button, then I can upload a photo.
- Developer note: all documents will be stored in Azure blob storage. This aspect does not require QA/UAT testing.
Here it is made clear who the intended audience for the note is, and whether this aspect is testable.
If technical details need to be captured, these can be recorded in the Developer Notes section or within child Task work items.
Define Negative Outcomes · AC-03 · SHOULD
As well as defining what a work item does do, AC should also include negative outcomes where necessary to provide clarity.
Do this
i. When an invalid email address is entered, display an error message stating that this is the case.
Exclusions · AC-04 · SHOULD
Where necessary, include details of any work that will be explicitly excluded.
Do this
- This does not include the setting of the new user’s password (this will be covered as part of a later PBI #XXXXX).
Avoid Making Assumptions · AC-05 · MUST
Assumptions and ambiguity should be avoided. It should be possible for someone with limited system knowledge to understand the criteria.
Do this
- This functionality should only be accessible to users with the “Identity Manager” permission.
Don’t do this
- This functionality should be restricted as usual.
Concise and Structured · AC-06 · MUST
AC must be written concisely but in a structured way such that points aren’t easily missed. This might mean separating one point into multiple.
This leads to AC points that are easier to verify.
Do this
1. Upon entering an incorrect username/password a message should be displayed that
a. States the details provided were incorrect
b. Asks the user to try again
c. Advises them to use the forgot password functionality if still not rightDon’t do this
1. When a user enters an incorrect username/password combination then a message should be displayed to inform them of this and that they need to try again or use the forgot password functionality.Miscellaneous Considerations · AC-07
Performance · AC-07.1 · MUST
If there are any particular performance targets that need to be met either now or at a point in the future when the system is under a greater load, this should be captured.
Security · AC-07.2 · MUST
If there are any particular security considerations for a piece of functionality, these should be included.
For example, if there is a file upload, should they be checked for viruses?
Permissions · AC-07.3 · MUST
What permissions are needed to be able to use the functionality being defined?
Not Testable · AC-07.4 · SHOULD
If an element of the Acceptance Criteria is going to be impossible to test effectively, this should be recorded for the benefit of QA/UAT testers.
Workflow · AC-07.4 · SHOULD
If appropriate, provide a path through the system to get to this new feature e.g.
- When the user navigates to
Admin Menu>Users>Add User, they will see the “Add User” form.
Validation · AC-07.5 · MUST
Validation requirements must be defined where appropriate. If we’ve defined an input field:
- As a text input
- Does it have a minimum/maximum length?
- Are there any constraints e.g. “cannot contain hyphens or asterisks”?
- Can it be whitespace only e.g. ” ”?
- As a number input
- Does it have a minimum/maximum value?
- How many decimal places can the number be specified to?
- Is it optional or mandatory?
User Experience and Aesthetics · AC-07.6 · SHOULD
Are there any specific requirements in terms of the layout, colour scheme, amount of visible information on page etc.
Enduring · AC-07.7 · SHOULD
Is the functionality as defined enduring i.e. will this make sense in 6 months, 1 year or 2 years time?
Consistent Domain Terminology · AC-07.8 · MUST
Be very consistent when using critical domain language.
For example if we refer to “System Administrator” in one place, we should use this consistently everywhere – rather than using “Admin” in one place and “System Administrator” elsewhere.