std/test

Tests, which cuarzo test runs. A test file is a file whose name ends in _test.cz; its tests are the functions whose names start with test_ and that take nothing:

// shapes_test.cz
import "std/test"
import "shapes"

func test_area() do
    assert_equal(area(2, 3), 6)
end
cuarzo test                         every *_test.cz file under this folder,
                                    or in a project, those its cuarzo.toml names
cuarzo test shapes_test.cz tests/   these files and folders

A test passes unless an assertion fails, it panics, or it stops with a runtime error; a test that brings its program down fails with what the program printed. Each test file is built into a program of its own (in build/tests beside it), and the programs run side by side.

Option
--filter <text> only the tests whose names, or file::name, hold the text
-j <n> how many test programs run at once (4)
--bench run the benchmarks instead of the tests
--coverage count the lines that run, and report them for each file of the program, with build/coverage.lcov
--update-snapshots take the snapshots again
--json results as JSON lines, one for each test, for editors
--junit <file.xml> results as JUnit XML too, for CI
--profile <name>, --release in a project, the profile to build the tests with; debug otherwise

Assertions

Function Fails unless
assert_equal(actual, expected) they are equal; text of several lines shows the lines that differ
assert_not_equal(actual, other) they differ
assert_true(value), assert_false(value)
assert_items(actual, expected) two arrays have equal items, in order; says which differ
assert_contains(text, part)
assert_ok(result) a Result is OK, and gives what it holds
assert_error(result) a Result is an ERROR, and gives the error
assert_panics(body) calling body panics, and gives the message
assert_fail(message) never: it fails the test at once

Each takes a message last, to say what was checked.

Setup, async tests, and benchmarks

setup() and teardown(), when a test file has them, run before and after each test. An async func test_...() is a test on the event loop: it passes when its task settles OK. A function whose name starts with bench_ is a benchmark, which cuarzo test --bench runs in rounds for about a second, reporting the time of one call: its mean, standard deviation, least, and median.

Properties

check_property(gen, holds, runs) checks that holds is true for runs random values (100 unless given). When one fails, it is shrunk to the smallest that still fails, which the failure shows:

func test_sum() do
    check_property(gen_items(gen_int(0, 100), 10), func(int[] xs) bool => sum(xs) >= 0)
end

Values come from gen_int(low, high), gen_bool(), gen_str(max_length, letters), gen_items(gen, max_length), and gen_one_of(choices, show), or any Gen[T], which says how to make a value, the smaller values to try, and how to show one.

Snapshots

assert_snapshot(name, text) keeps text in snapshots/ beside the test file the first time, and later compares with it; cuarzo test --update-snapshots takes it again when the change is wanted.

Interactive programs

open_terminal(command, columns, rows) starts a program on a terminal of its own (a pseudo-terminal) and draws what it writes on a screen, as a terminal would, so a test can drive a full-screen program or a game:

func test_menu() do
    TestTerminal t = assert_ok(open_terminal(["build/menu"], 80, 24))
    defer t.close()
    assert_true(t.wait_for("Choose a file"))
    t.send(KEY_DOWN + KEY_ENTER)
    assert_true(t.wait_for("Opened"))
    assert_true(t.style_at(0, 0).bold)
end

send(keys) types text or keys (KEY_UP, KEY_ENTER, ctrl('c'), and the others); wait_for(text, timeout_ms) waits for the screen to show text; text() and line(row) read the screen; style_at(row, column) gives a character's colors and attributes, as a TerminalStyle of std/terminal_emulator, which draws the screen; cursor() where the cursor is; wait_exit(timeout_ms) the program's status. The screen follows the sequences terminal programs use: cursor movement, erasing, scrolling regions, the alternate screen, and colors in 16, 256, and 24-bit forms.