Why Bug Report Quality Matters

A bug report is a communication tool between QA and development. A well-written bug report gets fixed fast. A poorly-written one gets ignored, bounced back for clarification, or deprioritized because nobody can reproduce it.

Time impact of bad bug reports:

  • Developer spends 30 minutes trying to reproduce a vague bug = wasted time
  • Bug bounces back to QA for more information = 1-2 day delay
  • Bug gets closed as “Cannot Reproduce” = the defect ships to production

Time impact of good bug reports:

  • Developer reads report, reproduces in 2 minutes, starts fixing immediately
  • No back-and-forth communication needed
  • Bug is fixed in the same sprint it was reported

Anatomy of a Perfect Bug Report

Title

The title should answer three questions: What failed, Where it failed, and When/How it failed.

Formula: [Component] Action fails with [Error] when [Condition]

Bad: “Login doesn’t work” Good: “Login form returns HTTP 500 when email address contains ‘+’ character”

Bad: “Cart problem” Good: “Cart total shows $0.00 after applying 100% discount coupon to single item”

Environment

Always specify:

  • Browser/app version
  • Operating system
  • Screen resolution (for UI bugs)
  • User role/permissions
  • API version (for backend bugs)

Preconditions

State the starting point clearly:

  • “User is logged in with role: Admin”
  • “Cart contains 2 items (total: $59.98)”
  • “Feature flag ’new-checkout’ is enabled”

Steps to Reproduce

Numbered, precise steps that anyone can follow:

1. Navigate to https://app.example.com/login
2. Enter "user+test@example.com" in the email field
3. Enter "ValidPass123!" in the password field
4. Click "Sign In" button

Rules:

  • One action per step
  • Include exact values (not “enter an email”)
  • Include exact URLs and navigation paths
  • Number every step
  • Start from a known state (preconditions)

Expected Result

What should happen according to requirements or common sense:

“User is redirected to the dashboard page. Welcome message displays the user’s name.”

Actual Result

What actually happens, with specific details:

“Page displays HTTP 500 Internal Server Error. Console shows: TypeError: Cannot read property 'split' of undefined at parseEmail (auth.js:47)

Evidence

Attach one or more:

  • Screenshot — annotated with arrows/highlights pointing to the issue
  • Video — screen recording showing the full reproduction
  • Console logs — browser console errors
  • Network trace — HAR file or specific request/response
  • Server logs — relevant error logs from the application

Severity and Priority

Classify the bug’s impact (covered in detail in the next lesson).

Additional Information

  • Frequency: Always / Intermittent (3 out of 10 attempts) / One time
  • Workaround: Is there an alternative path users can take?
  • Regression: Did this work in a previous version?
  • Related bugs: Links to similar or related issues

Real-World Bug Report Example

Title: Checkout fails with "Payment declined" for valid Visa cards
         ending in 0000 on Safari 17

Environment: Safari 17.2 / macOS Sonoma 14.2 / Production

Preconditions:
- User logged in as test_user_42
- Cart contains "Premium Plan" ($49.99/month)

Steps to Reproduce:
1. Navigate to /checkout
2. Select "Credit Card" payment method
3. Enter card: 4242 4242 4242 0000 (valid Stripe test card)
4. Enter expiry: 12/28
5. Enter CVC: 123
6. Click "Subscribe"

Expected Result:
Payment succeeds. User sees confirmation page with subscription details.

Actual Result:
Error banner: "Payment declined. Please try a different card."
Network tab shows POST /api/payments returns 422 with body:
{"error": "card_number_invalid", "message": "Card ending in 0000 rejected"}

Note: Same card works correctly on Chrome 120 and Firefox 121.
Safari-specific issue — likely related to how Safari handles
the card number input field formatting.

Frequency: Always on Safari 17. Never on Chrome/Firefox.
Workaround: User can complete checkout using Chrome or Firefox.
Regression: Worked on Safari 16. Broke after checkout redesign (v3.2.0).

Exercise: Fix These Bug Reports

Rewrite the following poorly-written bug reports:

Bad Report 1:

Title: Search broken
Description: When I search for things, it doesn't work right.

Bad Report 2:

Title: Slow page
Description: The page is too slow. Please fix.
Solution

Rewritten Report 1:

Title: Search returns 0 results for existing products when query
       contains special characters (&, <, >)

Environment: Chrome 120 / Windows 11 / QA environment

Preconditions:
- Product "AT&T Wireless Plan" exists in database
- User is on homepage

Steps to Reproduce:
1. Click search bar in header
2. Type "AT&T" in search field
3. Press Enter

Expected Result:
Search results show "AT&T Wireless Plan" and any other matching products.

Actual Result:
"0 results found for AT&T". The & character is being URL-encoded
as %26 but the search API does not decode it before matching.

Frequency: Always with &, <, > characters. Normal queries work fine.

Rewritten Report 2:

Title: Dashboard page takes 12 seconds to load with 500+ tasks
       (expected < 3 seconds)

Environment: Chrome 120 / macOS / Production

Preconditions:
- User account has 547 tasks across 12 projects

Steps to Reproduce:
1. Log in as user test_heavy_user (547 tasks)
2. Navigate to /dashboard
3. Measure page load time (DOMContentLoaded event)

Expected Result:
Dashboard loads in under 3 seconds per SLA requirements.

Actual Result:
DOMContentLoaded: 12.3 seconds. Network tab shows:
- GET /api/tasks returns 547 items in single response (4.2MB payload)
- No pagination. All tasks loaded at once.
- 3 waterfall API calls that could be parallelized

Evidence: [Performance profile attached] [HAR file attached]
Suggested cause: Missing pagination on tasks API endpoint.

Common Mistakes

  1. “It doesn’t work” — explain what specifically does not work
  2. No steps to reproduce — developers cannot fix what they cannot see
  3. Screenshots without context — always annotate what to look at
  4. Missing environment info — bugs are often browser or OS-specific
  5. Emotional language — “This terrible bug” does not help. Be factual
  6. Not checking if it is already reported — search existing bugs first

Key Takeaways

  • Bug reports are communication tools — write them for the developer who will fix the issue
  • Title formula: [Component] Action fails with [Error] when [Condition]
  • Steps to reproduce are the most critical section — one action per step, exact values
  • Always include expected vs actual result with specific details
  • Attach evidence: annotated screenshots, videos, console logs, network traces
  • Include environment, frequency, workaround, and regression information