TestPrune.Core 6.0.0

dotnet add package TestPrune.Core --version 6.0.0
                    
NuGet\Install-Package TestPrune.Core -Version 6.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TestPrune.Core" Version="6.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TestPrune.Core" Version="6.0.0" />
                    
Directory.Packages.props
<PackageReference Include="TestPrune.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TestPrune.Core --version 6.0.0
                    
#r "nuget: TestPrune.Core, 6.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TestPrune.Core@6.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TestPrune.Core&version=6.0.0
                    
Install as a Cake Addin
#tool nuget:?package=TestPrune.Core&version=6.0.0
                    
Install as a Cake Tool

TestPrune

Run only the tests your change could have affected.

TestPrune analyzes your F# code to work out which functions depend on which, then uses that map to skip tests that couldn't have been touched by what you changed. The aim: when your suite takes minutes but you changed one function, you wait seconds.

Status: early alpha. This is a young project, substantially AI-written, and still finding its shape. Behavior and APIs shift between versions, so pin a version and expect surprises. Issues and PRs are very welcome.

Why?

When your test suite takes minutes but you only changed one function, running everything is wasteful. TestPrune builds a map of your code — which functions call which, which tests cover which code — and tries to pick just the tests that matter.

Change multiply? Ideally only the multiply tests run. Change a type that three modules depend on? Those three modules' tests run. Add a new file? Everything runs, just to be safe.

Quick example

Say you have a math library and some tests (from examples/SampleSolution):

// src/SampleLib/Math.fs
module SampleLib.Math

let add x y = x + y
let multiply x y = x * y
// tests/SampleLib.Tests/MathTests.fs
[<Fact>]
let ``add returns sum`` () = Assert.Equal(5, add 2 3)

[<Fact>]
let ``multiply returns product`` () = Assert.Equal(12, multiply 3 4)

You change multiply. TestPrune works out that only multiply returns product needs to run — and skips add returns sum.

Try the CLI

The quickest way to see it work is the test-prune CLI, a reference implementation that wires the library up for you:

test-prune index       # Build the dependency graph
test-prune run         # Run only affected tests
test-prune status      # Show what would run (dry-run)
test-prune dead-code   # Find unreachable production code

It detects changes from your version control (jj or git), so run index once, then run/status after each edit.

Global options: --repo <path> (repo root, default: auto-detect), --parallelism <n> (max parallel analyses, default: processor count).

The CLI re-analyzes serially and isn't tuned for big codebases — FSharp.Compiler.Service type-checking is slow. For real workflows, embed TestPrune.Core in your build tooling, where you can cache and parallelize. See the integration guide.

How it works

  1. Index — Parse every .fs file, record which functions/types exist and what they depend on. Store in SQLite.
  2. Diff — Look at what files changed since last commit.
  3. Compare — Figure out which specific functions changed (added, removed, or modified).
  4. Walk — Follow the dependency graph from changed functions to find every test that transitively depends on them.
  5. Run — Execute only those tests.

If anything looks uncertain (new files, project-file changes), it falls back to running everything. Better to run too many tests than miss a broken one.

Declarative dependencies

For edges the analyzer can't see — reflection, DI-by-type, or non-F# files like snapshots, migrations, or config — TestPrune.Attributes lets you declare them:

open TestPrune

[<DependsOn(typeof<PluginRegistry>)>]                    // reflection target
let registerPlugins () = ...

[<DependsOnFile("tests/snapshots/api.snap.json")>]       // specific file
[<Fact>]
let ``api snapshot`` () = ...

[<DependsOnGlob("migrations/*.sql")>]                    // glob
type DbIntegrationTests() = ...

Glob dialect: ** crosses path segments, * stays within one, ? is a single non-/ char. Paths are repo-relative and case-sensitive. The attributes are metadata — no runtime behavior.

Packages

Package What it's for
TestPrune.Core The library — use this in your build system or editor
TestPrune.Attributes Consumer-side markers: [<DependsOn>], [<DependsOnFile>], [<DependsOnGlob>]
TestPrune.Falco Extension for Falco web apps (route → test mapping)
TestPrune.Analyzers Opt-in F# analyzer that flags anonymous records (invisible to impact analysis)
TestPrune CLI tool (reference implementation)

Going deeper

Design choices

Static analysis, not coverage. TestPrune reads your code's AST instead of instrumenting test runs. So you don't need to run tests to build the graph, and there's no flaky-coverage problem. The tradeoff: it may run a few extra tests, but it aims never to miss a broken one.

Safe by default. When in doubt, run everything. A missed broken test is much worse than running a few unnecessary ones.

Single-file storage. The dependency graph is one .test-prune.db file. No servers, no services. Rebuilds are atomic.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on TestPrune.Core:

Package Downloads
FsHotWatch.TestPrune

FsHotWatch plugin for TestPrune test impact analysis

TestPrune.Falco

Falco route-based integration test filtering extension for TestPrune

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.0.0 0 7/14/2026
5.0.0 76 7/11/2026
4.3.0 200 6/16/2026
4.2.3 114 6/15/2026
4.2.2 126 6/12/2026
4.2.1 126 6/7/2026
4.2.0 104 6/5/2026
4.1.0 120 6/4/2026
4.0.3 116 6/2/2026
4.0.2 105 5/26/2026
4.0.1 117 5/4/2026
4.0.0 127 4/25/2026
3.0.2 137 4/22/2026
3.0.1 141 4/20/2026
3.0.0 112 4/20/2026
2.0.0 170 4/11/2026
1.0.1 163 4/7/2026
0.1.0-beta.1 154 4/2/2026
0.1.0-alpha.9 74 4/2/2026
0.1.0-alpha.8 73 4/1/2026
Loading failed