rules_rust_mutants
Mutation testing for Rust crates built with rules_rust.
rust_mutation_test enumerates source-level mutations for a rust_library,
compiles each mutant with the same rustc configuration as rust_test, and
runs the crate's inline #[cfg(test)] tests against each mutant.
Rules
Setup
Bzlmod
Add the following to your MODULE.bazel file:
bazel_dep(name = "rules_rust_mutants", version = "{SEE_RELEASE_NOTES}")
WORKSPACE
If you're using WORKSPACE, load repositories with:
load("@rules_rust_mutants//:repositories.bzl", "rust_mutation_dependencies")
rust_mutation_dependencies()
Usage
load("@rules_rust_mutants//:defs.bzl", "rust_mutation_test")
load("@rules_rust//rust:defs.bzl", "rust_library")
rust_library(
name = "my_lib",
srcs = ["lib.rs"],
edition = "2021",
)
rust_mutation_test(
name = "my_lib_mutation_test",
crate = ":my_lib",
)
Run with:
bazel test //:my_lib_mutation_test --test_output=all
Behavior Notes
- Mutation generation uses
cargo-mutantsJSON output. - Mutation enumeration uses
cargo mutants --list --json --diff --Zmutate-file .... - Rustc params are generated from rules_rust's canonical argument-construction
pipeline (
collect_inputs+construct_arguments). mutants_configis forwarded ascargo mutants --config <path>.- By default, survived mutants fail the Bazel test target.
allow_survivors = Truereports survivors without failing.- If mutation generation produces zero mutants, the Bazel target succeeds and
prints
No mutations generated..
Tooling
- A hermetic
cargo-mutantsbinary is built from source by this extension. - A Cargo binary from the active Rust toolchain is used for
cargo-mutantsinternals.
Rules
rust_mutation_test
load("@rules_rust_mutants//:defs.bzl", "rust_mutation_test")
rust_mutation_test(name, allow_survivors, crate, exclude_re, mutants_config, rustc_flags)
Mutation testing for a Rust library crate.
rust_mutation_test:
- Enumerates source-level mutants with
cargo-mutants. - Builds rustc params from rules_rust's canonical argument construction
pipeline (
collect_inputs + construct_arguments). - Runs baseline and per-mutant compile+test cycles against inline
#[cfg(test)]tests from the crate. - Fails if any mutant survives (unless
allow_survivors = True). - Succeeds and prints
No mutations generated.when enumeration yields zero mutants.
Mutation enumeration mode:
- Uses
cargo mutants --list --json --diff --Zmutate-file ....
Example:
load("@rules_rust_mutants//:defs.bzl", "rust_mutation_test")
rust_library(
name = "my_lib",
srcs = ["lib.rs"],
)
rust_mutation_test(
name = "my_lib_mutation_test",
crate = ":my_lib",
)
Run with: bazel test //:my_lib_mutation_test --test_output=all
ATTRIBUTES
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| allow_survivors | If True, survived mutants are reported but do not fail the test. Default is False (survivors fail). | Boolean | optional | False |
| crate | The rust_library crate to mutation-test. The crate's inline #[cfg(test)] tests are compiled and run against each mutation. | Label | required | |
| exclude_re | Regular expression patterns to exclude mutants. Each pattern is forwarded as cargo mutants --exclude-re <pattern>. | List of strings | optional | [] |
| mutants_config | Optional cargo-mutants configuration file. It is forwarded as cargo mutants --config <path>. If all mutants are filtered out, the target succeeds and reports no mutants. | Label | optional | None |
| rustc_flags | Additional flags passed through to rustc when compiling the baseline and mutant test binaries. | List of strings | optional | [] |