Finding and reporting bugs
Write bug reports clear enough that developers can fix them fast.
Topic 6 — Finding and reporting bugs
Goal: Write bug reports clear enough that developers can fix them fast.
Lesson 6.1 — "It's broken" is not a bug report
It's Nadia's second week at FreshCart, and she's found her first real bug. The checkout screen froze. Heart racing, she walks to Priya's desk — Priya being the senior developer who built checkout — and says, "Hey, the app crashed on me." Priya looks up, friendly but blank: "Okay… which screen? Doing what? On what phone?" Nadia doesn't know. She tried it once, it broke, and now she can't make it happen again.
That walk back to her desk taught her the most important thing in this job. Finding a bug is only half of it. The other half — the half that actually gets it fixed — is being able to hand the developer a way to see it for themselves.
The single most valuable quality of a bug report is reproducibility: clear, exact steps that let a developer make the bug happen on their own machine. A developer can't fix what they can't see. "The app is broken" is useless to Priya. "Here's exactly how to make it break, every time" is gold.
A developer can only fix a bug they can reproduce. Your real product is the recipe for the bug, not the bug itself.
Nadia, of all people, gets this fast. For eight years she was a pharmacy technician, and "it probably works" was never an acceptable answer when she was checking a dosage. She'd verify the drug, the strength, the count — every time, the same careful way. That instinct, the one that made her good behind the counter, is the exact instinct QA pays for.
Lesson 6.2 — The phrase that runs the whole job: "steps to reproduce"
Marcus, the lead QA engineer mentoring her, has a line he repeats so often Nadia starts hearing it in her sleep.
"The most valuable phrase in this job," he tells her, "is steps to reproduce."
Here's the logic. If you can reliably reproduce a bug, you can describe it — and a described bug is a fixable bug. If you can't reproduce it yet, that's not a dead end; that's your first task. Your job becomes finding exactly what triggers it.
Was it a specific input — the empty promo field, a coupon with a space in it, an order over a certain amount? A specific sequence — adding an item, removing it, then checking out? A specific device or build — only on the old iPhone, only after the latest deploy?
Nadia goes back to her frozen checkout. She tries it on the latest build, slowly, changing one thing at a time. On the fourth attempt it freezes again, and this time she catches it: it only happens when she applies a promo code, removes the last grocery item from the cart, then taps Pay. Remove the promo step, no freeze. She's found the trigger. Now she has something Priya can use.
That hunt — narrowing a vague "sometimes it breaks" down to a precise "do these three things and it breaks every time" — is the core detective work of testing.
Lesson 6.3 — Anatomy of a bug report Priya can act on
A professional bug report is a small, complete form rather than a paragraph of panic, and every field earns its place. Here is what Marcus has Nadia put in every one:
- Title — short and specific. It alone should tell a developer what breaks and when.
- Steps to reproduce — a numbered sequence, starting from a known state.
- Expected result — what should have happened.
- Actual result — what did happen (the bug).
- Environment — device, OS, browser and version, and which build. Many bugs only appear under specific conditions, so this is how Priya recreates yours.
- Evidence — a screenshot or, better, a short screen recording, plus any error message or log. On FreshCart's order-tracking map, a recording of the pin jumping the wrong way is worth a thousand words.
- Severity and priority — how bad the impact is, and how urgently it needs fixing (Topic 2).
Two of those last words trip up beginners, so pin them down now. Severity is the technical impact — does it crash, corrupt data, lose money, or just look slightly off? Priority is the business urgency — how soon should we fix it? They're different axes. A typo in the footer is low severity and low priority. But a promo bug that overcharges customers during a weekend sale can be moderate severity and top priority, because of timing and money. Tom, the product manager, is the one who usually sets priority, because he's weighing business urgency; Nadia proposes a severity based on what she observed.
Writing all this clearly is, at heart, a communication skill — which is wonderful news if you're a career-changer coming from a writing- or detail-heavy background. The QA engineer who files crisp, complete reports becomes the one developers actually want to receive bugs from.
Lesson 6.4 — Write it the way a stranger will read it
The first report Nadia drafts, she's proud of. Marcus reads it and gently rewrites the steps with her, and the lesson sticks.
Her draft said: "Apply promo, change the cart, pay — it freezes." True, but useless to someone who wasn't there. Steps to reproduce start from a known state and omit nothing implied. The reader is a stranger on a different machine who can't see your screen.
Here's the rewrite they do together:
- Open a fresh FreshCart build (v4.2.0) on iPhone 13, iOS 17.
- Add 3 grocery items to the cart.
- Go to Checkout.
- Enter promo code
SAVE10and tap Apply. - Tap the trash icon to remove the last grocery item.
- Tap Pay Now.
Notice the difference. Exact UI elements (the Apply button, the trash icon, Pay Now), exact values (SAVE10, 3 items), and a clear starting point. Nothing assumed. Marcus's rule: someone who has never touched FreshCart should be able to follow your steps like a recipe and hit the same wall you did.
One more habit baked into a good report: reproduce it 2–3 times before you file it. Not because you doubt yourself, but because the second and third runs are where you confirm it's real and lock in the exact path. Nadia's pharmacy reflex again — you don't report a dosage error you saw once and didn't double-check.
And the title? Her instinct was "checkout broken." Compare:
| Bad title | Good title |
|---|---|
| checkout broken | Checkout freezes when promo code is applied then last item is removed |
| payment bug | "Pay Now" stays disabled after re-adding a removed item |
The good title names the what and the when. A developer triaging fifty reports should know what yours is about without opening it.
Lesson 6.5 — Be a partner, not a prosecutor (and the habits that prove it)
Nadia is nervous about something deeper than formatting. Filing a bug feels like telling on Priya. What if Priya gets defensive? What if it sounds like an accusation?
Marcus reframes it for her, and it's the reframe that makes QA-and-dev relationships work. Be objective and blameless. You report behavior, never blame. Not "Priya messed up the promo logic" — instead, "the page returns a 500 error when the promo field is empty." State the steps, the expected, the actual. Let the facts carry it.
Report the behavior, not the human. "The page returns a 500 error" — never "the developer broke it."
The bug report describes the software, and Priya is on the same side as Nadia: both of them want FreshCart to work. Frame it that way and the partnership stays healthy, which over a career matters more than any single bug.
A handful of hygiene rules round out the professional habit:
- One bug per report. Don't cram three issues into one ticket — it turns tracking and fixing into a mess. Three bugs, three reports.
- Check it isn't a duplicate. Search the tracker first. Re-filing a known bug just adds noise.
- Reduce the steps. Find the shortest path that still triggers it. If the freeze happens with or without the third grocery item, drop that step. A tighter repro helps Priya pinpoint the cause faster.
- Hand off a verifiable repro. Your report's job ends where it's testable: anyone — Priya, you, or Dev's automation suite — can run your exact steps to confirm the fix and regression-check around it later. (You'll re-test and regression-check after the fix yourself; that verification loop is covered in Topics 4 and 8.)
Filing a clean, blameless, verifiable report is Topic 6's whole craft. Do that well and the rest of the loop — re-testing the fix, the regression pass, the bug's journey from Open to Closed — has something solid to stand on.
Worked example — From "it crashed" to a ticket Priya thanks her for
Friday afternoon. FreshCart is running a weekend promo, and Nadia notices something during exploratory testing: sometimes the order total looks wrong after she fiddles with a coupon. Vague. Exactly the kind of thing she walked to Priya's desk about in week two — except now she knows what to do.
First, she reproduces it. She tries different coupons, different carts, one variable at a time. The pattern emerges: when she applies SAVE10, then removes the last item, the 10% discount is recalculated against the old total, so the customer is charged too much. She runs it three times. Same result every time. Real bug, exact trigger, and it touches money during a sale — that's going to be high priority, and Tom will want it today.
Then she writes the report, every field doing its job:
- Title: "Promo discount calculated on pre-removal total — customer overcharged after removing an item"
- Steps: the six numbered steps from a fresh v4.2.0 build on iPhone 13, ending in the wrong total.
- Expected: discount recalculates against the new cart total; customer charged the correct amount.
- Actual: discount stays tied to the old total; customer overcharged by the value of the removed item's share.
- Environment: iPhone 13, iOS 17, FreshCart build v4.2.0.
- Evidence: a 12-second screen recording, plus a screenshot of the wrong total.
- Severity/Priority: severity high (real money), priority she flags for Tom to confirm — and he marks it top, because it's live on a sale weekend.
One bug, one ticket. She searches the tracker first — no duplicate. Priya picks it up, follows the recipe, sees the overcharge on the first try, and fixes it within the hour. When the build comes back, Nadia re-tests the exact steps (gone), then regression-checks that a normal promo with no removal still discounts correctly (it does). Dev adds it to the regression suite.
No drama, no blame, no back-and-forth. That's a QA engineer the dev team is glad to have.
Key terms
- Reproducibility — the quality of a bug that lets a developer recreate it on their own machine; the most important property of a report.
- Steps to reproduce — the numbered, exact sequence (from a known state) that triggers the bug.
- Expected vs. actual result — what should happen versus what did; the gap is the bug.
- Environment — the device, OS, browser/version, and build the bug appeared on.
- Severity — the technical impact of a bug (crash, data loss, cosmetic).
- Priority — the business urgency of fixing it; often set by the PM.
- Regression — re-checking that a fix didn't break something nearby (Topic 4).
- Reducing steps — trimming a repro down to the shortest path that still triggers the bug.
Try this
Take any app on your phone and try to break one small flow — search, a form, a cart. When something behaves oddly, don't note it yet. First reproduce it 2–3 times until you know the exact trigger. Then write a real bug report with all the fields: title, numbered steps from a known state, expected, actual, environment, and what evidence you'd attach. Read your steps back and ask Marcus's question: could a stranger on a different phone follow this like a recipe and hit the same wall? If not, tighten it. That single exercise is the skill this whole topic is built to give you.
Common pitfalls
- Reporting a bug you saw once. One sighting isn't a repro. If you can't make it happen again, your job is to find the trigger first — not to file "it crashed sometimes."
- Steps that assume what the reader can see. "Change the cart and pay" means nothing to someone on another machine. Name the exact buttons, values, and starting state.
- Cramming several bugs into one ticket. Three issues in one report makes every one of them harder to track, fix, and close. One bug, one report.
- Writing blame instead of behavior. "The dev broke promos" poisons the partnership and tells Priya nothing. "Returns a 500 when the promo field is empty" tells her exactly where to look.
Key takeaways
- A bug report's most important quality is reproducibility — clear steps to reproduce from a known state, confirmed 2–3 times.
- A complete report has title, steps, expected vs. actual, environment, evidence (screenshot/recording + any log), and severity/priority — where severity is technical impact and priority is business urgency.
- Be objective and blameless: report the behavior, never the person — it keeps the QA–dev partnership healthy.
- Hygiene: one bug per report, check for duplicates, and reduce the steps to the shortest path that triggers it.
- A good report is verifiable — your exact steps are what lets anyone confirm the fix later. (The re-test and regression pass after a fix are covered in Topics 4 and 8.)
Preparing your quiz…