Skip to content

Test Case Derivation Methodology

This document describes a systematic approach to deriving exhaustive test case specifications from requirements and architectural blueprints. Apply this workflow at the start of any implementation task to ensure all edge cases and qualifiers are covered before writing code.

Analyze the architectural blueprint to identify the layers that require verification. In a standard Arda-style data authority module, these typically include:

  1. Business Logic (POJO): Internal invariants and property-level validations.
  2. Mutation Behaviors (Service Layer): Logic driven by operation qualifiers (e.g., STRICT, LAX, UPDATE).
  3. Cross-Entity Propagation: Side effects in linked services (e.g., role creation, record linking).
  4. Universal Constraints (Universe/Persistence): Multi-record constraints like uniqueness and bitemporal integrity.
  5. Transactional Integrity: Error handling and rollback behavior.

2. Deriving Test Cases (Exhaustive Criteria)

Section titled “2. Deriving Test Cases (Exhaustive Criteria)”

Use the following criteria to determine which tests are needed.

A. Invariant Testing (Positive and Negative)

Section titled “A. Invariant Testing (Positive and Negative)”

For every “Requirement” or “Invariant” in the domain model:

  • Create a test that satisfies the condition (Positive).
  • Create a test for every way the condition can be violated (Negative).

B. Matrix Selection (Combinatorial Mutations)

Section titled “B. Matrix Selection (Combinatorial Mutations)”

If the requirements use a “Mutation Behavior” table (Input vs. State vs. Qualifier):

  • Every cell in the table represents at least one test case.
  • If a cell has nested conditions (e.g., “if found… otherwise…”), test both branches.

Identify every “Propagation” outcome (e.g., “Create BusinessRole”, “Update Parent”) and create cases where:

  • The side effect should happen and succeed.
  • The side effect should happen but fails (verify atomicity and rollback).
  • The side effect should not happen.
  • Test uniqueness constraints across multiple records.
  • Test metadata validation (e.g., ensuring child records match parent EIds).

A test suite is considered sufficient when it satisfies the Complete Coverage Heuristic:

  1. All Logic Paths: Every if/when branch in the Service Layer implementation corresponds to a test case.
  2. All Error Types: Every AppError type produced by the code (NotFound, ArgumentValidation, Duplicate) is triggered at least once.
  3. Boundary Conditions: Null vs. Not-Null inputs are tested for every optional parameter.
  4. Bitemporal Logic: (If applicable) Both “Create” and “Update” are tested against the bitemporal coordinates (asOf time).

Organize test cases chronologically or by layer in a *-test-case-spec.md file using the following format:

  • ID: TC-[Layer]-[Sequence] (e.g., TC-IM-01 for Item Mutation).
  • Name: Brief description of the scenario.
  • Expectation: Clear statement of the expected outcome (e.g., “Expect: Success”, “Expect: Failure with AppError.NotFound”).
  1. Draft the Spec: Write the test case list before writing the implementation code.
  2. Review Against Requirements: Check every line of the requirements document; if a line specifies a behavior, there must be a corresponding test ID.
  3. Execution: Implement tests alongside code. Use the spec as a checklist for the Final Build Verification.