Bug Lifecycle

The process a defect goes through from discovery to closure. A well-defined lifecycle ensures bugs don't get lost, misunderstood, or marked done before they're verified.

The process a defect goes through from discovery to closure. A well-defined lifecycle ensures bugs don't get lost, misunderstood, or marked done before they're verified.


Standard Bug Lifecycle

[New] → [Assigned] → [Open] → [Fixed] → [Retest] → [Closed]
                        ↓                    ↓
                   [Deferred]          [Reopened]
                        ↓
                   [Rejected]
StateOwnerMeaning
NewQABug reported; not yet triaged
AssignedDev LeadTriage done; assigned to a developer
OpenDeveloperDeveloper is actively working on the fix
FixedDeveloperFix implemented; awaiting QA verification
RetestQAQA verifying the fix on the fixed build
ClosedQAFix verified; bug is done
ReopenedQAVerification failed; bug returned to developer
DeferredProduct OwnerAcknowledged; not fixing in this release
RejectedDeveloper / LeadNot a bug (expected behaviour, duplicate, or cannot reproduce)

Writing a Good Bug Report

A bug report must answer: what happened, what was expected, and how to reproduce it.

Template:

Title: [Short, specific, searchable — include the affected feature and the symptom]
       Good: "Checkout: 'Place Order' button disabled after promo code applied"
       Bad: "Button doesn't work"

Environment:
  - URL: staging.myapp.com
  - Browser: Chrome 124 / Safari 17
  - OS: macOS Sonoma
  - Build: v2.3.1-rc4

Severity: Critical / High / Medium / Low
Priority: P1 / P2 / P3 / P4

Steps to Reproduce:
  1. Navigate to /cart
  2. Add item SKU-123 (£29.99) to cart
  3. Apply promo code SUMMER20
  4. Click "Proceed to Checkout"
  5. Observe the "Place Order" button

Actual Result:
  "Place Order" button is greyed out and non-clickable after promo code applied.
  Error in console: "Uncaught TypeError: Cannot read properties of undefined (reading 'total')"

Expected Result:
  "Place Order" button is enabled and the order can be placed with the discount applied.

Attachments:
  - screenshot-checkout-bug.png
  - console-error.txt (browser console output)
  - network-requests.har (if relevant to API failures)

Reproducibility: 100% (reproduced 5/5 attempts)

Severity vs Priority

These are frequently confused. They measure different things.

Severity — technical impact on the application. Set by QA.

SeverityMeaningExample
CriticalApplication crash, data loss, security breachPayment not processed; data deleted
HighMajor feature broken, no workaroundLogin fails for 50% of users
MediumFeature partially broken, workaround existsExport CSV produces wrong column order
LowCosmetic, minor UX issueButton label has a typo

Priority — business urgency. How quickly it must be fixed. Set by Product Owner.

PriorityMeaning
P1Fix now (same day); blocks release or affects all users
P2Fix this sprint; high business impact
P3Fix next sprint; planned work
P4Nice to have; add to backlog

High severity ≠ high priority, and vice versa:

  • High severity, low priority: data corruption in a rarely used export feature used by 2 users
  • Low severity, high priority: CEO's name is misspelled on the homepage

Bug Triage

Regular meeting (or async process) where new bugs are assessed:

  1. Reproducibility — can the team reproduce it? Without reproduction, no fix.
  2. Severity — how bad is the impact?
  3. Priority — when must it be fixed?
  4. Assignment — which developer owns it?
  5. Version/sprint — target fix version

Bugs that cannot be reproduced move to Deferred with label "cannot reproduce". They're kept open so if another reporter hits the same issue, we reopen with additional context.


Reopening a Bug

When Retest fails. The fix didn't resolve the issue, or introduced a regression:

  1. Add a new retest comment with: build version, retest steps, actual result
  2. Attach new evidence (screenshot, log)
  3. Change status back to Reopened (→ Open)
  4. Tag the original developer

Do not close a bug without verifying it on the fixed build. "Fixed" means the developer believes it's fixed. "Closed" means QA confirmed it.


Defect Metrics

MetricFormulaWhy it matters
Defect Detection RateBugs found in testing / total bugs (testing + prod)Higher = better QA coverage
Defect Escape RateBugs found in prod / total bugsTarget: < 5%
Mean Time to DetectAvg time from intro to discoveryShorter = faster feedback
Mean Time to FixAvg time from report to closureIndicates dev velocity on bugs
Defect DensityBugs per 1,000 lines of codeCompare modules; spiky density = low quality area
Reopen RateReopened bugs / total closedHigh reopen rate = inadequate fixes or incomplete testing

Root Cause Classification

Tag each closed bug with a root cause. Trends reveal systemic problems.

Root CauseExample
Missing requirementFeature not in spec; nobody thought about it
Wrong implementationDev misunderstood the requirement
Integration failureComponent A and Component B had incompatible contracts
Environment issueOnly failed in staging because of config difference
Data issueSpecific input values triggered an unhandled path
RegressionExisting functionality broken by new code
Third-partyExternal service API changed

Monthly review of root cause distribution guides process improvement: many "missing requirement" bugs → invest in better upfront analysis; many "regression" bugs → invest in test coverage.


Bug Lifecycle in Jira

Jira workflow mapping:
  New         → To Do (or Backlog)
  Assigned    → In Progress
  Fixed       → In Review / Ready for QA
  Retest      → In Testing
  Closed      → Done
  Reopened    → In Progress (with "Reopened" label)
  Deferred    → Backlog (with "Deferred" fix version)

Custom Jira fields to add: Severity, Root Cause, Found in Version, Fixed in Version, Reproducibility.


Common Failure Cases

Closing a bug without QA verification on the fixed build Why: developers mark bugs Fixed based on local testing; the fix may not have been deployed to the environment QA uses, or the fix only addresses one reproduction path. Detect: reopen rate is above 15%, or bugs are found Closed without a retest comment from QA. Fix: enforce a workflow rule that only QA can transition a ticket from Fixed/Retest to Closed; require a retest comment with the build version and result.

Bug reports with vague steps that cannot be reproduced Why: "it crashed when I clicked around" is not reproducible; developers cannot fix what they cannot reproduce, so the bug lingers or gets rejected. Detect: developers mark bugs as "Cannot Reproduce" and move them to Deferred more than once per sprint. Fix: require all bug reports to include exact reproduction steps, environment details, build version, and reproducibility rate before the ticket leaves New status; use the template in this page.

Severity and priority conflated, leading to wrong triage decisions Why: when QA sets severity and priority to the same value reflexively, low-traffic critical data-loss bugs get deprioritised while highly visible cosmetic issues get P1 treatment. Detect: all Critical severity bugs are also P1 and all Low severity bugs are P4 — there are no severity/priority mismatches in the backlog. Fix: review severity and priority independently during triage; the product owner sets priority, QA sets severity, and the two dimensions are discussed explicitly for any mismatch.

"Cannot Reproduce" bugs closed instead of deferred Why: a bug that cannot be reproduced today may be caused by an intermittent condition (race condition, environment state, data edge case) that will recur; closing it loses the history. Detect: the same symptoms appear in a new bug report weeks later with no link to the original. Fix: move unreproduce bugs to Deferred with a "Cannot Reproduce" label rather than closing them; link new reports with similar symptoms to the original on creation.

Connections

Open Questions

  • What testing scenarios does this technique systematically miss?
  • How does this approach need to change when delivery cadence moves to continuous deployment?