Zig Test

Zig Test

zig test is a tool that can be used to quickly build and run Zig code to make sure behavior meets expectations. @import("builtin").is_test is available for code to detect whether the current build is a test build.

detect_test.zig

const std = @import("std");
const builtin = @import("builtin");
const assert = std.debug.assert;

test "builtin.is_test" {
    assert(builtin.is_test);
}
``` ```
$ zig test detect_test.zig
Test 1/1 builtin.is_test...OK
All tests passed.

Zig has lazy top level declaration analysis, which means that if a function is not called, or otherwise used, it is not analyzed. This means that there may be an undiscovered compile error in a function because it is never called.

unused_fn.zig

fn unused() i32 {
    return "wrong return type";
}
test "unused function" { }
``` ```
$ zig test unused_fn.zig
Test 1/1 unused function...OK
All tests passed.

Note that, while in Debug and ReleaseSafe modes, unreachable emits a call to @panic, in ReleaseFast and ReleaseSmall modes, it is really undefined behavior. The implementation of std.debug.assert is as simple as:

pub fn assert(ok: bool) void {
    if (!ok) unreachable;
}

This means that when testing in ReleaseFast or ReleaseSmall mode, assert is not sufficient to check the result of a computation:

assert.zig

const std = @import("std");
const assert = std.debug.assert;

test "assert in release fast mode" {
    assert(false);
}
``` ```
$ zig test assert.zig --release-fast
Test 1/1 assert in release fast mode...OK
All tests passed.

Note that although the above example shows the test passing, this is invoking unchecked Undefined Behavior. This documentation is showing only one possible outcome of this test.

Better practice for checking the output when testing is to use std.testing.expect:

test.zig

const std = @import("std");
const expect = std.testing.expect;

test "assert in release fast mode" {
    expect(false);
}
``` ```
$ zig test test.zig --release-fast
Test 1/1 assert in release fast mode...test failure

Tests failed. Use the following command to reproduce the failure:
/home/andy/dev/zig/docgen_tmp/test

See the rest of the std.testing namespace for more available functions.

zig test has a few command line parameters which affect the compilation. See zig --help for a full list. The most interesting one is --test-filter [text]. This makes the test build only include tests whose name contains the supplied filter text. Again, thanks to lazy analysis, this can allow you to narrow a build to only a few functions in isolation.