TestTracks: Testing Without the Framework Tax
I released TestTracks, a railway-oriented testing framework for F#. It solves problems I kept hitting with traditional test runners: slow startup, difficult debugging, and opaque control flow.
The Problem
Standard test frameworks use reflection to discover tests via attributes. This creates friction:
- Slow startup: Reflection scans assemblies on every run
- Debugging pain: Can't easily debug into a single test—you're going through the framework's machinery
- Hidden control flow: Setup/teardown happens "magically" via attributes, making it hard to reason about state
For quick iteration cycles, this adds up. You want to run one test, step through it, and understand exactly what's happening.
The Solution
TestTracks treats tests as plain functions that return values. No attributes, no reflection, no framework magic:
fsharp
let main args =
let mathTests = suite "Math" [
test "addition" (fun () -> assertEqual 4 (2 + 2) "should add")
]
parseTestArgs args [mathTests]
Benefits:
- Instant debugging: Tests are just functions. Set a breakpoint, run, step through
- Fast execution: No reflection scan—your main function directly calls test functions
- Transparent flow: Setup/teardown is explicit data flow, not hidden attributes
Railway-Oriented Design
Tests return TestResult types (Pass/Fail/Skip) instead of throwing exceptions. This makes error handling compositional:
fsharp
test "validation" (fun () ->
assertTrue (x > 0) "positive"
|> combine (assertEqual 10 x "equals 10")
|> combine (assertSome (Some x) "is Some")
)
All three assertions run and accumulate errors, giving you complete failure information in one test run.
When to Use It
TestTracks is ideal if you:
- Want fast feedback loops while developing
- Need to debug tests frequently
- Prefer composition over configuration
- Like seeing exactly what your code does
It includes common assertion functions (equality, collections, numeric comparisons, regex), data-driven testing via list comprehensions, and suite-level setup/teardown with strongly-typed environments.
A minimal, IDE agnostic, focussed module that doesn't get in the way of testing.
Try it out: github.com/qa3-tech/TestTracks