Optimize Test Suite
Reduce suite runtime and maintenance cost without weakening its ability to catch regressions. Measure first, make one evidence-backed optimization at a time, and compare against the baseline.
Establish the Contract
- Read applicable repository instructions and test-running guidance.
- Identify supported interpreters, environments, test commands, markers, shards, and integration gates. Do not conflate environments.
- Record the requested scope and success criteria: wall time, CPU time, collection time, slowest tests, flake rate, or maintenance duplication.
- Preserve externally visible behavior, safety invariants, failure semantics, and required test categories.
- Do not add a dependency, enable uncontrolled parallelism, or change CI policy unless explicitly requested.
Measure a Baseline
Run the smallest representative command that exposes the problem, then the authoritative suite when practical.
Capture:
- exact command and environment;
- collected, passed, skipped, failed, and deselected counts;
- wall-clock duration and framework timing output;
- slowest tests and setup/call/teardown phases when supported;
- repeated-run variance when timings are noisy;
- whether caches are cold or warm.
Use existing profiler, duration, trace, or timing features before writing instrumentation. Do not optimize from intuition alone.
Classify the Cost
Assign each candidate one primary cause:
- duplicated scenario or equivalent assertion;
- repeated expensive fixture or application bootstrap;
- unnecessarily broad integration/e2e coverage;
- filesystem, database, network, subprocess, sleep, retry, or polling cost;
- oversized parameter matrix with equivalent partitions;
- repeated data generation, parsing, imports, compilation, or discovery;
- serial execution forced by avoidable shared mutable state;
- timeout masking a hang, race, or production defect;
- test framework or environment misconfiguration.
Separate slow tests from flaky tests. A speed change that hides a race, suppresses a failure, or only raises a timeout is not an optimization.
Prove Redundancy Before Deleting
Compare setup, stimulus, assertion, branch, and failure mode. Treat tests as redundant only when another retained test detects the same meaningful regression under the same relevant boundary.
Keep distinct tests when they protect different:
- public contracts or entrypoints;
- failure paths, boundary values, security rules, or state transitions;
- interpreters, platforms, dependency variants, or integration seams;
- regression histories that remain plausible.
Prefer deleting an exact duplicate. Use parametrization only when cases share one behavior and failures remain easy to identify. Do not compress unrelated behaviors into a clever table merely to reduce line count.
When existing coverage or mutation tooling is available, use it as supporting evidence, not as the sole proof of equivalence. Do not add such tooling without authorization.
Optimize in Risk Order
Apply the smallest effective change, generally in this order:
- Delete proven duplicate tests, assertions, setup, and obsolete compatibility cases.
- Reuse existing helpers and fixtures; remove repeated construction.
- Narrow setup to the data and subsystem the test actually needs.
- Replace real sleeps with deterministic clocks, events, or injectable polling seams.
- Replace accidental external I/O with existing fakes at the correct boundary.
- Move repeated immutable setup to a broader fixture scope only after proving isolation and cleanup.
- Split fast contract tests from deliberately gated integration/e2e tests without removing either contract.
- Reduce parameter matrices using behavioral equivalence classes and retain boundary cases.
- Enable sharding or parallel execution only when isolation is proven and the repository already supports it or the user requests it.
Fix production code only when profiling exposes an actual product defect or a missing testability seam and the task authorizes that change. Do not distort production APIs solely for test speed.
Guard Against False Improvements
Reject changes that improve timing only by:
- skipping, deselecting, xfail-ing, or weakening assertions;
- reducing retries that were exposing a real race without fixing it;
- sharing mutable fixtures across tests;
- relying on order, warm caches, leaked processes, persistent databases, or developer-machine state;
- mocking the behavior under test instead of its external dependency;
- moving slow tests out of the default command without an explicit suite contract;
- comparing different test counts, environments, or cache states without explanation.
Verify
- Run focused tests after each change.
- Run the same baseline command with the same environment and comparable cache state.
- Compare test counts, outcomes, slowest phases, wall time, and variance.
- Run tests that validate collection, markers, suite boundaries, fixtures, or CI commands when changed.
- Repeat timing samples when the improvement is near measurement noise.
- Run the broader authoritative suite when risk and cost justify it.
- Inspect the diff and confirm every deletion has retained failure-detection evidence.
Restore or revise any change that causes new flakes, order dependence, leaked resources, reduced contract coverage, or insignificant speedup relative to complexity.
Report
Summarize:
- files changed and tests deleted, consolidated, or repartitioned;
- root causes of redundancy or slowness;
- before/after commands, counts, timings, and sample conditions;
- evidence that regression protection remains;
- remaining bottlenecks, measurement limits, and risks.
State measured improvement numerically. Do not claim the whole suite is faster when only a subset was measured.
1---2name: optimize-test-suite3description: Diagnose and improve redundant, slow, flaky, or poorly partitioned automated test suites while preserving failure-detection strength and behavior coverage. Use when Codex needs to profile test duration, identify duplicated assertions or scenarios, consolidate tests and fixtures, reduce unnecessary setup, I/O, subprocess, database, network, or framework overhead, improve fast-versus-integration suite boundaries, or demonstrate measurable test-runtime improvement without weakening regression protection.4---56# Optimize Test Suite78Reduce suite runtime and maintenance cost without weakening its ability to catch regressions. Measure first, make one evidence-backed optimization at a time, and compare against the baseline.910## Establish the Contract11121. Read applicable repository instructions and test-running guidance.132. Identify supported interpreters, environments, test commands, markers, shards, and integration gates. Do not conflate environments.143. Record the requested scope and success criteria: wall time, CPU time, collection time, slowest tests, flake rate, or maintenance duplication.154. Preserve externally visible behavior, safety invariants, failure semantics, and required test categories.165. Do not add a dependency, enable uncontrolled parallelism, or change CI policy unless explicitly requested.1718## Measure a Baseline1920Run the smallest representative command that exposes the problem, then the authoritative suite when practical.2122Capture:2324- exact command and environment;25- collected, passed, skipped, failed, and deselected counts;26- wall-clock duration and framework timing output;27- slowest tests and setup/call/teardown phases when supported;28- repeated-run variance when timings are noisy;29- whether caches are cold or warm.3031Use existing profiler, duration, trace, or timing features before writing instrumentation. Do not optimize from intuition alone.3233## Classify the Cost3435Assign each candidate one primary cause:3637- duplicated scenario or equivalent assertion;38- repeated expensive fixture or application bootstrap;39- unnecessarily broad integration/e2e coverage;40- filesystem, database, network, subprocess, sleep, retry, or polling cost;41- oversized parameter matrix with equivalent partitions;42- repeated data generation, parsing, imports, compilation, or discovery;43- serial execution forced by avoidable shared mutable state;44- timeout masking a hang, race, or production defect;45- test framework or environment misconfiguration.4647Separate slow tests from flaky tests. A speed change that hides a race, suppresses a failure, or only raises a timeout is not an optimization.4849## Prove Redundancy Before Deleting5051Compare setup, stimulus, assertion, branch, and failure mode. Treat tests as redundant only when another retained test detects the same meaningful regression under the same relevant boundary.5253Keep distinct tests when they protect different:5455- public contracts or entrypoints;56- failure paths, boundary values, security rules, or state transitions;57- interpreters, platforms, dependency variants, or integration seams;58- regression histories that remain plausible.5960Prefer deleting an exact duplicate. Use parametrization only when cases share one behavior and failures remain easy to identify. Do not compress unrelated behaviors into a clever table merely to reduce line count.6162When existing coverage or mutation tooling is available, use it as supporting evidence, not as the sole proof of equivalence. Do not add such tooling without authorization.6364## Optimize in Risk Order6566Apply the smallest effective change, generally in this order:67681. Delete proven duplicate tests, assertions, setup, and obsolete compatibility cases.692. Reuse existing helpers and fixtures; remove repeated construction.703. Narrow setup to the data and subsystem the test actually needs.714. Replace real sleeps with deterministic clocks, events, or injectable polling seams.725. Replace accidental external I/O with existing fakes at the correct boundary.736. Move repeated immutable setup to a broader fixture scope only after proving isolation and cleanup.747. Split fast contract tests from deliberately gated integration/e2e tests without removing either contract.758. Reduce parameter matrices using behavioral equivalence classes and retain boundary cases.769. Enable sharding or parallel execution only when isolation is proven and the repository already supports it or the user requests it.7778Fix production code only when profiling exposes an actual product defect or a missing testability seam and the task authorizes that change. Do not distort production APIs solely for test speed.7980## Guard Against False Improvements8182Reject changes that improve timing only by:8384- skipping, deselecting, xfail-ing, or weakening assertions;85- reducing retries that were exposing a real race without fixing it;86- sharing mutable fixtures across tests;87- relying on order, warm caches, leaked processes, persistent databases, or developer-machine state;88- mocking the behavior under test instead of its external dependency;89- moving slow tests out of the default command without an explicit suite contract;90- comparing different test counts, environments, or cache states without explanation.9192## Verify93941. Run focused tests after each change.952. Run the same baseline command with the same environment and comparable cache state.963. Compare test counts, outcomes, slowest phases, wall time, and variance.974. Run tests that validate collection, markers, suite boundaries, fixtures, or CI commands when changed.985. Repeat timing samples when the improvement is near measurement noise.996. Run the broader authoritative suite when risk and cost justify it.1007. Inspect the diff and confirm every deletion has retained failure-detection evidence.101102Restore or revise any change that causes new flakes, order dependence, leaked resources, reduced contract coverage, or insignificant speedup relative to complexity.103104## Report105106Summarize:107108- files changed and tests deleted, consolidated, or repartitioned;109- root causes of redundancy or slowness;110- before/after commands, counts, timings, and sample conditions;111- evidence that regression protection remains;112- remaining bottlenecks, measurement limits, and risks.113114State measured improvement numerically. Do not claim the whole suite is faster when only a subset was measured.