Skip to content
CryoCryo home
LanguageTesting

21Testing

Cryo ships a built-in unit-test framework. Tests live in <project>/tests/ files whose namespace declaration carries the ![config(testing)] directive. Inside such a file, every function marked ![test] is auto-discovered by the compiler and run fork-per-test by cryo test.

![config(testing)]
namespace MyApp::Tests;

import std::test::assert::{ expect_eq, expect, bail };

![test]
function addition_is_commutative() -> Result<(), TestError> {
    return expect_eq(1 + 2, 2 + 1);
}

![test]
![ignore]
function expensive_integration_test() -> Result<(), TestError> {
    // Run only when the user passes --ignored.
    return expect(setup_real_environment(), "environment ready");
}

![test]
![should_panic]
function unwrap_none_panics() -> Result<(), TestError> {
    const empty: Option<int> = Option::None;
    const _value: int = empty.unwrap();   // panics
    return bail("unwrap should have panicked");
}

A test function returns Result<(), TestError>. Ok(()) is success; Err(...) is failure with a message. The assert module provides:

  • expect(condition, message): fails if the condition is false.
  • expect_eq(a, b): fails if a != b (requires T: Eq + Display).
  • expect_ne(a, b): fails if a == b.
  • bail(message): unconditional failure.
  • bail_other(message): non-assertion failure (treated as an error rather than a test fail).

The runner forks a child process per test, captures its output, and applies the ![should_panic] inversion if requested. Run with:

cryo test                          # run every discoverable test
cryo test some_filter              # run tests whose name contains "some_filter"
cryo test --list                   # discover only; print and exit
cryo test --ignored                # also run ![ignore]-marked tests
cryo test --exact                  # treat the filter as an exact match
cryo test -q, --quiet              # suppress per-test ok / ignored lines

Output format

The runner ships three output formats; --format=<mode> picks per-run:

FormatLayout
plainCargo-style test NAME ... ok lines; CI-friendly. Default.
prettyTests grouped under their namespace, indented leaves, [PASS] / [FAIL] / [skip] chips. Colored on a TTY.
compactOne line per namespace with a dot-stream of results (. pass, F fail, s skip, P did-not-panic, E runner error) and a trailing per-group tally.

Color follows --color=<auto|always|never>. auto (default) emits ANSI escapes only when stdout is a terminal; the NO_COLOR environment variable forces it off per https://no-color.org/.

Configuration precedence is CLI flag > environment variable > cryoconfig > built-in default:

cryo test --format=pretty --color=always
CRYO_TEST_FORMAT=compact CRYO_TEST_COLOR=never cryo test
# cryoconfig
[test]
format = "pretty"   # one of: plain | pretty | compact
color  = "auto"     # one of: auto  | always | never

cryo test forwards [test] format = "..." to the spawned test binary as --format=..., so the cryoconfig defaults travel without needing exported environment variables.