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 = std.builtin;
const expect = std.testing.expect;
test "builtin.is_test" {
expect(builtin.is_test);
}
$ zig test detect_test.zig
1/1 test "builtin.is_test"... OK
All 1 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
1/1 test "unused function"... OK
All 1 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:
const std = @import("std");
const assert = std.debug.assert;
test "assert in release fast mode" {
assert(false);
}
When compiling this test in ReleaseFast mode, it invokes unchecked Undefined Behavior. Since that could do anything, this documentation cannot show you the output.
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 "expect in release fast mode" {
expect(false);
}
$ zig test test.zig -O ReleaseFast
1/1 test "expect in release fast mode"... test failure
error: the following test command crashed:
docgen_tmp/zig-cache/o/d760ff9dc12761126824676bb5d40d62/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.