A vague bug report costs more than the bug. Every “can’t reproduce” round trip burns a developer’s focus and delays the fix by days. This guide gives you a practical template for bug reports that developers can act on the first time, with real examples, title formulas and the evidence that actually helps.
Key takeaways
- Good bug reports answer four questions fast: what broke, where, how to make it happen again and why it matters.
- The title is a search key: use the formula “[Area] Action leads to result on condition.”
- Exact environment details and numbered steps beat long narrative descriptions every time.
- Attach a screen recording plus logs for crashes; one minute of video saves an hour of guesswork.
- Set severity by user impact, state the reproduction rate and write one bug per report.
Why most bug reports fail developers
Developers rarely reject a bug because they disagree with it. Instead, they bounce it back because they cannot see it. The report is missing a build number, the steps skip a step, or the “actual result” is just “doesn’t work.”
Consequently, a ticket ping-pongs between QA and engineering. Each loop adds a day, and context fades every time. Meanwhile, the bug sits in the backlog looking smaller than it really is.
The fix is not more words. It is the right words, in the right order. In other words, a report should let a developer reproduce the issue in under five minutes without asking a single question.
The four questions every report must answer
- What broke? The observed behavior, stated precisely.
- Where? Device, OS, app build, network, account and locale.
- How do I see it? Numbered steps from a known starting state.
- Why does it matter? Severity, user impact and any workaround.

The anatomy of actionable bug reports
Use the same structure for every report. Because the fields are predictable, developers learn where to look, and your tracker becomes searchable. The table below is the template we use for crowd testers on TestGate.
| Field | What to write | Example |
|---|---|---|
| Title | Area, action, result and condition in one line | [Checkout] Tapping “Pay” twice charges card twice on slow 3G |
| Environment | Device, OS build, app version, network, locale | Pixel 8, Android 15, app 4.12.0 (build 1893), Vodafone DE 3G, de-DE |
| Preconditions | Account state and data needed | Logged-in user with one saved Visa card, cart over 50 EUR |
| Steps to reproduce | Numbered, one action per step | 1. Open cart. 2. Tap “Checkout.” 3. Tap “Pay” twice quickly. |
| Expected result | What should happen, per spec or common sense | One charge, button disabled after first tap |
| Actual result | What happened, with exact messages | Two charges of 54.90 EUR; two order confirmation emails |
| Reproduction rate | Successes out of attempts | 4 of 5 attempts |
| Evidence | Video, screenshots, logs, HAR file | Screen recording, logcat excerpt, order IDs |
| Severity | Impact level with one-line reason | Critical: real money charged twice |
Writing bug report titles that are easy to search
The title does most of the work. Developers scan titles in a list, product owners prioritize from titles, and duplicate detection depends on them. Therefore, treat the title as a search key, not a headline.
A reliable formula is: [Area] Action leads to result on condition.
Weak titles versus strong titles
- Weak: “App crashes.” Strong: “[Camera] App crashes when switching to front camera during video recording on iOS 18.1.”
- Weak: “Login broken.” Strong: “[Login] ‘Continue with Apple’ returns blank screen after Face ID on iPhone 15.”
- Weak: “Text issue in German.” Strong: “[Settings] ‘Benachrichtigungen’ label truncated on ‘Notifications’ toggle at largest font size.”
- Weak: “Payment error.” Strong: “[Checkout] UPI collect request expires before PIN screen loads on Jio 4G.”
Notice the pattern. Each strong title names a place, a trigger and a visible symptom. In addition, it includes the condition that makes the bug appear. As a result, anyone can guess whether a new report is a duplicate before opening it.
Steps to reproduce: the heart of good bug reports
Steps are where most bug reports fall apart. Testers skip “obvious” actions, combine several actions into one step, or start from an unclear state. However, nothing is obvious to someone who was not there.
Rules for reproduction steps
- Start from a known state. For example, “Fresh install, logged out” or “Logged in as test user tg-qa-14.”
- Write one action per step. “Tap ‘Profile'” is a step. “Go to profile and change your name” is two.
- Use the exact UI labels. Quote buttons and menu items as they appear on screen.
- Include data you typed. Note the name, amount, coupon code or file you used.
- Note timing when it matters. “Wait for the spinner, then immediately rotate the device.”
- Stop at the failure. The last step should be the one that triggers the bug.
Then, before you submit, follow your own steps once more on a clean state. If the bug does not appear, a step is missing. This single habit eliminates a large share of “cannot reproduce” replies.
Handling intermittent bugs
Some bugs appear only occasionally. Report them anyway, because intermittent crashes in production often hit thousands of users. State the reproduction rate, such as “3 of 10 attempts.” In addition, describe the conditions you suspect, for example battery saver on, poor signal or a backgrounded app. Finally, attach a recording of a failing attempt, not a passing one.
Evidence that makes bug reports self-explanatory
Evidence turns a claim into a fact. A short screen recording shows the timing, the taps and the exact state of the screen. For crashes and data issues, logs give developers the stack trace they need.
- Screen recording: 15 to 60 seconds, starting a few steps before the failure. Turn on “show taps” on Android.
- Screenshots: annotate the exact problem area. One focused image beats five full screens.
- Android logs: a logcat excerpt or a full bug report from Developer Options.
- iOS logs: the crash log from Settings, Privacy and Security, Analytics Data. See Apple’s guide to acquiring crash reports and diagnostic logs.
- Web: browser console errors and a HAR file from DevTools for network issues.
- Identifiers: order IDs, transaction references, user IDs and timestamps with time zone.
Expected versus actual: be specific
“Doesn’t work” is not an actual result. Instead, describe exactly what you saw. Quote error messages word for word, including codes such as “ERR_PAYMENT_DECLINED (402).” Note what you expected and where that expectation comes from, for example the spec, the design file or the behavior on another platform. If the app behaves correctly on iOS but not on Android, say so, because that comparison narrows the search instantly. Similarly, if the bug started with a specific build, name the last good build. Developers can then diff two versions instead of reading the whole codebase.
Severity, priority and impact in bug reports
Severity is about impact. Priority is about scheduling. Testers usually set severity, while product owners set priority. Mixing them up leads to “everything is critical” inflation, and inflated severity trains developers to ignore it.
| Severity | Definition | Example bug title |
|---|---|---|
| Critical | Data loss, security exposure, money impact or app unusable for many users | [Checkout] Klarna payment marked paid but order not created |
| High | Core flow broken with no reasonable workaround | [Sign-up] OTP SMS never arrives on Airtel India numbers |
| Medium | Feature broken but a workaround exists | [Search] Filters reset after returning from product page |
| Low | Cosmetic or minor usability issue | [Profile] Avatar misaligned in dark mode on Galaxy S24 |
Always add one line explaining the impact. For instance, “Blocks every new user in India from signing up” tells a product owner far more than the word “High.”
A complete example of an actionable bug report
Here is a full report written to the template. It is short, yet it leaves nothing to guess.
Title: [Checkout] iDEAL redirect returns to empty cart instead of order confirmation on Safari iOS 18
Environment: iPhone 14, iOS 18.0.1, Safari, web build 2026.09.12, KPN 4G, nl-NL
Preconditions: Guest user, one item in cart, delivery address in Utrecht
Steps: 1. Tap “Afrekenen.” 2. Choose iDEAL and select ING. 3. Approve payment in the ING app. 4. Tap “Terug naar winkel.”
Expected: Order confirmation page with order number
Actual: Empty cart page; payment shows as completed in ING; confirmation email arrives 4 minutes later
Rate: 5 of 5 on Safari; 0 of 5 on Chrome iOS
Evidence: Screen recording, HAR file, payment reference attached
Severity: High: users believe the order failed and may pay twice
Because the report compares Safari and Chrome, the developer immediately suspects session cookies lost during the cross-app redirect. That kind of clue is what shortens a fix from days to hours.
Bug report checklist before you hit submit
Run through this list every time. It takes 60 seconds, and it saves a round trip.
- Does the title follow “[Area] Action leads to result on condition”?
- Did you search for duplicates using the key words from your title?
- Are device, OS build, app version, network and locale all listed?
- Do the steps start from a known state, with one action each?
- Did you rerun the steps once on a clean state?
- Are expected and actual results specific, including exact error text?
- Is the reproduction rate stated?
- Is there a recording, and logs for crashes?
- Is severity set by impact, with a one-line reason?
- Does the report cover exactly one problem?
How a triage gate raises the bar
Even good testers miss details under time pressure. That is why on TestGate every report passes a triage gate. A test lead reproduces it, merges duplicates and sets severity before it syncs to Jira, Azure DevOps, Linear, GitHub or TestRail. You can see how that works on our platform page, and how it scales in our article on bug triage at scale. If you want to apply these skills as a paid tester, visit TestGate for testers.
Frequently asked questions
What should a good bug report include?
A clear title, the environment (device, OS, app version, network, locale), numbered steps to reproduce, expected and actual results, reproduction rate, and evidence such as a screen recording and logs. Severity and any workaround complete it.
What is the difference between severity and priority?
Severity describes the impact of the bug on users or the business. Priority describes how soon the team will fix it. A tester usually sets severity, while the product owner sets priority.
How do I report a bug that I cannot reproduce every time?
Report it anyway, and state the reproduction rate, for example 2 out of 10 attempts. Include everything you know about the conditions, plus logs and a recording of a failing attempt.
Should one bug report cover several problems?
No. Write one report per problem. Separate reports can be assigned, fixed and verified independently, and duplicates are much easier to detect.
Get bug reports your developers trust
Want every crowd finding reproduced, deduplicated and ready to fix when it lands in your backlog? Talk to us.



