libtest-mimic

Build a custom Rust test harness that looks and behaves like rustc's built-in test runner

Library
Cargo
v0.8.2
144stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity8
Maintenance20
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture72
Code Quality74
Innovation65
Learning Curve68

libtest-mimic is a small Rust crate for writing your own test harness — the binary Cargo invokes via cargo test when a target opts out of the built-in libtest runner. It mimics the real thing closely: output formatting, most CLI flags (--test-threads, filtering by substring, --ignored, --format json, etc.), and exit-code behavior all match what cargo test normally produces, so custom test runners built with it feel native to anyone used to standard Rust tests.

This matters for projects that need custom test discovery or execution logic that the standard #[test] attribute can’t express — for example, running a suite of tests generated dynamically from files on disk (a common pattern for compiler/parser projects wanting one Trial per fixture file), or projects needing custom argument parsing before invoking tests. libtest-mimic handles the boilerplate of CLI parsing, colored/plain output, JSON output, and threaded/serial execution, letting the harness author focus purely on producing a list of Trials and running them.

What You Get

  • A Trial type representing a single test or benchmark with a name, kind, and runner closure
  • An Arguments type that parses the same CLI flags as the built-in libtest harness (--test-threads, name filters, --ignored, --format)
  • A run() function that executes trials with libtest-matching console output, including colored and JSON formats
  • Support for ignored tests and custom test “kinds” beyond plain tests/benchmarks
  • A Conclusion result type with exit_code()/exit() helpers matching standard test binary exit-code conventions
  • Example harnesses (examples/simple.rs, examples/tidy.rs) demonstrating dynamic test discovery

Common Use Cases

  • Building a file-driven test harness (e.g. one Trial per fixture file) for compilers, parsers, or template engines
  • Writing ‘tidy’ or lint-style checks that need to report results in the same format as regular cargo test output
  • Wiring an existing custom test runner into IDEs/CI that expect standard test-binary CLI flags and JSON output
  • Adding benchmarked or specially-tagged test kinds that the standard #[test] attribute doesn’t distinguish

Under The Hood

Architecture - The crate is deliberately small and split into three files: src/lib.rs defines the public Trial/Conclusion/Failed/Measurement types and the run() entry point that drives test execution (serial or threaded based on parsed arguments); src/args.rs implements Arguments, a CLI argument definition (built on clap) that mirrors the flags rustc --test binaries accept; and src/printer.rs handles all console/JSON output formatting so it visually matches the built-in libtest harness, including colored pass/fail/ignored lines. run() takes the parsed Arguments and a Vec<Trial> supplied by the caller, meaning all test discovery is left entirely to the harness author — the crate only owns argument parsing, execution, and reporting.

Tech Stack - Pure Rust (edition 2021, MSRV 1.65) with a minimal dependency set: clap (with the derive feature) for CLI argument parsing, escape8259 for JSON string escaping in --format json output, and anstream/anstyle for portable terminal color output. Dev-dependencies (fastrand, pretty_assertions) support the crate’s own test suite, which itself uses libtest-mimic-style fixture tests under tests/.

Code Quality - The tests/ directory includes both unit-style tests (all_passing.rs, panic.rs, mixed_bag.rs, threads.rs) and ‘real’/‘common’ fixture directories plus a checked-in json-output.json expectation file, indicating output-format regression testing rather than only logic testing. The crate is dual-licensed (MIT/Apache-2.0, the Rust ecosystem standard) and has 17 tagged releases over roughly 6 years, showing a slow but steady maintenance cadence appropriate for a stable, narrowly scoped crate rather than one under heavy active development.

API Design - The API surface is intentionally tiny: construct Trial::test(name, closure) (or Trial::bench/ignorable_test variants), collect them into a Vec<Trial>, parse CLI args with Arguments::from_args(), and call libtest_mimic::run(&args, tests).exit(). This mirrors how a real libtest-driven test binary would look from the outside while giving the author full control over how the Vec<Trial> is built, which is the crate’s core value proposition — matching the well-known cargo-test UX with almost no boilerplate for the harness author.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search