The most expensive defects in software are not the ones found during testing — they are the ones that are never found during testing because they were baked into the requirements from the start. A vague requirement like “the system should be fast” gets implemented differently by every developer, tested inconsistently by every tester, and surprises every stakeholder at demo time. Requirements analysis is the disciplined practice of examining specifications before code is written to identify ambiguities, gaps, contradictions and untestable statements. It is the single highest-ROI activity a QA engineer can perform, yet it is the one most frequently skipped.
The Cost of Requirements Defects — Why Upstream Matters
Research by IBM, NIST and the Standish Group consistently shows that defects originating in requirements are 10–100 times more expensive to fix when discovered in production than when caught during requirements review. A missing validation rule found during a review meeting costs a 15-minute conversation. The same missing rule found in production costs an incident response, a hotfix, regression testing, and customer trust.
# Cost multiplier of defects by discovery phase
# Based on IBM Systems Sciences Institute and NIST research
DEFECT_COST_MULTIPLIER = {
"Requirements Review": 1, # baseline — cheapest to fix
"Design Review": 5, # 5x more expensive
"Coding (Unit Test)": 10, # 10x
"Integration Testing": 20, # 20x
"System Testing": 50, # 50x
"Production": 100, # 100x — most expensive
}
# Example: a missing validation rule
defect = "Email field accepts invalid formats (missing @ symbol check)"
base_cost_hours = 0.25 # 15 minutes to fix during requirements review
print(f"Defect: {defect}")
print(f"\nCost to fix at each phase:")
print("=" * 55)
for phase, multiplier in DEFECT_COST_MULTIPLIER.items():
cost = base_cost_hours * multiplier
print(f" {phase:<25} {multiplier:>4}x → {cost:>6.1f} hours")
# Common categories of requirements defects
REQ_DEFECT_TYPES = [
{
"type": "Ambiguity",
"example": "'The system should respond quickly'",
"problem": "What does 'quickly' mean? 1 second? 5 seconds? 30 seconds?",
"fix": "'The system shall respond within 2 seconds at the 95th percentile'",
},
{
"type": "Incompleteness",
"example": "'Users can reset their password via email'",
"problem": "What about expired links? Invalid emails? Rate limiting?",
"fix": "Add acceptance criteria for each edge case and error condition",
},
{
"type": "Inconsistency",
"example": "Page 3: 'Max 50 chars'. Page 7: 'Max 100 chars' for the same field",
"problem": "Two requirements contradict each other for the same feature",
"fix": "Cross-reference related requirements and resolve conflicts with the PO",
},
{
"type": "Untestability",
"example": "'The UI should be user-friendly'",
"problem": "No objective criteria to verify — what does 'user-friendly' mean?",
"fix": "'95% of users complete checkout in under 3 minutes (usability test)'",
},
]
print("\n\nCommon Requirements Defect Types:")
print("=" * 55)
for rd in REQ_DEFECT_TYPES:
print(f"\n {rd['type']}")
print(f" Bad: {rd['example']}")
print(f" Problem: {rd['problem']}")
print(f" Better: {rd['fix']}")
Common Mistakes
Mistake 1 — Assuming requirements are final and correct when received
❌ Wrong: “The product owner wrote the requirements, so they must be correct and complete. My job starts when the build is ready.”
✅ Correct: “Requirements are a starting point for conversation, not a finished product. I review them critically for testability, completeness, and consistency, and raise questions before development begins.”
Mistake 2 — Only reviewing functional requirements and ignoring non-functional ones
❌ Wrong: Checking that every feature is described but never asking about performance targets, security constraints, or accessibility standards.
✅ Correct: Reviewing both functional requirements (what the system does) and non-functional requirements (how well it does it) — including performance, security, usability, and compliance expectations.