Unit Testing Checklist

Scope and Setup

    Pin down the smallest meaningful unit — a pure function, a class method, a React component. If you find yourself needing to spin up a database or hit a real HTTP endpoint, you've crossed into integration territory and should split that into a separate suite.

    Match the repo's existing convention — Jest or Vitest for TypeScript, pytest for Python, RSpec for Ruby, JUnit for Java. Don't introduce a second framework into a monorepo without team buy-in; the maintenance cost shows up six months later.

    Decide upfront which dependencies are stubbed, mocked, or replaced with fakes. Network calls, the system clock, randomness, and the filesystem are the usual suspects. Over-mocking produces brittle tests that pass even when the unit is broken — only mock at module boundaries you actually own.

Test Case Design

    Cover the canonical inputs from the spec — the cases a product manager would describe in a demo. Use AAA structure (Arrange / Act / Assert) and keep each test focused on one behavior so a failure name tells you what broke.

    Empty inputs, null/undefined, zero, negative numbers, off-by-one boundaries, max-length strings, Unicode, leap-day dates, timezone edges. The bugs you'll ship are almost always in this list.

    Assert on the specific exception type and message — not just "throws". Include cases where collaborators reject (network timeout, DB constraint violation, malformed JSON) so the unit's error handling is exercised, not just the happy path.

    For parsers, serializers, and pure transformations, fast-check (JS) or Hypothesis (Python) catches edge cases example-based tests miss. Skip for UI components and side-effect-heavy code.

    Pin the seed for reproducibility and cap the run count so CI doesn't balloon. Write the property as an invariant the unit must always satisfy (round-trip, idempotence, ordering preservation), not as a restated example.

Implementation

    Test exported functions and class methods, not private internals. Tests bound to private implementation details break on every refactor and lose their value as a safety net.

    Freeze time with sinon fake timers, jest.useFakeTimers(), or freezegun. Seed random number generators. Avoid new Date() and Math.random() inside assertions — these are the leading cause of flaky tests.

    Prefer "returns 401 when the token is expired" over "test_validate()". The CI failure summary should read like a spec; an engineer who didn't write the test should know what broke without opening the file.

Local Execution and Coverage

    Order-dependent tests, leaked global state, and timing-sensitive assertions only show up on repeat. jest --runInBand followed by parallel runs catches both shared-state bugs and concurrency bugs.

    Most teams set 80% line / 70% branch as the floor for new code. Coverage is a smoke detector, not a fire alarm — a 95% covered unit with weak assertions is worse than 80% covered with sharp ones.

    Inspect the coverage report's uncovered branches — usually error handlers and defensive guards. If a branch genuinely can't be reached, delete it rather than add a contrived test to satisfy the metric.

Static Analysis and Quality Gates

    ESLint + Prettier, ruff + black, RuboCop — whichever the repo uses. Pre-commit hooks via husky or lefthook prevent lint errors from ever reaching CI.

    Type-check tests with the same strictness as production (tsc --noEmit, mypy). Loose any in tests masks the real type contract; if your mock satisfies any, the test isn't proving the unit accepts the real shape.

    Address new code smells, duplicated blocks, and cyclomatic complexity warnings introduced by this change. Existing debt isn't your problem to fix here — but don't add to it.

PR and Sign-Off

    List what's covered, what's intentionally not (and why), and the coverage delta. Reviewers shouldn't have to reconstruct your test strategy from the diff alone.

    Branch protection should require unit tests, lint, type check, and coverage to pass before merge. If a check is flaky, fix it or quarantine it — never get into the habit of re-running until green.

Use this template in Manifestly

Start a Free 14 Day Trial
Use Slack? Start your trial with one click

Related Software Development Checklists

Ready to take control of your recurring tasks?

Start Free 14-Day Trial


Use Slack? Sign up with one click

With Slack