# Testing

> Use when the project needs automated testing with Jest, Vitest, pytest, or similar frameworks

- Skill: `tomevault-io/testing-13` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/testing-13`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/testing-13/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/testing-13

---


# Testing Best Practices

## Test Structure

Follow the Arrange-Act-Assert pattern: set up the conditions, perform the action, check the result. Each test should verify one behavior. If a test name contains "and", it probably tests two things -- split it.

Name tests to describe behavior, not implementation: "returns empty array when no items match filter" not "test filterItems function". Good test names serve as documentation.

## Test-Driven Development

Write the test before the implementation. Start with the simplest failing test, write minimal code to make it pass, then refactor. This cycle (Red-Green-Refactor) prevents over-engineering and ensures every line of production code is covered.

When fixing bugs, write a test that reproduces the bug first. Then fix the code. The test proves the bug existed and prevents regression.

## What to Test

Test behavior, not implementation. Test public interfaces, not private methods. If you refactor internals without changing behavior, tests should still pass. Tests that break during refactoring are testing the wrong thing.

Focus coverage on: business logic, data transformations, error handling paths, edge cases (empty inputs, boundary values, null/undefined). Skip testing: framework boilerplate, simple getters/setters, third-party library behavior.

## Mocking

Mock external dependencies (APIs, databases, file system), not your own code. Over-mocking creates tests that pass even when the real system is broken. Use the lightest mock possible -- spy on a method rather than replacing an entire module.

Reset mocks between tests to prevent state leakage. In Jest/Vitest, use `beforeEach(() => { vi.clearAllMocks() })`. In pytest, fixtures handle cleanup automatically.

## Test Performance

Fast tests get run often. Slow tests get skipped. Keep unit tests under 100ms each. Isolate slow integration tests into a separate suite that runs less frequently.

Avoid `sleep` or timeouts in tests. Use fake timers (`vi.useFakeTimers()`) for time-dependent code. Wait for conditions with polling utilities, not fixed delays.

## Test Organization

Colocate tests with source files (`Button.tsx` next to `Button.test.tsx`) or use a parallel `__tests__/` directory. Be consistent across the project.

Use `describe` blocks to group related tests. Use `it` or `test` for individual cases. Setup shared across a `describe` block goes in `beforeEach`, not duplicated in each test.

## Continuous Integration

Tests must pass before merging. Run the full suite in CI on every pull request. Fail the build on test failures -- never merge with known failures. Aim for meaningful coverage (80%+) over line-count metrics.

---
> Source: [calcosmic/Aether](https://github.com/calcosmic/Aether) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-15 -->

