Analysing Requirements for Testability — Ambiguity, Completeness and Consistency

Reading a requirements document is not the same as analysing it. Analysis is the systematic process of examining each requirement for testability — can you objectively verify whether this requirement is met? Ambiguous, incomplete, inconsistent, and untestable requirements all share one trait: they make it impossible to write a definitive test case with a clear pass/fail outcome. This lesson teaches you the structured techniques for finding these problems before they contaminate the development and testing process.

Four Testability Checks Every QA Engineer Must Apply

Apply these four checks to every requirement you review. If a requirement fails any of them, it needs revision before development begins.

# Testability analysis framework with real examples

TESTABILITY_CHECKS = [
    {
        "check": "1. Clarity — Is there only ONE way to interpret this?",
        "fail_keywords": ["appropriate", "user-friendly", "quickly", "efficiently",
                          "reasonable", "adequate", "intuitive", "minimal"],
        "bad_example": "REQ-12: The system should handle errors appropriately.",
        "problem": "'Appropriately' means different things to different people",
        "improved": "REQ-12: When a server error occurs, display error code and a "
                    "'Contact Support' link. Log the full stack trace to the error table.",
    },
    {
        "check": "2. Completeness — Are all scenarios covered?",
        "fail_keywords": ["etc.", "and so on", "as needed", "if applicable",
                          "to be determined", "TBD"],
        "bad_example": "REQ-18: The form validates email, phone, etc.",
        "problem": "'etc.' hides unknown scope — what other fields need validation?",
        "improved": "REQ-18: The form validates: email (RFC 5322), phone (E.164 format), "
                    "postal code (country-specific regex), and date of birth (18+ years).",
    },
    {
        "check": "3. Consistency — Does it contradict other requirements?",
        "fail_keywords": [],
        "bad_example": "REQ-05: Username max length is 20 characters. "
                       "REQ-31: Display the full username (up to 50 characters) on the profile.",
        "problem": "Two requirements specify different max lengths for the same field",
        "improved": "Resolve with PO: 'Username max length is 20 characters' applied "
                    "consistently across all references in the spec.",
    },
    {
        "check": "4. Measurability — Can the result be objectively verified?",
        "fail_keywords": ["good", "fast", "nice", "easy", "better", "improved",
                          "enhanced", "optimised"],
        "bad_example": "REQ-22: The dashboard should load fast.",
        "problem": "'Fast' has no measurable threshold — 2 sec? 5 sec? 10 sec?",
        "improved": "REQ-22: The dashboard shall load within 3 seconds at the 95th "
                    "percentile under a load of 500 concurrent users.",
    },
]

# Simulate analysing a requirements document
sample_requirements = [
    ("REQ-101", "Users can register with a valid email address", "PASS"),
    ("REQ-102", "The system should be user-friendly", "FAIL — untestable, subjective"),
    ("REQ-103", "Search results load quickly", "FAIL — no measurable threshold"),
    ("REQ-104", "Password must be 8-64 chars with 1 upper, 1 digit, 1 special", "PASS"),
    ("REQ-105", "Handle edge cases appropriately", "FAIL — ambiguous and incomplete"),
    ("REQ-106", "Order total = subtotal + tax (8%) - discount", "PASS"),
    ("REQ-107", "Support major browsers etc.", "FAIL — incomplete, 'etc.' hides scope"),
]

print("Testability Analysis Results")
print("=" * 65)
for req_id, text, result in sample_requirements:
    status = "✓" if result == "PASS" else "✗"
    print(f"  {status} {req_id}: {text}")
    if result != "PASS":
        print(f"           → {result}")

passed = sum(1 for _, _, r in sample_requirements if r == "PASS")
total = len(sample_requirements)
print(f"\n  Result: {passed}/{total} requirements are testable ({passed/total*100:.0f}%)")
print(f"  Action: {total - passed} requirements need revision before development")
Note: The “ambiguity trigger words” list — appropriate, user-friendly, quickly, efficiently, intuitive, minimal, reasonable — is your first-pass filter for untestable requirements. When you see any of these words in a specification, highlight them immediately. They are almost always a sign that the author has not defined measurable acceptance criteria. Replace them with specific, observable outcomes: “responds within 2 seconds,” “completes the workflow in 5 steps or fewer,” “displays a specific error message.”
Tip: Build a personal “testability checklist” that you apply to every requirements document. Include the four checks above plus domain-specific items for your industry (regulatory compliance for healthcare, PCI-DSS for payments, WCAG for public-facing apps). Print it and keep it next to your keyboard during reviews. Over time, spotting untestable requirements becomes automatic — but the checklist ensures you never skip a check when you are tired or rushed.
Warning: Do not rewrite requirements yourself and assume the product owner agrees. When you find an ambiguous requirement, flag it with a specific question: “REQ-103 says ‘load quickly’ — what is the target response time? I suggest 3 seconds at p95 under 500 concurrent users. Does that match the business expectation?” Let the product owner confirm or adjust. Silently reinterpreting requirements leads to tests that verify the wrong thing.

Common Mistakes

Mistake 1 — Accepting ambiguous requirements because “the developer will figure it out”

❌ Wrong: “REQ-103 says ‘load quickly’ — the developer probably knows what that means.”

✅ Correct: “REQ-103 is untestable as written. I will ask the product owner to define a specific threshold before the story enters a sprint.”

Mistake 2 — Only checking requirements individually without cross-referencing

❌ Wrong: Reviewing each requirement in isolation and approving them all without checking for contradictions between them.

✅ Correct: Cross-referencing related requirements (especially data fields, validation rules, and business rules) to catch inconsistencies where two requirements specify conflicting behaviour for the same feature.

🧠 Test Yourself

A requirement states: “The system should handle errors appropriately.” What is the primary problem with this requirement from a testability perspective?