Selection strategy
Test selection vs path filters, Nx and Turborepo
These approaches overlap, but they do not answer exactly the same question. The best baseline is often the simplest one that is safe, maintainable, and measurably cheaper for the repository.
What each approach knows
| Approach | Primary evidence | Strength | Main boundary |
|---|---|---|---|
| Changed-path rule | Files and directories in the Git diff | Cheap, explicit, easy to review | Shared and transitive dependencies must be maintained manually |
| Nx/Turborepo-style affected task graph | Declared projects, packages and task dependencies | Fits repositories already organized around that graph | Precision stops at the configured project or task boundary |
| Source dependency test selection | Resolved imports from changed source to tests | Can narrow within a package and retain per-test provenance | Dynamic behavior, unsupported languages and resolution gaps require fallback |
| DiffCI observation | Git delta, dependency evidence, CI structure and execution comparison | Measures whether a selection would be safe and worthwhile before CI authority changes | Advisory; it does not replace or accelerate required production CI |
Precision is not the same as value
A dependency graph can select fewer tests than a directory rule and still cost more after analysis overhead. A package-level task graph can be less precise but cheaper, easier to explain, and already integrated with build caching. The economic comparison needs actual command execution.
DiffCI's open benchmark found repositories where a simple path rule was already optimal, repositories where dependency analysis found a narrower candidate, and repositories where mandatory fallbacks dominated. That mixture is why DiffCI reports the baseline rather than declaring one method universally better.
How to choose
- Use path filters first when repository boundaries are stable, shared dependencies are limited, and the mapping is easy to review.
- Use the monorepo task graph when Nx, Turborepo, or an equivalent already defines the authoritative project and task relationships.
- Evaluate source dependency selection when large packages contain many independently reachable tests and coarse project selection still runs too much.
- Keep full-run triggers regardless. Lockfiles, workflows, root configuration, and incomplete evidence can invalidate every narrow strategy.
Run the comparison without changing CI
npx "@diffci.com/diffci@latest" checkThe local check analyzes the change and runs inferred full and selected commands when possible. It retains fallback reasons and measured timings. Use observe --no-send when analysis should not execute tests.
For GitHub Actions prerequisites, see the test impact analysis guide. For a safety checklist, see how to run affected tests safely.