A bug report template names the seven fields a triager needs before acting on a defect: environment, steps to reproduce, expected result, actual result, severity, priority, and the evidence that proves what happened. The field almost every template gets wrong is expected result. It gets listed, but never anchored to where the expectation should come from: the specification, not the reporter's opinion.
If you're here because an interviewer asked you to name the fields, a junior engineer's first ticket just got kicked back marked "need info," or an auditor wants to see your defect template, you're in the right place. This isn't the QA lead's strategy document on where testing effort should go, and it isn't the argument about whether your AI-generated tests are testing anything real. It's the artifact a triager spends ten seconds on before deciding whether your defect gets picked up today or bounced back.
How a team decides what happens to a defect once it's triaged is a separate question, one the triage playbook already covers and the defect life cycle covers in more depth than a template article should attempt. What follows is narrower: the fields, filled in twice on the exact same bug, and the one field that decides whether either version survives triage at all.
The bug report template: 7 fields, each one justified
Every bug report opens with a one-line title, and that part isn't interesting: name the defect specifically enough that a triager doesn't need to open the ticket to route it. "Promo code fails to discount checkout total," not "checkout bug." The seven fields below are the ones that actually decide the outcome, and each earns its place for a different reason.
| Field | Why it's on the template |
|---|---|
| Environment | Narrows reproduction to what matters |
| Steps to reproduce | Fewest actions that trigger the fault reliably |
| Expected result | Cites the specification, not a guess |
| Actual result | What the system verifiably did |
| Severity | How badly the product is broken |
| Priority | How soon it competes for engineering time |
| Attachments and evidence | Proves the actual result happened |
Severity and priority are the two fields most templates blur into one box. The distinction traces back to IEEE 1044-2009, the standard classification scheme for software anomalies: severity is a technical judgment, how badly the product is broken, and priority is a scheduling judgment, how soon it competes for engineering time against everything else in the backlog. A defect can be high severity and low priority (a crash in a feature nobody uses yet) or the reverse (a typo on the pricing page, live, during a launch). The cases where they pull apart are their own topic; here it's enough that the template asks for both, named separately, each justified on its own line rather than folded into one guess.
How to write a bug report: the same defect, twice
Here's one defect, filed twice, same day, same product. The bug: a valid promo code returns success from the API but never reduces the checkout total. The difference between the two reports isn't the defect. It's which fields got filled in as an afterthought and which got filled in as evidence.
The two animated inputs are complementary: a failing run establishes what happened, while the specification establishes what the product was expected to do.
The bad version. Title: "Promo code doesn't work." Environment: not specified. Steps to reproduce: "Go to checkout, put in a promo code, nothing happens." Expected result: "It should apply the discount." Actual result: "Nothing happens." Severity: not set. Priority: "ASAP."
The good version. Title: "Valid promo code SAVE10 does not reduce checkout total (REQ-CART-114)." Environment: Chrome 127 on macOS 14.5, staging, build 8f21a9c, at /cart/checkout. Steps to reproduce: add SKU-4471 ($40.00) to the cart, go to checkout, enter SAVE10 in the promo field, click Apply. Expected result: per REQ-CART-114 (Promotions spec, section 3.2), a valid unexpired code recalculates the total by its configured percentage before tax. SAVE10 is a 10% code, so $40.00 should become $36.00. Actual result: total stays at $40.00, no error shown, and the network tab shows POST /api/cart/promo returning 200 with { applied: true, discount: 0 }. Severity: major, checkout completes but a paid discount silently fails to apply. Priority: high, affects every use of the code this week and sits next to revenue.
Neither version invented information the other lacked. The good version just wrote down what was already true and verifiable: the build, the exact request and response, the spec section. Here's what actually flipped the triage outcome, field by field:
| Field | Bad version | Good version |
|---|---|---|
| Expected result | An opinion, not cited | Cites REQ-CART-114 directly |
| Environment | Left blank | Browser, build, and URL specified |
| Actual result | "Nothing happens," unverifiable | API payload proving discount is zero |
| Severity and priority | Guessed, marked "ASAP" | Justified: revenue impact, no crash |
A triager reading the bad version has three choices: guess, ask a clarifying question and lose a day, or close it "cannot reproduce." A triager reading the good version has one choice: assign it, because the report already did the work of proving a bug exists and pointing at where.
Expected result is a citation, not an opinion
This is the field a QA lead's process document skips and an interview question over-indexes on, which is exactly why it earns its own section instead of one line in a table.
In ISTQB terminology, "expected result" is not "what I wanted." It is a citation of the specification: a requirement ID, a spec line, a documented behavior, a prior release's screenshot, anything a triager can check independently of your judgment. When a report's expected result is "it should apply the discount," the only evidence behind it is that the reporter feels that way. That's not nothing, reporters are often right, but it's not verifiable on its own, and a triager cannot tell the difference between a correct hunch and a misunderstanding of the feature without doing the reporter's homework for them.
That line is not a joke about tone. It's a triage mechanism. A feature request gets prioritized against a roadmap. A bug gets prioritized against risk. Filing the wrong one under the wrong label is how "the discount should apply" sits in a backlog for a sprint while the actual defect, an API silently returning a zero-value discount, keeps costing revenue. The citation is what tells the triager which queue the ticket belongs in, and it's the one thing a reporter's certainty cannot substitute for.
How Autonoma files a failure
Everything above assumes a human wrote the report from what they observed clicking through the app. That's still true for most defects. But a growing share of end-to-end coverage now runs as generated tests against a live build, and when one of those fails, the question changes: what can the failure record supply on its own, and what still has to come from a person?
A generated test that fails can carry the entire machine-observable half of a report, because it executed the steps itself rather than reconstructing them from memory. That means the exact sequence of actions, the browser and viewport the run used, a trace and video of the failure, the DOM state at the moment things went wrong, the network activity (including a response like a discount coming back as zero), the console output, and the exact commit the run was pointed at. Anyone who has filed a "cannot reproduce" closure knows how much of a human bug report is really an attempt to reconstruct exactly that, after the fact, from memory. A failing generated test doesn't reconstruct it. It was there.
What it cannot supply is the other half: whether the behavior it observed is wrong. Our platform's tests are generated from your codebase, so they know what a flow is supposed to do in the sense of what the code implements, but "supposed to do" in the specification sense, the actual requirement, still lives with the people who wrote it. That's not a gap we're trying to engineer away. Filing and tracking the resulting defect is a bug tracker's job, Jira, Linear, whatever your team runs, and Autonoma isn't trying to replace that, or a QA hire, or your unit and contract test layers. It produces the failure record. The test results dashboard is where that trace, video, and network capture actually live once a run completes, in the same place your team already checks after CI.
What the machine cannot fill in
Lay a bug report's fields next to that list of what a failing generated test can attach, and six of the seven sort cleanly onto the machine-suppliable side: environment, steps to reproduce, actual result, and the attachments that prove it. Severity and priority can often be inferred too, once the impact is visible in the trace. One field refuses to sort there. Expected result requires knowing what the answer should have been, and that requires the specification, not the execution.
Most of the template existed because evidence was expensive to capture and had to be compressed into a paragraph typed from memory. Capturing it is no longer expensive.
Working out why the API returned a zero-value discount, whether it's a stale pricing cache, a rounding bug, or a misconfigured promo rule, is its own exercise, root cause analysis, and it starts after this report is filed, not inside it. The report's job was never to explain the bug. It was to prove one exists and point precisely at where, and that job doesn't change no matter who or what wrote the steps.
Get this right consistently across a team, human-filed or machine-filed, and the fields stop being a compliance exercise. A defect escape rate built on reports with cited expected results and real evidence actually measures what testing caught. One built on reports like the bad version measures how often someone bothered to write a citation, which is a different number wearing the same name. Autonoma exists for the half of that record a machine can actually observe: what ran, where, and what happened. The half that says what should have happened stays exactly where it always was, with the person who knows the spec.
Frequently Asked Questions
A bug report template is a fixed set of fields a defect report must fill in before it goes to triage: environment, steps to reproduce, expected result, actual result, severity, priority, and supporting evidence. Filling in all seven fields makes a report actionable, but expected result is the one that decides the triage outcome, because it has to cite the specification, a requirement ID, a spec line, or documented behavior, rather than state the reporter's opinion of what should have happened.
A bug report should include a specific one-line title, the environment it occurred in (browser, OS, build, and URL), the exact steps to reproduce it, an expected result that cites something concrete like a requirement ID or spec line, the actual result observed, a severity and priority, and any attachment (screenshot, video, log, or network capture) that proves the actual result happened. The title and steps get a report routed; the expected result and evidence get it acted on.
Write the steps to reproduce as the smallest number of actions that trigger the fault every time, specify the exact environment and build rather than leaving it implied, and anchor the expected result to a source outside your own judgment, a spec line, a requirement ID, or documented behavior, instead of a preference. Then attach evidence, a screenshot, a video, or a network log, that proves the actual result rather than just describing it. A good bug report lets a triager act without asking a clarifying question first.
Actual result is what the system verifiably did: the output, error, or behavior you observed, ideally backed by evidence like a screenshot or log. Expected result is what the system should have done according to the specification, not according to personal preference. When expected result is an opinion rather than a citation, the report functions as a feature request rather than a bug, because there is no independent way to confirm the behavior is actually wrong.
Missing or vague environment details are the most common cause: a defect that only appears on a specific browser, build, or account state looks unreproducible if that context was never recorded. Steps that skip a required action, rely on data the reporter had but the tester doesn't, or describe the flow from memory instead of a live retrace also lead to a not-reproducible closure, even when the underlying bug is real.
Yes, and it should be set separately from priority. Severity measures technical impact, how badly the product is broken, while priority measures scheduling urgency, how soon it should be worked relative to everything else. A crash in a rarely used feature can be high severity and low priority; a visible typo during a launch can be the reverse. Filing both, justified rather than guessed, is what lets a triager sort a backlog instead of re-deriving impact from scratch on every ticket.
Autonoma can give a bug report a strong, reproducible starting point by running planned end-to-end checks in a live preview environment and identifying the failing flow. Use that run evidence alongside the environment and build context when you create the report. The expected-result citation still belongs to the specification and the person who can verify it, while a bug tracker such as Jira or Linear remains the system that records and routes the work.




