Skip to content
Independent guides for QA & test automationRSSEditorial policy
QA Vibes

Free downloads

QA and product owner templates

Nine files: bug reports and test cases for the people who find problems, and acceptance criteria, a definition of done, and a release scorecard for the people who decide what gets built. Every one comes with a worked example.

Why these, when free templates are everywhere

A blank template tells you which headings to write, not what goes under them. Each template here comes with a filled-in example from a real bug or a real test run, and the bug report sections are the ones our bug report grader scores.

The worked example scores 100 out of 100 in the grader. The blank template scores 15, because headings alone don't tell a developer anything.

What the grader checks

  • Specific title10
  • Numbered steps to reproduce20
  • Expected vs actual result15
  • Environment details10
  • Evidence attached15
  • Impact on users5
  • Severity and priority5
  • Neutral, factual tone10
  • Enough detail5
  • No leaked secrets5

For deciding what gets built

The acceptance criteria template is the one our acceptance criteria grader scores, and the worked example is the story from our acceptance criteria guide: the version it replaced scores 48 out of 100, and this one scores 100.

The definition of done lists the seven lines from acceptance criteria vs definition of done, with a column for where each one is enforced. A line with nothing in that column is a line that gets skipped under a deadline.

For deciding when to ship

The scorecard is the eleven checks from go or no-go, each with a column for the evidence rather than a tick. Fill in the thresholds before the build exists: a threshold written while looking at the results is a threshold that will be met.

It has columns for the owner of every waiver and the date it expires, because a waiver with no date is not a waiver — it is a permanent change to the standard, made without deciding to make one.

Bug reports and test cases

Bug report template (Markdown)

The template from the bug report grader. Paste it into Jira, Linear, a GitHub issue, or a chat message.

<What fails> in <where> for <who>

## Environment
- Build / version:
- Browser / device + OS:
- Environment (prod, staging) and account role:

## Steps to reproduce
1.
2.
3.

## Expected

## Actual

## Impact
Severity:
Priority:
Who is affected / workaround:

## Attachments
- Screenshot / video:
- Logs, HAR, or trace:

Worked example: a real bug report (Markdown)

The complete report of a real Sauce Demo checkout bug from our bug report guide. It scores 100 in the grader.

Checkout: Last Name input writes into First Name for problem_user

Environment: https://www.saucedemo.com, account problem_user, Chromium 153 (Playwright 1.63.0), Windows 11. Observed 2026-09-15.
Severity: Major
Priority: P2

Steps to reproduce:
1. Open https://www.saucedemo.com and log in as problem_user.
2. Click "Add to cart" on Sauce Labs Backpack.
3. Open the cart and click "Checkout".
4. Type "Ada" in First Name.
5. Type "Lovelace" in Last Name.
6. Type "10115" in Zip/Postal Code and click "Continue".

Expected result: First Name shows "Ada", Last Name shows "Lovelace", and Continue opens "Checkout: Overview".

Actual result: Each character typed in Last Name replaces the First Name value, so First Name shows "e" and Last Name stays empty. Continue shows "Error: Last Name is required" and checkout cannot continue. Pasting the whole value gives First Name "Lovelace" instead.

Reproducible: 6 of 6 attempts (3 typed, 3 pasted). standard_user is not affected.

Impact: Any customer on this account cannot complete checkout, so every order is blocked. There is no workaround in the UI.

Evidence: screenshot problem-user-last-name.png and Playwright trace trace.zip attached.

GitHub issue form (YAML)

The same sections as a GitHub issue form, with required fields. Save it as .github/ISSUE_TEMPLATE/bug_report.yml.

name: Bug report
description: Report something that doesn't work, with the details needed to reproduce and fix it.
title: "<What fails> in <where> for <who>"
labels: ["bug"]
body:
  - type: markdown
    attributes:
      value: |
        Describe what the software did, not who caused it. File one bug per report, and remove passwords and tokens from logs and screenshots.
  - type: textarea
    id: environment
    attributes:
      label: Environment
      description: Build or version, browser or device and OS, environment (production, staging), and account role.
      placeholder: "https://www.saucedemo.com, account problem_user, Chromium 153, Windows 11"
    validations:
      required: true
  - type: textarea
    id: steps
    attributes:
      label: Steps to reproduce
      description: Numbered steps that anyone can follow from a known starting page.
      value: |
        1.
        2.
        3.
    validations:
      required: true
  - type: textarea
    id: expected
    attributes:
      label: Expected result
    validations:
      required: true
  - type: textarea
    id: actual
    attributes:
      label: Actual result
      description: Quote exact error messages.
    validations:
      required: true
  - type: input
    id: reproducibility
    attributes:
      label: Reproducibility
      placeholder: "6 of 6 attempts; standard_user is not affected"
  - type: textarea
    id: impact
    attributes:
      label: Impact
      description: Who is affected, what it costs them, and whether there is a workaround.
    validations:
      required: true
  - type: dropdown
    id: severity
    attributes:
      label: Severity
      options:
        - Blocker
        - Critical
        - Major
        - Minor
        - Trivial
    validations:
      required: true
  - type: dropdown
    id: priority
    attributes:
      label: Priority
      options:
        - P1
        - P2
        - P3
        - P4
  - type: textarea
    id: evidence
    attributes:
      label: Evidence
      description: Screenshots, video, console logs, HAR files, or traces. You can attach files by dragging them into this field.

Test case template (CSV)

Columns for ID, case, technique, preconditions, input, steps, expected and actual result, and status.

ID,Case,Technique,Preconditions,Input,Steps,Expected result,Actual result,Status
TC-001,,,,,"1. 
2. 
3. ",,,Not run

Worked example: 10 checkout test cases (CSV)

The ten Sauce Demo checkout cases from our test case guide, with the results we observed.

ID,Case,Technique,Preconditions,Input (First / Last / Zip),"Result observed (Sauce Demo, standard_user)"
CHK-INFO-01,All fields valid,,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",Ada / Lovelace / 10115,"Continued to ""Checkout: Overview"""
CHK-INFO-02,First name missing,Equivalence partitioning,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",(empty) / Lovelace / 10115,"""Error: First Name is required"""
CHK-INFO-03,Last name missing,Equivalence partitioning,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",Ada / (empty) / 10115,"""Error: Last Name is required"""
CHK-INFO-04,Postal code missing,Equivalence partitioning,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",Ada / Lovelace / (empty),"""Error: Postal Code is required"""
CHK-INFO-05,Everything missing,,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",(empty) / (empty) / (empty),"""Error: First Name is required"" (only the first problem is shown)"
CHK-INFO-06,Shortest values,Boundary values,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",A / L / 1,Continued
CHK-INFO-07,Very long first name,Boundary values,"Logged in as standard_user with one product in the cart, on Checkout: Your Information","300 × ""A"" / Lovelace / 10115",Continued; all 300 characters kept
CHK-INFO-08,Spaces only in first name,Error guessing,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",3 spaces / Lovelace / 10115,Continued
CHK-INFO-09,Letters in postal code,Error guessing,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",Ada / Lovelace / ABCDE,Continued
CHK-INFO-10,Accents and emoji,Error guessing,"Logged in as standard_user with one product in the cart, on Checkout: Your Information",Zoë 🙂 / Łukasiewicz / 00-950,Continued

Deciding what to build and when to ship

Acceptance criteria template (Markdown)

The template from the acceptance criteria grader: a slot for the starting state, the action, and the result, plus the failure and the boundary most stories forget.

As a <role>, I want <goal> so that <reason>.

## Acceptance criteria

- Given <starting state and data>
  When <action>
  Then <what the user sees, receives, or can query afterwards>
- Given <the same state, invalid input>
  When <action>
  Then <the exact error message, and what is left unchanged>
- Given <the boundary: the limit, the empty case, the expired case>
  When <action>
  Then <result>

## Limits

- Response time / page size / retry count:

## Out of scope

-

Worked example: a story with checkable criteria (Markdown)

The rewritten story from our acceptance criteria guide. The version it replaced scores 48 in the grader; this one scores 100.

As a support agent handling refund calls, I want to filter the order list by status and date so that I can find a caller's order while they are still on the line.

## Acceptance criteria

- Given I am signed in as a support agent and the account has at least 20 orders
  When I select status "Refunded" and the date range 1-31 August
  Then only refunded orders placed in that range are listed, and the result count is displayed above the table
- Given a filter combination that matches no orders
  When the filter is applied
  Then the table is replaced by the message "No orders match these filters." and a Clear filters button is displayed
- Given a filter is applied
  When I reload the page
  Then the same filter is still applied and the URL contains it
- Given the order service is unavailable
  When I apply a filter
  Then the list I already had is kept and the message "Filters are unavailable right now. Try again." is displayed
- Given an account with 10000 orders
  When I apply any filter
  Then the filtered list is displayed within 2 seconds

## Out of scope

Exporting the filtered list; that is a separate story.

Definition of done (Markdown)

Seven lines that apply to every story, with a column for where each one is enforced. A line with nothing in that column is a line that gets skipped under a deadline.

# Definition of done

One standard for every story, not a per-story checklist. Work that does not meet it is not
released and is not shown at review: it goes back to the backlog.

Start from these seven and change them to fit your product. Keep it short — a definition of done
that runs to thirty items is one nobody reads.

- [ ] The change has an automated test that fails without it, and the suite passes in CI.
- [ ] Code has been reviewed by someone who did not write it.
- [ ] No new linter, type, or accessibility violations.
- [ ] New or changed behaviour that users see is documented where users will look.
- [ ] Feature flags default to off, and the change is deployable without a manual step.
- [ ] No known defect of severity Major or above is left open against the work.
- [ ] Observability: the new path emits whatever the team needs to tell whether it is working in production.

## Where each line is enforced

Fill this in. A line with nothing in the right-hand column is a line that will be skipped under a
deadline, and nobody will know.

| Line | Enforced by |
| --- | --- |
| The change has an automated test that fails without it, and the suite passes in CI |  |
| Code has been reviewed by someone who did not write it |  |
| No new linter, type, or accessibility violations |  |
| New or changed behaviour that users see is documented where users will look |  |
| Feature flags default to off, and the change is deployable without a manual step |  |
| No known defect of severity Major or above is left open against the work |  |
| Observability: the new path emits whatever the team needs to tell whether it is working in production |  |

## What does not belong here

- Anything specific to one story. That is an acceptance criterion.
- Anything nobody checks. It teaches the team the whole list is optional.
- Anything outside the team's control. A sign-off is a release gate, not a definition of done.
- Anything that cannot pass or fail, such as "code is clean".

Go/no-go release scorecard (CSV)

Eleven criteria with a column for the evidence, the owner, and the date a waiver expires. Fill in the thresholds before the build exists.

Criterion,Evidence required,Evidence,Met (yes/no/waived),Owner,Resolve by (if waived)
"One named release owner, and they are in the room.",Name,,,,
Every criterion has a threshold that was written before the results were known.,Date the thresholds were agreed,,,,
"Test results are per suite, per build, with reruns and skips visible.","Build id, suite, pass/fail, rerun count, approved skips",,,,
"Open defects are listed by severity, with the workaround for each.",Link to the filtered list; count at Blocker and Major,,,,
Non-functional readings are next to the thresholds they were meant to meet.,"Reading and threshold, e.g. p95 740 ms against 800 ms",,,,
"Rollback has been rehearsed, with a known duration.",Date last rehearsed and how long it took,,,,
Someone is named to watch a named signal for the first hours after release.,"Name, signal, and for how long",,,,
Support has the release note and the known-issue workarounds.,"Confirmed by whom, and when",,,,
"Reduced scope was considered explicitly, not just go or hold.",What could ship without the part that is not ready,,,,
"Every waiver has a named owner, a mitigation, and a date.","One row per waiver, filled in below",,,,
The decision and its evidence are recorded where the next release can read them.,Where,,,,

Decision (go / go with reduced scope / hold),,,,,
Decided by,,,,,
Date,,,,,

Learn to fill them in

How to write a high-quality bug report walks through the worked example line by line, and how to write effective test cases explains the techniques behind the ten checkout cases.

What we checked, and what we didn't

Our tests check that the worked examples match the published articles and still score as stated, that the CSV rows match the article's table, and that the issue form follows GitHub's issue form syntax. We haven't rendered the issue form in a GitHub repository. Its bug label must already exist in yours.