--- name: test-authoring description: >- Write meaningful tests for requested behavior, boundaries, failures, and state or tenant isolation. Use when adding coverage, reproducing a bug, or writing regression tests. Follow the repository's runner and conventions; do not expand test-authoring requests into unrequested production changes. --- # Test Authoring Read [anti-ai-writing](../anti-ai-writing/SKILL.md) before drafting names, comments, or reports. Keep changes scoped to the requested coverage and preserve unrelated work. ## Discover the Runner and Expected Behavior Read repository instructions, neighboring tests, fixtures, dependency versions, runner configuration, and relevant CI commands. Prefer repository wrappers and scripts over assumed global commands. Identify the package directory and how to select focused tests, then confirm the runner actually executes them. For test edits, follow the repository validation procedure in [writing-clean-simple-code](../writing-clean-simple-code/SKILL.md#verify-behavior-and-comprehension) to discover configured lint, formatter, and type checks, including rules that apply to test files. This validation does not authorize production changes. Derive expected outcomes from authoritative requirements, independently verified examples, or preserved contracts. Do not copy the implementation's formula into the expected result. Resolve behavior-changing ambiguity before asserting a guessed outcome; continue coverage whose intent is settled. Before writing a test, name the behavior or defect its assertion would detect and the production change that would make it fail. If no meaningful change would fail it, strengthen the assertion or choose a different test boundary. ## Choose the Level That Captures the Behavior Use the lowest level that meaningfully exercises the requirement: | Level | Appropriate coverage | | --- | --- | | Unit | Isolated logic with controlled inputs and observable results. | | Integration or composition | Behavior across parsing, persistence, services, or other component boundaries. | | End-to-end | Critical user flows or browser/runtime behavior that lower-level tests cannot establish. | Exercise production code. Do not mock the changed parser, compiler, engine, query, or component whose behavior the test is meant to establish. Textual source checks are appropriate only for an explicitly textual contract, not as runtime coverage. Use real query/database behavior when mocks conceal tenant or scope defects. Use manual verification for requirements automation cannot establish, and state that limitation. Manual checks cannot replace required runner evidence for a behavioral code change. Avoid fixed test-level percentages or unnecessary end-to-end tests when focused coverage establishes the same behavior. Cover relevant success, negative, boundary, null/empty, and failure cases. Include normalization, repeated operations, partial inputs, and fallbacks where they affect reachability or contracts. For shared repairs, include the original defect and a plausible repair-induced failure from actual producers and consumers. Investigate conflicting expectations across layers even when both suites pass. For query changes, optimizations, persisted configuration, or asynchronous and interactive state, read [scope and state coverage](references/scope-and-state.md). ## Write Readable, Deterministic Tests Organize each test into recognizable setup, action, and assertions without requiring ceremonial comments. Name the behavior and expected outcome. Keep one coherent behavior per test; multiple assertions can establish that behavior. Prefer outcomes over internal call sequences unless the interaction itself is the required contract. Reuse repository fixtures and builders, but keep distinguishing inputs and expected results visible. Do not add abstraction solely to remove a few lines of setup. Prefer cheap real collaborators; use fakes or mocks for costly, nondeterministic, or unsafe boundaries outside the behavior under test. Verify a fake models the contract being exercised rather than assuming it is equivalent to production. Control time, randomness, scheduling, and I/O with repository utilities. Prefer explicit synchronization to arbitrary sleeps. Give each test its own state and restore changed globals, clocks, mocks, environment, and resources even after failure. Use bounded waits and clean up background tasks. Do not depend on test order or mutate shared fixtures across cases. Use snapshots only for meaningful, reviewable output contracts. Inspect expected changes deliberately; do not regenerate snapshots merely to make failures green. Use focused assertions when a broad snapshot hides the behavior of interest. ## Establish Evidence for the Requested Coverage - For a bug reproduction, use a realistic fixture that distinguishes defective behavior. Run it against the defective version when feasible and confirm the intended assertion fails; syntax, import, or setup failures do not count. A reproduction-only request stops there and does not authorize production repair. - When tests accompany an authorized behavior change or fix, prefer observing the intended assertion fail before implementation and pass afterward. If the old version cannot be run safely or meaningfully, record why and use the strongest available baseline or reproduction. Do not claim regression sensitivity that was not observed. - For coverage of existing correct behavior, run the test and verify it reaches the intended path and asserts an independently justified result. Use a focused mutation in an isolated copy when a consequential gap remains about whether the test could detect a regression; do not require one for every test-only change. Keep before/after conditions comparable. Use isolated copies or restore only agent-owned edits; never reset or stash mixed user work. A reproduction test may remain failing for a later repair. Report its result without weakening the assertion to obtain a green suite. ## Execute and Report Run the intended tests and the configured lint, formatter, and type checks for affected packages using the shared validation procedure above. Retain command results, rerun affected checks after edits, and report unavailable checks as incomplete. An intentionally failing reproduction test may remain failing; that exception does not waive lint, formatter, or type checks. Use actual repository commands and working directories. Confirm selected tests ran and inspect failures; zero selected tests is not verification. Broaden or repeat checks only for material changes, failures, or unresolved concerns. Do not skip a flaky test or rerun until green as a substitute for understanding it; use [root-cause-debug](../root-cause-debug/SKILL.md) for unresolved failure investigation. Report what behavior the tests establish, actual execution results, observed before/after evidence, and material limits. Distinguish authored but unrun tests from verified coverage. Passing tests do not prove absence of defects or that an unexecuted browser/live flow works. Commit, push, and publication require separate authorization through the applicable workflow. ## Anti-Rationalization Guardrails These rules govern phase transitions. Missing evidence leaves the gate incomplete; do not substitute a declaration of confidence or silently waive a requirement. | Model Rationalization | Enforced Rule | | --- | --- | | The change is too small to test. | Choose meaningful behavioral coverage for a code change; size does not establish that the affected behavior is safe. | | I verified the behavior mentally. | Run the actual test runner and retain its output. Reasoning cannot satisfy an execution gate. | | Mocking is too hard. | Use real collaborators or a suitable integration boundary. Do not mock the behavior under test or claim coverage that was not exercised. | | I will call this test regression-sensitive without running the old behavior. | Record the unobserved side of the comparison; a passing new test alone does not prove it would detect the defect. | | Test-only changes do not need lint. | Run configured lint, formatter, and type checks for test edits, including intentionally failing reproduction tests. |