Testing, Validation & Quality Assurance

Deriving Test Cases from Requirements

18 min Lesson 3 of 10

Deriving Test Cases from Requirements

A test that is not anchored to a requirement is a test with no purpose. Requirements-based testing is the discipline of tracing every test case back to a specific, documented requirement — ensuring that the system is verified against the business intent that drove its creation. For systems analysts, this skill sits at the intersection of two responsibilities you already own: writing clear requirements and guaranteeing they are verifiable. If a requirement cannot be tested, it was not well written.

This lesson walks through the full cycle: reading a requirement, extracting testable conditions from it, structuring those conditions into formal test cases, and measuring how completely your suite covers the functional scope.

What Makes a Requirement Testable?

Before you can derive test cases, you must confirm the requirement is testable. A testable requirement has four properties: it is specific (one behaviour per statement), measurable (defines expected outcomes in observable terms), achievable (within the system boundary), and unambiguous (no room for two interpretations). The mnemonic is SMAA.

Consider two versions of the same requirement for a clinic booking system:

  • Untestable: "The system shall allow users to book appointments easily."
  • Testable: "The system shall allow a registered patient to book an available appointment slot within 3 clicks from the home page, and shall confirm the booking via on-screen message and email within 30 seconds."

The second version gives you explicit test conditions: registration state, click count, slot availability, confirmation channel, and response time. Each condition becomes a potential test case.

From Requirement to Test Conditions

The first step is requirement decomposition: reading a requirement and listing every distinct condition it implies. Each condition represents a state of the world that the system must handle correctly.

Take this functional requirement from an online order management system:

REQ-027: When a customer submits an order, the system shall: (a) verify the customer account is active, (b) check that each ordered item has sufficient stock, (c) calculate the total including applicable tax, (d) decrement stock for each fulfilled item, (e) send an order confirmation email within 60 seconds, (f) reject the order with a descriptive error message if the account is suspended or any item is out of stock.

Decomposing REQ-027 yields these testable conditions:

  1. Active account + all items in stock → order accepted, stock decremented, email sent.
  2. Suspended account → order rejected, error message displayed.
  3. Active account, one or more items out of stock → order rejected, error identifies which items.
  4. Tax calculation is correct for each applicable product category.
  5. Confirmation email arrives within 60 seconds of submission.
  6. Stock level is decremented by exactly the ordered quantity.

Each condition above maps to at least one test case. This direct mapping is the heart of requirements-based testing.

The Structure of a Formal Test Case

A test case is not just an action — it is a complete specification of a single test scenario. A well-formed test case has six fields:

  • Test Case ID — unique identifier (e.g., TC-027-01).
  • Requirement Reference — the requirement(s) it verifies (e.g., REQ-027a, REQ-027d).
  • Preconditions — the state the system must be in before the test runs.
  • Test Steps — numbered actions the tester performs.
  • Test Data — specific inputs (account IDs, quantities, product codes).
  • Expected Result — the observable outcome that constitutes a pass.
Analyst responsibility: You do not need to write every test case yourself — that is often the test engineer's job. Your responsibility is to ensure every requirement produces at least one test condition and that the expected results in those test cases are directly derivable from your SRS language. Ambiguous requirements produce untestable expected results.
From Requirement to Test Case: Decomposition Flow Functional Requirement REQ-027: Order Submission Decompose Test Conditions C1: Active acct + stock OK C2: Suspended account C3: Item out of stock C4: Tax calculation C5: Email within 60 sec C6: Stock decrement Specify Formal Test Cases TC-027-01 (C1) Pre: active account, item qty=5 in stock Action: submit order for qty=2 Expected: order confirmed, stock=3, email sent TC-027-02 (C2) Pre: account status = suspended Expected: order rejected, error message shown TC-027-03 (C3) Pre: active acct, item X stock=0 Expected: rejected, names item X as OOS ... TC-027-04 through TC-027-06 ... Coverage Check All 6 conditions covered? 6/6 = 100% req coverage
Requirements decomposition flow: a single functional requirement yields testable conditions, each of which becomes a formal test case. Coverage is measured by the ratio of conditions tested.

Functional Requirements Coverage

Requirements coverage is the percentage of documented functional requirements for which at least one passing test case exists. It is your primary metric for test completeness at the analysis level and is calculated as:

Requirements Coverage (%) = (Number of requirements with at least one passing test case) ------------------------------------------------------------ × 100 (Total number of functional requirements in the SRS)

A 100% requirements coverage target means every line in your SRS has been exercised. In practice, safety-critical systems demand 100%; commercial software often targets 90–95% for functional requirements while deprioritising low-risk edge cases in the first release.

Coverage is not the same as quality. You can achieve 100% requirement coverage with shallow test cases that only test the happy path. Depth comes from techniques like equivalence partitioning and boundary value analysis (covered in the next lesson). Coverage tells you what you tested; test design techniques determine how well you tested it.

Mapping Requirements to Test Cases: A Practical Matrix

For a mid-sized project, analysts maintain a lightweight Requirements-to-Test mapping table (a precursor to the full Traceability Matrix covered in Lesson 6). Each row is a requirement; each column is a test case; a checkmark shows that the test case covers that requirement.

Requirements-to-Test Case Coverage Matrix (Logistics System) Req-to-Test Coverage Matrix — Logistics Order System (excerpt) Requirement TC-001 TC-002 TC-003 TC-004 TC-005 Coverage REQ-010: Driver login 2 cases ✔ REQ-011: Assign delivery 2 cases ✔ REQ-012: Status update 1 case ✔ REQ-013: Route optimise GAP — 0 cases! Coverage Summary 3 of 4 requirements covered = 75% (REQ-013 is a gap) Coverage: 75% ✔ = Test case covers this requirement ✕ = Not covered by this test case Red row = coverage gap (no test case at all for this requirement)
A requirements-to-test coverage matrix for a logistics system excerpt. REQ-013 has no test cases — a gap that must be addressed before release.

Handling Coverage Gaps

Any requirement with zero test cases is a coverage gap — a potential blind spot in the release. When you discover gaps, the response depends on risk:

  • High-risk gap: Write the missing test cases immediately. Block release until they pass.
  • Medium-risk gap: Document the gap as a known risk, assign an owner, and set a deadline for the next iteration.
  • Explicitly deferred requirement: Mark it as out-of-scope for this release in the traceability matrix so auditors can see the decision was deliberate, not accidental.
Never silently skip requirements. A missing test that nobody noticed is far more dangerous than a documented gap. Undiscovered gaps in authentication, data validation, or financial calculations can result in security breaches, data loss, or regulatory violations. The matrix makes gaps visible — which is the whole point.

Positive, Negative, and Edge Test Cases

For each test condition, you should design at least three categories of test cases:

  • Positive (happy path): valid inputs, expected conditions, normal flow — the system should succeed.
  • Negative (error path): invalid inputs, boundary violations, missing data — the system should fail gracefully with clear error messages.
  • Edge cases: boundary values, empty states, maximum loads, concurrent operations — where the system is most likely to behave unexpectedly.

For REQ-027 (order submission), a complete set covers the customer placing a valid order (positive), placing an order with a zero-quantity item (negative), and placing two simultaneous orders that together would exhaust the last unit of stock (edge). Each of these maps back to a sub-condition of the original requirement.

Analyst Checklist Before Handing Off Requirements

Before your SRS leaves the analysis phase, run this mental checklist on every functional requirement:

  1. Can I state the expected outcome in observable, measurable terms? If not, rewrite the requirement.
  2. Have I identified every distinct condition (sub-clauses, business rules, error paths) this requirement implies?
  3. Can each condition be tested independently, with a defined precondition and pass/fail criterion?
  4. Is there at least one test condition for the happy path, one for the error path, and one for the boundary?

Satisfying this checklist before handoff reduces test-design time significantly and virtually eliminates the frustrating back-and-forth where testers come to analysts asking what a requirement actually means. Clear requirements are, in the end, pre-tested requirements.