Half the lifetime of a bug is spent in translation: the tester saw something, and the developer has to reproduce it. Good bug reports collapse that gap. After a couple of years of writing them — and watching which ones got fixed the same day and which ones bounced back as "cannot reproduce" — the pattern is clear. Bug reports developers act on are specific, minimal, and honest.
A bug report title formula that survives triage
Triage happens in a list view, so the title has to carry the whole story: [Area] What breaks — condition. "Checkout: total not updated after removing item (Android 14)" tells a developer what, where, and roughly why in one line. "App is broken" tells them nothing, except that reading the ticket will be work.
Minimal repro steps, expected vs actual
Cut the steps down to the shortest path that still reproduces the bug — every extra step is a place where the developer's environment can diverge from yours. Then state expected and actual behavior explicitly. This split matters because it separates fact from opinion: actual behavior is observable; expected behavior is a claim about the spec, and stating it plainly invites correction if you misread the requirement.
A bad report and a good one
Title: Checkout broken!!
Steps: Try to buy something, it doesn't work.
Please fix ASAP.
The same bug, written to be acted on:
Title: Checkout: total not updated after removing item (Android 14)
Steps:
1. Add two items to the cart
2. Open the cart and remove one item
3. Observe the total
Expected: total reflects the single remaining item
Actual: total still shows the sum of both items
Evidence: screen recording + API response attached
Environment: Android 14, Pixel 7, build 3.8.1 (staging)
Evidence, environment, and honest severity
Attach evidence in order of usefulness: a screen recording first, then relevant logs or the API response, then screenshots. A recording alone has settled more "cannot reproduce" debates for me than any amount of prose. Environment details — device, OS version, build number, backend environment — belong in every report, because "works on my machine" is usually true, on their machine.
Severity and priority are different axes, and both deserve honesty. Severity is impact; priority is urgency. A typo on the payment screen is low severity but high priority; a crash in a screen nobody visits may be the reverse. Inflating severity to get attention works exactly once, and then your reports get discounted forever.
One bug per ticket, and close the loop
Bundled tickets — "various UI issues on profile screen" — cannot be assigned, estimated, or verified cleanly. One of the five issues gets fixed and the ticket haunts the JIRA board for a sprint. File one bug per ticket, even when it feels bureaucratic; future you, running a retest, will be grateful.
Retest etiquette is the last mile. When a fix lands, verify it promptly, on the same environment and the same steps, and say exactly what you did: "retested on build 3.8.2, staging, steps above — fixed." If you find a new adjacent bug during the retest, that is a new ticket, not a reopened one. Reopening should mean one thing only: the original bug, still reproducible.
Takeaway: before you submit a report, reread it as the developer. Could you reproduce this bug in two minutes using only what is written there? If not, the report is not done.
None of this is glamorous, and all of it compounds. A tester whose reports are consistently minimal, evidenced, and honest ends up with a strange superpower: their tickets get picked up first.