Run only the .NET tests a change can affect.
TestDetta compares your branch with its base, works out which test projects and which test classes can observe the change, and runs just those. When it cannot be sure, it runs more, never less. It runs inside your CI and on your machine; your source, coverage and test results never leave them.
Documentation: testdetta.com/docs
$ td test --base origin/main
TestDetta 0.5.2 · 1 changed file · 2 affected test projects
Tests to run
┌──────────────────┬──────────┬─────────┬───────┬──────────────────────────────────────────────────────────┐
│ Test project │ Run │ Classes │ Saved │ Why │
├──────────────────┼──────────┼─────────┼───────┼──────────────────────────────────────────────────────────┤
│ tests/Shop.Tests │ filtered │ 3 / 41 │ - │ 3 of 41 test class(es) run or reference the changed code │
│ tests/Api.Tests │ skipped │ 0 / 12 │ - │ no test class runs or references the changed code │
└──────────────────┴──────────┴─────────┴───────┴──────────────────────────────────────────────────────────┘
TestDetta is the TestDetta package on nuget.org, a .NET tool with the
command td. The .NET 10 SDK runs td itself; your tests keep the SDK and runner your repository already uses.
Runs on Windows, Linux and macOS; every pull request runs the whole test suite on Windows and Linux, .NET Framework
4.6.2 to 4.8 test projects and legacy (non-SDK) solutions included.
dotnet tool install --global TestDetta # or: dotnet tool install TestDetta (local tool manifest)
dotnet tool update --global TestDetta # to the latest versionxUnit v2 and v3, NUnit, MSTest and TUnit, on VSTest and Microsoft.Testing.Platform, in C#, Visual Basic and F# (compatibility).
td record # on the default branch: run every test once and record coverage maps
td test --base origin/main # on a branch: run only the affected tests
td affected -v # what would run, and why, without running anythingAdd .testdetta/ to .gitignore. Without a coverage map TestDetta still works, deciding by name, which
selects more. Every command and option: CLI reference.
- uses: actions/checkout@v7 # pin to a commit SHA
with:
fetch-depth: 0 # TestDetta compares with the merge base
- if: github.event_name == 'push' # default branch: record the maps
uses: TestDetta/action@8750db18099a2af0436788d20dc591e94b550c07 # v0.5.2
with:
mode: record
- if: github.event_name == 'pull_request' # pull requests: run the affected tests
uses: TestDetta/action@8750db18099a2af0436788d20dc591e94b550c07 # v0.5.2
with:
mode: testThe whole workflow, permissions and inputs: GitHub Actions. GitLab CI, Jenkins, Azure DevOps and Bitbucket: Other CI systems.
A Claude Code plugin (dist/claude-plugin): agents run td test instead of a full
dotnet test, and the affected tests run before the agent hands back.
/plugin install testdetta --marketplace selcukgural/TestDetta
- Projects. Changed files are followed through project references; build-wide files affect every project below them.
- Symbols. Old and new syntax trees are compared, so a comment or whitespace edit selects nothing.
- Coverage. A map of which test class ran which method gives the classes for changed code directly.
- Names. New code, fields and constants are traced through the source by name.
- Fallbacks. A change that cannot be traced (
appsettings.json, a.csproj, reflection-found types) runs the whole test project.
Details: How it decides ·
Limitations ·
Validate on your repository (shadow mode and td audit) ·
Your test configuration ·
Troubleshooting ·
Security and data
.NET 10 SDK: dotnet build, dotnet test (Category=Slow tests build and record sample projects). Coding
guidelines: CONTRIBUTING.md. Design notes: docs/design. Security reports:
SECURITY.md.
TestDetta is free and open source for every repository, public or private. It is built by one person; if it saves your team test time, you can help it go on through GitHub Sponsors: monthly or once.