Testing
Stof has a thin testing layer built in, alongside run — #[test] marks a function as a test, and it always runs as its own separate async process.
Test Functions
The assert family — assert, assert_eq, assert_not, assert_neq — comes from the standard library and throws the moment a check fails:
#[test]
fn passes() {
assert(true);
assert_eq("hi", "hi");
assert_not(false);
assert_neq("hi", 42);
pln("all assertions passed");
}This example calls passes() directly rather than using #[main], since #[test] functions aren't meant to run that way — they're picked up by a different command entirely, covered below.
Note: #[test] functions (scopes & imports, too) are not included in the default prod parse profile, so you'll have to change to test when running embedded, outside of the CLI stof test command.
Expecting a Failure
Add #[errors] alongside #[test] when a test is supposed to throw — the CLI's test runner treats that throw as a pass, not a failure:
#[test]
#[errors]
fn fails() {
throw("this is an expected error");
}The playground can't replicate that CLI-level interpretation — calling fails() here just shows the throw itself, which is exactly what #[errors] expects to happen. Whether that throw counts as a pass or a failure is a judgment the stof test command makes, not something visible from the function alone.
Running Tests
stof test replaces stof run at the command line, and reports each test's pass/fail individually, with a small stack trace on anything that failed unexpectedly.