Skip to content
All posts
April 2, 20265 min read

What Makes a Good Bug Report (That Developers Actually Respect)

Bad bug reports waste everyone's time. Good ones get fixed fast. Here's the exact structure of a bug report that developers can act on immediately, with real examples of what bad vs good looks like.

TestingBug ReportsBest PracticesEngineering
Share:

A bad bug report is almost worse than no bug report.

It creates back-and-forth. It gets marked as "can't reproduce." It sits in a backlog for weeks because nobody wants to deal with the ambiguity. The developer moves on to other work. The bug ships to production.

A good bug report gets fixed the same day. Here's the difference.


The Anatomy of a Good Bug Report

Every good bug report answers five questions:

  1. What were you doing? (steps to reproduce)
  2. What did you expect to happen? (expected behavior)
  3. What actually happened? (actual behavior)
  4. Can you prove it? (evidence: screenshot, video, log)
  5. How bad is it? (severity + impact)

If your report can't answer all five, it's not ready to file.


Bad vs Good: Real Examples

Bad Report

code
Title: App crashes on checkout

Description:
The app crashes when trying to checkout. 
Please fix ASAP.

What happens with this report:

  • Developer opens it and immediately asks: "What device? What OS? What items were in the cart? What payment method? When did this start?"
  • QA comes back 2 days later with answers
  • Developer tries to reproduce, can't, asks more questions
  • Bug sits in limbo for a week

Good Report

code
Title: App crashes when applying promo code during checkout (Android 13, Pixel 6)

Environment:
- Device: Google Pixel 6
- OS: Android 13 (build TQ3A.230805.001)
- App version: 2.4.1 (build 241)
- Reproducibility: 4/4 attempts

Steps to Reproduce:
1. Add any item to cart (tested with item ID #1045 - Blue T-Shirt)
2. Tap "Checkout"
3. On the payment screen, tap "Enter promo code"
4. Enter "SAVE10" and tap "Apply"
5. App crashes immediately

Expected Behavior:
Promo code is validated, 10% discount applied to order total

Actual Behavior:
App crashes with no error message. Returns to home screen.

Evidence:
- [Screen recording attached: checkout-crash-2026-05-02.mp4]
- Crash log from logcat attached below

Crash Log:
FATAL EXCEPTION: main
Process: com.example.app, PID: 12345
java.lang.NullPointerException: Attempt to invoke virtual method 
'java.lang.String com.example.app.models.PromoCode.getDiscountType()' 
on a null object reference
    at com.example.app.checkout.CheckoutViewModel.applyPromoCode(CheckoutViewModel.kt:142)

Severity: High
Impact: Users cannot complete purchases using promo codes. 
Affects ~15% of our active promotions currently running.

What happens with this report:

  • Developer opens it, sees the stack trace, knows exactly which line
  • Fixes in 30 minutes
  • Never needs to ask a single follow-up question

The Five Elements in Detail

1. Steps to Reproduce

The most important part. If a developer can't reproduce the bug, they can't fix it.

Rules for good steps:

  • Number them sequentially
  • Be specific: "tap the blue button" not "go to settings"
  • Include the starting state: "Logged in as a free user with 3 items in cart"
  • Note any preconditions: "This only happens on first launch after a fresh install"
  • Test them yourself — walk through your own steps and confirm the bug appears before filing

[!WARNING] "Random" is not a valid reproduction rate. If a bug appears randomly, include the reproduction rate ("3 out of 10 attempts") and document all the variations you've tried. "Random" tells the developer nothing they can act on.

2. Expected vs Actual Behavior

These should be one sentence each. Clear, factual, no opinion.

Bad:

code
Expected: It should work
Actual: It doesn't work and it's really bad

Good:

code
Expected: Promo code "SAVE10" is validated and 10% discount shown on order total
Actual: App crashes immediately after tapping "Apply"

3. Environment

Bugs are often environment-specific. Without this, a developer fixes it on their machine and marks it resolved — but it still fails on the affected hardware.

Required:

  • Device model
  • OS version
  • App version and build number
  • Network conditions (if relevant)
  • Account type (if the app has tiers)

For Android specifically, include:

code
Device: Samsung Galaxy A52
OS: Android 12 (One UI 4.1)
App: 2.4.1 (241)
Network: Wi-Fi (5GHz)
Account: Free tier, 30 days since registration

4. Evidence

A screenshot shows the result. A screen recording shows the steps. A log file shows the cause.

Use all three when the bug is worth fixing. At minimum, use one.

For crashes: Always attach logcat output. Even if you don't understand it, the developer will. A stack trace cuts debugging time from hours to minutes.

bash
# Capture logcat for a specific app
adb logcat --pid=$(adb shell pidof com.your.package) > crash-log.txt

For UI bugs: Screen recording beats screenshots for anything that involves timing, animation, or sequence.

5. Severity and Business Impact

Severity describes the technical impact. Business impact describes who is affected and how badly.

SeverityTechnical Definition
CriticalApp crash, data loss, security issue
HighMajor feature broken, no workaround
MediumFeature partially broken, workaround exists
LowVisual/cosmetic issue, no functional impact

Then add business context: "This affects the checkout flow" is more motivating than "High severity" in isolation.


Platform-Specific Evidence Tips

Android

bash
# Full logcat with timestamp
adb logcat -v time > full-log.txt

# Filter to your app only
adb logcat --pid=$(adb shell pidof com.your.app) -v time > app-log.txt

# Capture ANR traces
adb pull /data/anr/traces.txt

Web / Signage

Always include:

  • Browser and version (
    code
    Chrome 124.0.6367.60
    )
  • Console errors (F12 → Console → screenshot)
  • Network tab for failed requests (F12 → Network → screenshot)
  • code
    curl -I [url]
    output for any header-related issues

Multi-Platform

If the bug affects some platforms and not others, document both:

code
Affects: Android 12 (Samsung One UI 4.1)
Does NOT affect: Android 13 (stock Pixel), iOS 17

This tells the developer it's likely an OS or OEM-specific issue, not a general regression.


The 60-Second Check

Before filing any bug report, ask yourself:

  • Can I reproduce this consistently?
  • Have I included exact steps, not a summary?
  • Have I noted the environment (device, OS, app version)?
  • Have I attached a screenshot or recording?
  • Have I described expected vs actual behavior in one sentence each?
  • Do I know the severity and who is impacted?

If any box is unchecked, spend 2 more minutes on the report. Those 2 minutes save the developer 30 minutes of investigation and save you from a "can't reproduce" close that buries the real issue.

The goal isn't a long report. It's a complete one.

Share:
S

Sudarshan Chaudhari

AI Systems Builder / Product Engineer

Bangkok, Thailand

Solo Android developer with 13+ years in QA, building Android apps, AI automation systems, and developer tools at SudarshanTechLabs.

Stay updated

Get new posts on Android, Kotlin, and solo dev straight to your inbox.

Newsletter preferences

Building something? Available for Android dev and QA consulting.

Work with me

Comments — powered by Giscus