docs / Getting Started / The miri test Runner

The miri test Runner

miri test is a native test runner. It walks a directory tree, discovers every @test function, and runs each one in its own subprocess — so a test that segfaults is reported as a failure instead of taking the whole run down with it.

use system.testing

// `miri test` discovers every @test function in the directory tree and runs
// each one in its own subprocess, so a crash reports as a failure rather
// than taking the whole run down.
@test
fn addition_works()
    assert_eq(2 + 2, 4)

@test
fn strings_concatenate()
    assert_eq("mi" + "ri", "miri")

// @ignore skips the test and prints the reason. It requires @test.
@test
@ignore("needs a fixture file")
fn reads_the_config()
    assert(false)

// @xfail pins a known bug: the test is expected to fail, and the run turns
// red if it starts passing — so a fixed bug cannot stay marked broken.
@test
@xfail("sub-word element stride, tracked upstream")
fn known_bug()
    assert_eq(1, 2)

Run it against a directory:

miri test --dir .

which reports in the familiar cargo style:

running 4 tests
test docs-test-runner.mi::addition_works ... ok
test docs-test-runner.mi::strings_concatenate ... ok
test docs-test-runner.mi::reads_the_config ... ignored, needs a fixture file
test docs-test-runner.mi::known_bug ... ok (expected failure)
test result: ok. 3 passed; 0 failed; 1 ignored
OptionEffect
--dir DIRDirectory to search. Defaults to the current directory.
--filter SUBSTRINGRuns only tests whose path::name contains the substring.
--format pretty|jsonHuman-readable (default) or machine-readable output.

The point of @xfail is that it refuses to rot. A known-broken test stays in the suite and stays red-free, but the moment the underlying bug is fixed the test starts passing and the run turns red with FAILED (unexpected pass) — so a fix cannot land while the bug is still marked broken. That is the opposite of commenting a test out, which is how known bugs normally become forgotten bugs.

Two file shapes are rejected rather than run: a file that declares its own main (it would collide with the dispatcher the runner synthesizes), and a file with executable statements outside any function (they would be silently dropped). A rejected file fails the run even when every test that did execute passed.