RizTech Academy logo
RizTech Academy
Manual Testing in PracticeLesson 5 of 630 min

Writing a bug report that gets fixed, not closed as "cannot reproduce"

Finding a bug is only half the job; the other half is reporting it so it gets fixed. A badly written bug report is closed as "cannot reproduce" or "works for me", wasting your find and eroding your credibility. A well-written one lets a developer reproduce the problem in a minute and fix it. This lesson is how to write a bug report that gets fixed — arguably the single most important communication skill a QA has, because it is where your testing turns into actual improvement.

Why bug reports matter more than they seem

You can be the best tester in the world, but if the developer cannot understand or reproduce your report, the bug does not get fixed — and worse, a string of vague reports teaches developers to distrust and deprioritise your bugs. The report is the deliverable of much of your work; its quality determines whether your finding becomes a fix. The two failure modes to avoid:

  • "Cannot reproduce" / "works for me" — the developer cannot make it happen, usually because the report is missing the exact steps, data, or conditions. The bug is real, but it bounces back and dies.
  • The vague report — "top-up is broken", "it doesn't work sometimes" — that gives the developer nothing to act on and signals you did not investigate.

A great bug report prevents both: it makes the bug reproducible and understood.

What a good bug report contains

A report that gets fixed has these parts, and the middle three are the heart:

  • A clear, specific title — summarises the bug so it is understandable and searchable in one line. "Top-up charges the agent's float twice when the confirm button is double-tapped" — not "top-up bug".
  • Steps to reproduce — the exact sequence, numbered, from a known starting state, that makes the bug happen. This is the most important part. Precise enough that the developer follows them and sees the bug.
  • Expected result — what should have happened.
  • Actual result — what did happen (the bug). The pairing of expected vs actual is what makes it a bug report rather than a vague complaint — it shows the gap precisely.
  • Environment — where it happened: device/OS (Android 12, mid-range phone), app version/build, network (3G), account/role, and any relevant data. Bugs are often environment-specific; omitting this is the commonest cause of "works for me".
  • Evidence — a screenshot, a screen recording (invaluable for a flow or timing bug), the relevant log line or error, the request/response for an API bug.
  • Severity and priority — how bad and how urgent (the next lesson).

Reproducibility is everything

The core skill is making the bug reproducible — the developer follows your steps and sees it too. To get there:

  • Nail down the exact steps. Not "make a top-up and it fails" but "1. Log in as an agent with float ₹500. 2. Open a customer wallet. 3. Enter ₹100. 4. Tap Confirm twice quickly." The "twice quickly" is the detail that reproduces it — a vague report omits exactly the detail that matters.
  • Find the minimal reproduction. Strip the steps to the fewest that still trigger the bug. A 3-step repro is far more likely to be believed and fixed than a 15-step one with irrelevant actions.
  • Capture the conditions. If it only happens on 3G, on a specific device, with a specific amount, say so — that condition is part of the reproduction. "Only on 3G, not on wifi" is a huge clue for the developer, not a nuisance.
  • Reproduce it yourself first. Before filing, do it again from your own steps to confirm they work. If you cannot reproduce it from your own steps, the developer certainly cannot — refine until you can, or say honestly "intermittent, seen N times, here is what I was doing".

For a timing/flow bug (like the double-tap double-charge), a screen recording often communicates in seconds what paragraphs cannot — capture it.

Write it so a developer welcomes it

Tone and framing matter, because the report is a communication to a person (the working-with-developers lesson):

  • State facts, not blame. "Top-up charges twice on double-tap" — an observation, not "the top-up code is broken" or "why wasn't this caught?". You are reporting a fact about the product, not judging the developer.
  • Be specific and complete, so the developer does not have to come back with questions — a report they can act on immediately is one they will act on.
  • Include the impact where it helps prioritisation — "this moves real money twice; a customer is charged for a top-up they got once" tells the developer why it matters, which is exactly the money-app severity the next lesson covers.
  • One bug per report. Do not bundle several issues into one ticket — each needs its own title, steps and tracking. Bundled reports get partially fixed and half-closed.

A developer who receives a report with a crisp title, three clear steps, expected-vs-actual, the exact environment, and a screen recording can reproduce and fix the bug quickly — and comes to trust your reports, which means your future bugs get taken seriously. That trust, built one good report at a time, is a large part of a QA's effectiveness.

The double-charge report, as a model

Putting it together, the model report for the bug the exploratory session found:

Title: Top-up charges the agent's float twice when Confirm is double-tapped Environment: Android 12, [mid-range device], app build 142, 3G network, agent role Steps: 1. Log in as agent with float ₹500. 2. Open a customer wallet. 3. Enter ₹100. 4. Tap Confirm twice in quick succession. Expected: One top-up of ₹100; agent float becomes ₹400; customer credited ₹100 once. Actual: Two top-ups; agent float becomes ₹300; customer credited ₹100 (once) — ₹100 of float lost. Evidence: [screen recording], [the two transaction records in the log]. Severity: High — moves real money incorrectly; agent loses float on every double-tap.

That report is reproducible, understood, and impossible to dismiss — the developer sees exactly what to do. That is the standard to aim for on every bug you file.

Check your work

Why it matters. The report is the deliverable of your testing; its quality decides whether a finding becomes a fix. Avoid "cannot reproduce" (missing steps/data/conditions) and the vague report ("it's broken") — both waste the find and erode trust.

What it contains. Clear specific title; exact numbered steps to reproduce (the most important part); expected vs actual (what makes it a bug report); environment (device/OS/build/network/data — omitting this causes "works for me"); evidence (screenshot/recording/log/request); severity and priority.

Reproducibility is everything. Nail the exact steps (incl. the detail that triggers it, like "twice quickly"), find the minimal repro, capture the conditions (3G-only is a clue not a nuisance), and reproduce it yourself first (if you can't, the dev can't). Record timing/flow bugs.

Communicate well. Facts not blame; specific and complete (no follow-up questions needed); include impact (esp. money) for prioritisation; one bug per report. Good reports build developer trust in your bugs.

Practice

  1. Write a full bug report (title, environment, numbered steps, expected, actual, evidence, severity) for a bug you find or the double-charge example — make it reproducible.
  2. Take a vague report ("top-up doesn't work sometimes") and rewrite it into a reproducible one, inventing the specific steps/conditions it was missing.
  3. Reduce a 12-step reproduction to the minimal steps that still trigger the bug.
  4. For an intermittent bug, write the honest report (frequency, what you were doing, conditions) rather than claiming clean repro steps.
  5. Rewrite a blame-toned report ("the devs broke checkout again") as a neutral, factual observation a developer would welcome.
  6. Record a short screen capture of a flow/timing bug and note how much it communicates versus a written description.

Official documentation

Next: severity versus priority, and regression testing.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship