QA How-To
How to Write a Great Bug Report
Learn to write reproducible bug reports with precise titles, evidence, environment details, expected results, severity, and developer-ready examples.
1,971 words | Article schema | FAQ schema | Breadcrumb schema
Overview
A bug report is an asynchronous debugging handoff. The reporter has seen a failure, while the developer, product owner, and future verifier have not. A great report transfers the exact state and evidence needed to recreate the problem, explains the user impact without exaggeration, and distinguishes observed facts from theories. That saves more engineering time than any elaborate template used mechanically.
This guide follows a realistic checkout defect from discovery through a developer-ready report. You will learn to confirm the issue, write a searchable title, minimize reproduction steps, document actual and expected behavior, select environment details, attach useful evidence, and discuss severity without turning the ticket into an argument. It also covers intermittent failures, security-sensitive findings, duplicate search, and verification after a fix.
Investigate Before Opening the Ticket
Reproduce the issue at least once when safe, then vary one factor at a time. For a checkout total that changes after applying a coupon, repeat with the same cart, account, currency, browser, and coupon. Refresh and try again. Check whether the wrong total appears before submission, in the confirmation response, or only after retrieval. Your goal is not to prove a root cause. It is to identify the shortest stable path and the boundaries of the observed behavior.
Confirm the build and requirement. A surprising result may be an intentional change, stale test environment, expired promotion, or outdated acceptance criterion. Search existing open and recently closed defects using product area, error text, endpoint, and symptom. If a matching issue exists, add new evidence and environment details there instead of splitting investigation. Open a new report when the behavior or cause appears distinct, and link related tickets.
Write a Searchable One-Line Title
A strong title follows area, condition, and failure: `Checkout: order total excludes shipping after SAVE10 coupon is removed`. It tells a triager where the defect lives, what state triggers it, and what goes wrong. If platform matters, include it only when confirmed, such as `iOS Safari`. Add an error code when it is stable and distinctive. Keep the title factual and update it when investigation narrows the behavior.
Weak titles include `Checkout broken`, `Urgent bug`, `Total issue`, and a pasted exception with no context. They are difficult to search, impossible to prioritize from a backlog, and often describe emotion instead of behavior. Do not put severity declarations such as CRITICAL in the title unless team policy requires a prefix. Severity and priority have dedicated fields and should be supported by impact information.
- Name the affected capability first.
- Include the trigger or state that distinguishes the failure.
- Describe the observable wrong result.
- Mention browser, role, or locale only when it changes reproducibility.
- Avoid blame, diagnosis, and vague urgency words.
State Preconditions and Test Data
Preconditions describe state that exists before step one. For the coupon defect: a signed-in standard customer, a shippable item priced at $60, delivery to a region with $5 shipping, and active coupon SAVE10. Specify the account role and feature flag when relevant. If a record is created through an API or seed, provide a safe identifier and creation method. Do not hide essential setup in a sentence such as `use the usual test account`.
Use synthetic data and sanitize attachments. Share an order ID from a non-production environment, not customer email, payment details, access tokens, or full production payloads. If the failure occurs only with sensitive data, use the approved restricted reporting channel and limit visibility. Note time-sensitive state such as token age, subscription renewal date, or inventory level. A ticket that cannot recreate its starting state will quickly become Not Reproducible.
Reduce Steps to a Deterministic Sequence
Number actions from a clear starting location. Example: open the cart containing the specified item; apply SAVE10; continue to checkout and select standard shipping; remove SAVE10 from the order summary; submit the order. Stop at the first point where the defect becomes observable. If the incorrect total already appears before submit, say so and avoid creating unnecessary orders unless persistence is part of the defect.
Each step should be one meaningful user action with exact choices. Remove exploratory history, unrelated navigation, and duplicate actions that do not influence the result. Then test whether any precondition or step can be removed while preserving the failure. This minimization often reveals the important trigger and makes automated regression easier. If alternative sequences also fail, document the shortest primary path and summarize variants separately instead of mixing branches into one unreadable list.
Separate Actual and Expected Results
The actual result records what happened, including values and timing: `After the coupon is removed, the summary shows subtotal $60, shipping $5, total $60. POST /orders also sends total 60, and the confirmation page persists $60.` This is stronger than `shipping is wrong`. It distinguishes a display-only issue from incorrect data sent to the service. Quote exact error text when it is stable, but avoid replacing structured observations with a screenshot alone.
The expected result must come from a requirement or an accepted business rule: `Removing SAVE10 restores subtotal $60, retains shipping $5, and produces total $65 in the summary, request, and saved order.` Link the pricing criterion. Do not write `should work correctly`, repeat the actual result with `not`, or invent behavior. When the requirement is ambiguous, report the observed inconsistency and ask product to define the expected outcome before treating it as a confirmed defect.
Record the Environment and Reproduction Rate
Include application build or commit, environment, account role, browser and version, operating system or device, locale, currency, relevant flags, API version, and test time when these affect diagnosis. For mobile, include app build, device model, OS version, network state, and installation or upgrade path. A URL labeled staging is not enough because shared environments may deploy several times during an investigation.
Report frequency honestly, such as 5 of 5 attempts or 2 of 10 after a fresh login. Describe what changes between successful and failed attempts, including network speed, cache state, worker, data, or sequence. Never write `sometimes` without counts. For an intermittent issue, preserve failed and successful request IDs so developers can compare server traces. A low reproduction rate does not make the impact unimportant, but it changes the evidence and investigation strategy.
Attach Evidence That Answers Questions
A screenshot should capture the affected area, relevant values, and enough surrounding context to identify the screen. A short recording should start before the triggering action and stop after the result, with pauses trimmed. Add console errors, network request and response details, server correlation IDs, or automation traces when they illuminate the failure. Text evidence is searchable, so paste the small relevant log excerpt as text in addition to attaching a larger file.
More evidence is not automatically better. A ten-minute recording, entire unfiltered log, or full database export makes the recipient hunt for the signal and may leak secrets. Name attachments clearly, add timestamps, highlight the exact request, and redact tokens, cookies, passwords, personal data, and unrelated customer records. State which evidence proves which observation. Preserve original files when metadata matters, and follow retention rules for sensitive systems.
- Capture the first visible divergence, not only the final error page.
- Include request and correlation IDs for cross-service failures.
- Paste concise searchable log excerpts and attach the full sanitized log if needed.
- Redact secrets and personal information before uploading.
- Check that every attachment opens for the intended audience.
Assign Severity and Explain Impact
Severity describes the technical and user impact of the defect. Priority describes how soon the organization chooses to address it. A data-loss issue in an obscure administrative flow may be high severity but scheduled after a workaround and risk review. A low-severity legal typo on a launch page can receive high priority. Follow the team's scale rather than treating labels as universal definitions.
Support your recommendation with evidence: affected users or roles, frequency, financial or data consequence, availability of a workaround, recoverability, and release scope. For the missing shipping charge, quantify whether orders are accepted at the wrong total and whether customers can exploit it repeatedly. Avoid inflating severity to gain attention. Product and engineering may revise priority using broader business context, and that is normal collaboration rather than rejection of the report.
Handle Special Cases Responsibly
For a crash or data corruption risk, stop destructive reproduction after collecting safe minimum evidence and alert the appropriate owner. Security vulnerabilities should use the organization's private security process, not a public project board. Provide impact and reproducible evidence without accessing data beyond authorization. Accessibility defects should identify the violated user interaction and assistive technology context, not only a scanner rule number.
When a developer cannot reproduce, compare environments and starting state instead of debating. Pair briefly, capture a fresh recording, provide the exact build and data factory, and test permissions, flags, caches, and regional settings. If the issue no longer occurs, note the last failing build and close according to policy with evidence. `Cannot reproduce` is an investigation state, not proof that the reporter was wrong.
Verify the Fix and Close the Loop
Retest on the build containing the fix using the original steps and data shape. Confirm the exact actual result now matches the expected result, then explore adjacent risks introduced by the change. For the coupon calculation, test removal before and after shipping selection, another promotion type, tax calculation, refresh, and retrieval of the saved order. Focused regression should follow the change, not become a random full application pass.
Record the verification build, environment, result, and evidence. Reopen with new observations if the original behavior remains. Create a separate linked defect if a genuinely different problem appears. Add an automated or manual regression case at the cheapest reliable layer, preferably around the pricing service for calculation rules plus one UI integration case. A defect is fully useful when the team learns from it and reduces the chance of recurrence.
Frequently Asked Questions
What should a good bug report include?
Include a searchable title, preconditions, exact test data, minimal reproduction steps, actual and expected results, environment and build, reproduction rate, impact, and focused evidence. Add severity and links to requirements or related issues according to team policy.
How do I write steps to reproduce a bug?
Begin from a known state, number one meaningful action per step, specify exact choices and data, and stop where the problem first becomes visible. Remove actions that do not affect reproduction and summarize alternate paths separately.
What is the difference between bug severity and priority?
Severity measures technical and user impact. Priority represents how soon the organization plans to act after considering releases, customers, workarounds, and other business factors. They influence each other but are not the same field.
What evidence should I attach to a defect?
Attach a focused screenshot or short recording, relevant request details, correlation IDs, concise logs, or an automation trace when each helps explain the failure. Redact secrets and personal data, and avoid overwhelming the report with unrelated output.
How do I report an intermittent bug?
Give attempt counts, record failed and successful conditions, and preserve timestamps, request IDs, test data, and environment details for comparison. Do not hide low frequency or replace the evidence with the word sometimes.
What should I do if a developer says the bug is not reproducible?
Confirm the issue on the stated build, compare accounts, flags, locale, cache, network, and setup, then share fresh evidence or pair on reproduction. Treat the response as a clue that an environmental or state condition is still missing.