In QA work, your most important output isn’t finding bugs. It’s communicating them clearly enough that they get fixed.

A bug that’s hard to reproduce from your report gets deprioritized. A bug described in ambiguous language gets misclassified. A critical issue buried in a vague paragraph gets treated as minor.

For Vietnamese QC engineers and leads working in English-language teams, bug report writing is a daily high-stakes communication task. Here’s the structure and language to do it well.

The Anatomy of a Good Bug Report

A bug report that gets acted on answers five questions clearly:

1. What happened? (Actual behavior) 2. What should have happened? (Expected behavior) 3. How do I reproduce it? (Steps) 4. How bad is it? (Severity and priority) 5. Proof? (Evidence — logs, screenshots, recording)

Every good bug report hits all five. If any is missing, the developer has to ask, and the bug waits.


Writing the Actual vs. Expected Behavior

The most common mistake in bug reports is mixing up observation and interpretation, or being too vague to act on.

Weak (vague, interpretive):

“The login page doesn’t work properly.”

Strong (specific, factual):

Actual: Clicking the login button with valid credentials redirects to /error with HTTP 500. No success message appears and the user session is not created. Expected: User should be redirected to /dashboard with a valid session cookie.

Notice the strong version:

  • Names the exact action (clicking login button)
  • Specifies the input state (valid credentials)
  • Describes what happens (redirect to /error, HTTP 500)
  • States the business impact (session not created)
  • States what should happen instead

The weak version tells the developer something is broken. The strong version tells them where, how, and what to verify after fixing.


Writing Reproduction Steps

Steps must be so clear that someone who has never used the feature before can reproduce the issue in one attempt. Write them as numbered instructions, each a single action.

Weak:

“Go to login and try to log in.”

Strong:

  1. Navigate to https://app.example.com/login
  2. Enter email: testuser@example.com (registered account with valid password)
  3. Enter password: Test@1234
  4. Click the Login button
  5. Observe the URL and page content after the redirect

→ Issue occurs at step 4: page redirects to /error instead of /dashboard

The arrow line at the end — “issue occurs at step X” — is a small addition that saves the developer time. They know exactly where to set a breakpoint.

When the bug is intermittent, say so explicitly and give the reproduction rate:

“Intermittent — reproduces approximately 3 out of 10 attempts. More consistent when the login form is submitted within 5 seconds of page load.”


Severity vs. Priority

These two terms are consistently misused, which causes confusion in triage meetings.

Severity = how bad is the impact on the system/user when it occurs?

  • Critical — system crash, data loss, security breach, complete feature failure
  • High — major feature broken, significant user impact, no workaround
  • Medium — feature partially broken, workaround exists
  • Low — cosmetic issue, minor inconvenience

Priority = how urgently does this need to be fixed relative to other work?

  • P1 — fix immediately / in this sprint
  • P2 — fix in next sprint
  • P3 — fix when capacity allows
  • P4 — nice to have / tech debt

A bug can be High Severity but Low Priority (a rare edge case that causes a crash vs. a common minor UX issue). Being able to explain this distinction in triage meetings is essential.

“This is High Severity — it causes complete session failure when it hits. But Priority 2 because it only affects users who submit the form within 5 seconds of page load, which is a narrow window. We can ship a fix next sprint.”


Language for Triage and Defect Review Meetings

Triage is where bugs get classified, assigned, and scheduled. Here’s the English for each phase.

Presenting a bug:

“This one came in from regression testing yesterday. It’s a High Severity — the payment confirmation email isn’t sent when the order is placed through the mobile API endpoint. Desktop checkout is fine. I’d suggest P1 because this affects all mobile users.”

Asking for a severity classification:

“How would you classify this one? I’ve marked it High but I’m not sure if it should be Critical given the data impact.”

Challenging a priority decision:

“I’d push back on P3 for this one — the affected flow is the password reset path, and that’s high-traffic. Can we revisit the priority?”

Discussing a workaround:

“There is a workaround — users can clear cookies and retry, and it works on the second attempt. So Severity goes down to Medium. But the UX is bad enough that I’d keep it P2.”

Closing a bug that can’t be reproduced:

“I’ve been unable to reproduce this in three separate attempts using the original reporter’s environment details. I’m going to mark this as Cannot Reproduce and add a comment asking the reporter for additional context. We can reopen if they provide more detail.”


Writing Sprint Defect Status Updates

During a sprint, defects need regular status updates. The format that works:

Bug #4821 — Payment confirmation email not sent (Mobile API) Status: In Progress Assigned: Minh (Backend) Root cause identified: The email service call is skipped when the order_source field is "mobile_api". Fix is in review — PR #312. ETA: EOD today, pending review pass.

Keep updates factual and forward-looking. “Working on it” is not a status update. “Root cause identified, fix in code review, ETA today” is.


🗣️ Key Phrases to Say Out Loud

  1. “The ACTUAL behavior is… the EXpected behavior is…” /ˈæktʃuəl ˈbiːhevjər … ɪkˈspɛktɪd/ — The core structure for every bug description

  2. “This rePROduces apPROximately three out of TEN attempts” /rɪˈpruːduːsɪz/ — Describing intermittent defects precisely

  3. “I’d PUSH back on P-THREE for this ONE” /aɪd pʊʃ bæk ɒn/ — Challenging a priority call diplomatically

  4. “There IS a WORKaround — BUT the UX is BAD enough that…” /ˈwɜːkəraʊnd/ — Conceding a workaround while arguing for the fix

  5. “Root CAUSE iDENtified — fix is in reVIEW” /ruːt kɔːz aɪˈdɛntɪfaɪd/ — Sprint status update format

  6. “I’m going to mark this CANnot rePROduce and ASK the rePORter for more conTEXT” — Standard language for closing unverified bugs

  7. “Can we reCLASSify the seVErity?” /riːˌklæsɪˈfaɪ … ˈsɛvərɪti/ — Requesting a triage decision change


📚 Vocabulary

1. Reproduce /ˌriːprəˈdjuːs/ (verb)

  • Meaning: To trigger the same bug again by following specific steps
  • Example: “I can’t reproduce this consistently — it only happens about 20% of the time.”

2. Regression /rɪˈɡrɛʃən/ (noun)

  • Meaning: A bug that reappears in code that previously worked correctly
  • Example: “This is a regression — it was working in v2.3 but broke in v2.4.”

3. Triage /ˈtraɪɑːʒ/ (noun/verb)

  • Meaning: The process of classifying and prioritizing bugs by severity and urgency
  • Example: “We do bug triage every Tuesday morning to classify new defects before sprint planning.”

4. Intermittent /ˌɪntəˈmɪtənt/ (adjective)

  • Meaning: A bug that does not occur consistently; happens only sometimes
  • Example: “This is intermittent — I’ve reproduced it 4 times but can’t find a reliable trigger.”

5. Workaround /ˈwɜːkəraʊnd/ (noun)

  • Meaning: A temporary solution that avoids the bug without fixing the root cause
  • Example: “There’s a workaround — refreshing the page before submitting clears the issue.”

6. Root cause /ruːt kɔːz/

  • Meaning: The underlying technical reason the bug occurs (not just the symptom)
  • Example: “Root cause: the session token expires after 30 minutes of inactivity, but the UI doesn’t handle the 401 response.”

7. Cannot reproduce (status label)

  • Meaning: The QC engineer followed all steps and the bug did not occur
  • Example: “Marking this ‘cannot reproduce’ — tested in Chrome 126, macOS, same account, three attempts.”

🎯 Practice Now

Exercise 1: Rewrite the Weak Bug Report

Here’s a poorly written bug report. Rewrite it using the five-question structure (actual/expected/steps/severity/evidence). Say your rewrite aloud.

“The search doesn’t work sometimes. When you search for a product name it shows nothing. Please fix.”

Your rewrite should cover:

  • Exact action taken (search for what, on which page)
  • What appeared (empty results? error message? spinner that never loads?)
  • What should have appeared
  • Numbered reproduction steps
  • Severity classification with reasoning

Sample strong version:

Title: Search returns empty results for valid product names on /catalog page Actual: Searching for “laptop stand” on the /catalog page returns 0 results. No error message is shown. Spinner appears for ~3 seconds then disappears. Expected: Should return at least 5 matching products (confirmed in database: 8 products contain “laptop stand” in the title). Steps:

  1. Navigate to https://app.example.com/catalog
  2. Type “laptop stand” into the search bar
  3. Press Enter or click the search icon
  4. Observe results — issue occurs at step 3

Severity: High — search is a primary user flow and returns no results for valid queries. Priority: P1 — affects all users on the catalog page. Evidence: Screenshot attached. Network tab shows the search API returns 200 with an empty results array despite valid matches in the database.

Exercise 2: Triage Meeting Role-Play

Read both sides of this triage dialogue aloud. Aim for natural pace — under 90 seconds total.

QC Lead: “Bug 4821 — the payment email. I’ve classified this High Severity, P1. Root cause is that the email service is skipped when order_source is mobile_api. All mobile checkouts are affected.”

Dev Lead: “Agreed on severity. But P1 might be aggressive — can users complete the transaction itself?”

QC Lead: “Yes, the payment goes through. They just don’t receive the confirmation. So strictly speaking there’s no data loss. I could move to P2 if we add a note about the business risk — no confirmation email means elevated support tickets.”

Dev Lead: “That’s reasonable. P2 it is, but flag for the next sprint. We should also add a monitoring alert for this email path.”

QC Lead: “Agreed. I’ll update the ticket and add it to the sprint backlog for review.”

Exercise 3: Write Your Own Status Update

Write a 3-sentence bug status update for a defect in your current (or imaginary) sprint. Include: current status, what was found, and ETA. Say it aloud.

Format: “Bug #[number] — [title]. Status: [current state]. [Finding or blocker]. ETA: [when].”


Bug reports are communication, not documentation. Write them for the developer who will read them at the end of a long day, with ten other tickets open. Make their job easy and your bugs get fixed first.

Export for reading

Comments