rvtest 0.2.0

A Next Level Testing Library for Rust — BDD specs, property-based testing, parametrized tests, rich reporting, and code coverage
Documentation

rvtest — A Next Level Testing Library for Rust.

rvtest extends Rust's built-in testing capabilities with:

  • BDD-style specs — organise tests with describe / it blocks, nested hierarchies, lifecycle hooks (before_all, after_all, before_each, after_each), tags, timeouts, and retries.
  • Property-based testing — verify invariants over randomly generated inputs, with automatic counterexample shrinking.
  • Parametrized tests — run the same test logic against multiple inputs without boilerplate.
  • Assertion macrosassert_eq! with structural diffs, assert_ok!, assert_err!, assert_matches!, assert_delta!.
  • Mocking utilitiesSpy (call-recording), Stub (fixed return), patch! (scoped function replacement). No proc-macro required.
  • Snapshot testing — file-based snapshot assertions with --update-all auto-accept and --review interactive mode.
  • Architecture tests — enforce module dependency rules (may_depend_on, may_not_depend_on, must_not_have_cycles, public_api_doc_required).
  • Output capture — per-test stdout/stderr capture, shown only on failure.
  • Rich reporting — Pretty (human-readable with colour), TAP, JUnit XML, JSON, Compact, and GitHub Actions annotations formats.
  • Code coverage — measure line/function/region coverage via pure-Rust .profraw parser (cargo rvtest --coverage). No external LLVM tools required.
  • Configurable runner — parallel execution, name and tag filtering, fail-fast, configurable timeouts and retries.
  • Optional proc-macro API#[describe] / #[it] attribute macros via the macros feature.

Usage inside #[test] (recommended)

Rvtest is designed to be used inside standard #[test] functions. Build a spec with describe and it, call run, then verify with assert_all_pass:

use rvtest::spec::describe;

#[test]
fn calculator_tests() {
    describe("Calculator")
        .it("adds two positive numbers", || {
            assert_eq!(2 + 2, 4);
        })
        .it("subtracts", || {
            assert_eq!(5 - 3, 2);
        })
        .tag("arithmetic")
        .run()
        .assert_all_pass();
}

Tags let you selectively run tests: cargo rvtest --tag arithmetic. Other modifiers include .timeout(dur) and .retries(n).

Property-based testing inside #[test]

use rvtest::property::{check, any};

#[test]
fn addition_is_commutative() {
    check("commutativity", any::<i32>(), |a: &i32| {
        let b: i32 = 42;
        a + b == b + *a
    });
}

Parametrized tests inside #[test]

use rvtest::param::parametrize;

#[test]
fn addition_cases() {
    for case in parametrize("add", [(1, 1, 2), (0, 0, 0), (-1, 1, 0)], |(a, b, exp)| {
        assert_eq!(a + b, *exp);
    }) {
        assert!(case.status.is_passed(), "{} failed", case.name);
    }
}

CLI usage (cargo rvtest)

The cargo-rvtest binary runs specs defined in your project and produces formatted output. See cargo rvtest --help.