Unit Testing: Component Isolation, AAA Pattern & F.I.R.S.T. Principles

Last Audited: 2026-08-18
Tier-1 Platform Core
In Plain Language

Isolated component testing strategies, Arrange-Act-Assert structure, F.I.R.S.T. principles, and risk-based coverage metrics paired with 'Don't Chase 100%'.

Unit Testing: The High-Speed Foundation of Code Quality

Unit tests form 70% to 80% of an effective testing pyramid. They evaluate individual functions, algorithms, data transformations, and state machines in complete isolation from databases, network sockets, and file systems. Because they execute in milliseconds, unit tests give developers instant feedback during active authoring.

The Arrange-Act-Assert (AAA) Architectural Pattern

Every unit test should be divided into three clear, easily readable sections:

1. Arrange (Setup)

Initialize inputs, create mock returns, and set up the test target with known starting state.

2. Act (Execute)

Invoke the single specific method or function under verification.

3. Assert (Verify)

Assert that expected return values or side-effects occurred exactly as specified.

TypeScript / Vitest Unit Test (AAA Format)
import { describe, it, expect } from 'vitest';
import { calculateInsulinDose } from '@/domain/calculator';

describe('calculateInsulinDose()', () => {
  it('calculates corrective bolus when blood glucose exceeds target threshold', () => {
    // 1. ARRANGE
    const currentBg = 180; // mg/dL
    const targetBg = 100;  // mg/dL
    const isf = 40;        // Insulin Sensitivity Factor: 1 unit drops BG by 40

    // 2. ACT
    const dose = calculateInsulinDose({ currentBg, targetBg, isf });

    // 3. ASSERT
    expect(dose).toBe(2.0); // (180 - 100) / 40 = 2.0 units
  });
});

The F.I.R.S.T. Principles of Unit Testing

FFast

Unit tests must execute in milliseconds so developers run them continuously on every file save.

IIndependent

Tests must never depend on the execution order or side-effects of other tests in the suite.

RRepeatable

Tests must yield identical results across all developer laptops, CI runners, and staging environments.

SSelf-Validating

Tests must output a clear boolean pass/fail with zero manual interpretation or log inspection.

TTimely

Tests should be written alongside or before production code (TDD/BDD) while requirements are fresh.

Risk-Based Test Coverage Guidance & "Don't Chase 100%"

Quality-over-Quantity Principle

In regulated environments, high code coverage is only meaningful when paired with risk-based assertions. Mandating a blanket 100% statement coverage target produces "coverage theater"—where developers write low-value tests that assert trivial getters and setters without checking edge cases, boundary parameters, or failure recovery.

Line / Statement Coverage
75% – 85% on Domain & Safety Logic

Measures which execution lines were visited during test suites. High value for algorithmic transforms, state machines, and medical calculations.

Prioritize critical domain decision trees over boilerplate configuration files, ORM schema declarations, or framework glue code.
ANTI-PATTERN WARNING
Avoid

❌ THE 100% STATEMENT TRAP: Mandating 100% statement coverage incentivizes engineers to write meaningless tests that execute trivial getters/setters without asserting behavior.

Branch / Decision Coverage
80% – 90% on Critical Branches

Verifies that every if/else branch, ternary condition, and switch case is traversed in both true and false evaluation paths.

Mandatory 100% branch coverage on all clinical risk mitigations and financial transaction pathways identified in the Risk Management File (ISO 14971).
ANTI-PATTERN WARNING
Avoid

❌ UNASSERTED BRANCH TRAP: Visiting an error branch without asserting that the exception was handled correctly or that the system entered a safe fail-state.

Function / Method Coverage
90%+ of Public API Exports

Confirms that every exported service method, API handler, and utility function is exercised by at least one dedicated test scenario.

Every public API endpoint must have both positive validation tests and negative fault-injection scenarios.
ANTI-PATTERN WARNING
Avoid

❌ HAPPY-PATH ONLY TRAP: Testing that a function returns 200 OK while completely ignoring negative parameter boundaries, timeouts, or network failures.

Requirement Traceability Coverage
Strict 100% Requirement Verification

Every documented software requirement (SRS ID) must map to at least one automated test case in the Traceability Matrix (RTM).

In regulated systems, requirement coverage is non-negotiable: 100% of functional requirements must have verified test evidence.
ANTI-PATTERN WARNING
Avoid

❌ ORPHAN CODE TRAP: Shipping code that has high line coverage but cannot be traced back to any approved design input requirement.

Try This With AI: AAA Unit Test Suite Generator
Unit Test Prompt

Use this prompt to generate clean, isolated AAA unit tests with happy paths, boundary checks, and null safety:

"Act as a Principal Test Engineer. Analyze the following function: [PASTE FUNCTION IMPLEMENTATION]. Write a complete Vitest/Jest unit test suite following the Arrange-Act-Assert (AAA) pattern and F.I.R.S.T. principles: (1) Happy path calculation tests, (2) Edge boundary conditions (zero, negative, max limits), (3) Null/undefined handling, and (4) Pure deterministic test doubles with zero external I/O."

Community Discussion & Feedback

Attributed peer feedback and official Netspective architecture notes.

Was this documentation helpful?(100% found this helpful • 0 ratings)

Leave Feedback or Question

○ Loading user info...
0/2000 chars

Discussion (0)

Loading discussion thread...