docs / Getting Started / Testing

Testing

system.testing provides four assertion intrinsics. Each is lowered directly by the compiler — the abort path is synthesized at the call site, embedding the source path:line in the failure message.

use system.io
use system.testing

fn add(a int, b int) int
    a + b

fn main()
    // Pass silently.
    assert_eq(add(2, 3), 5)
    assert(add(1, 1) == 2, "addition should be commutative")
    assert_ne(add(2, 2), 5)

    // A failing assertion aborts with:
    //   Runtime error: assertion failed at <path>:<line>: expected 6, got 5
    // assert_eq(add(2, 3), 6)

    // assert_panics catches Miri-level panic(...) calls.
    assert_panics(fn(): panic("boom"), "boom")
FunctionBehaviour
assert(cond, msg?)Aborts when cond is false.
assert_eq<T>(actual, expected, msg?)Aborts when values differ. Supports int/float/bool/String + all int widths, plus enums, Option, Result, structs, and classes defining equals.
assert_ne<T>(a, b, msg?)Aborts when values are equal.
assert_panics(f, expected?)Runs f() and aborts unless it calls panic(...).

A failed assertion aborts with Runtime error: assertion failed at <path>:<line>: <detail>. assert_panics uses a setjmp/longjmp catch frame so a Miri-level panic(...) inside the closure is caught and reported as a pass.

The detail is rendered structurally rather than as an address, so a failure names the values that actually differ:

Compared valuesFailure detail
Structsexpected Point(x=3, y=4), got Point(x=1, y=2)
Enums with a payloadexpected Circle(4), got Circle(3)
Resultexpected Err(boom), got Ok(1)
Optionexpected None, got Some(1)
assert_nevalues must differ, both were 5

The same rendering is available in ordinary string interpolation — an Option, a Result, or any enum you define can go straight into an f-string:

use system.io
use system.testing

enum Shape
    Circle(int)
    Square(int)

struct Point
    x int
    y int

fn missing() int?
    None

fn load() Result<int, String>
    Result.Err("no such key")

fn main()
    // f-strings render Option, Result and any user enum by variant.
    let found = Some(15)
    let absent = missing()
    println(f"{found}")            // Some(15)
    println(f"{absent}")           // None
    println(f"{load()}")           // Err(no such key)

    let shape = Shape.Circle(3)
    println(f"{shape}")            // Circle(3)

    // assert_eq compares and diffs the same shapes, plus structs and any
    // class defining equals:
    //   assert_eq(Point(x: 1, y: 2), Point(x: 3, y: 4))
    //   -> expected Point(x=3, y=4), got Point(x=1, y=2)
    assert_eq(Point(x: 1, y: 2), Point(x: 1, y: 2))
    assert_eq(shape, Shape.Circle(3))

Structural == underpins all of this: enum payloads and managed fields compare by value, not by pointer. Note that a struct renders in an assertion failure but is not itself interpolatable — put its fields in the f-string instead.