Testing and Benchmarks
A test or a benchmark in Zaza is an executable plus a list of run cases. Each
case is data: a label, arguments, an environment, and a working directory. The
API in build_lib/test_suite.zig turns that list into the run steps and the
per-case and aggregate build steps, so a build file states what to run instead
of wiring run steps by hand.
const cpp = @import("../../build_lib/cpp_example.zig");
const test_suite = @import("../../build_lib/test_suite.zig");
const demo = cpp.CppExample.executable(.{
.name = "workflows_demo",
.description = "workflow example",
.source_files = &.{"examples/test_workflows/src/main.cpp"},
.cpp_std = "17",
});
_ = try test_suite.addTest(b, target, .{
.name = "test-workflows",
.target = demo,
.cases = &.{
.{ .label = "unit", .args = &.{"unit"},
.env = &.{.{ .name = "WORKFLOW_MODE", .value = "unit" }},
.cwd = b.path("examples/test_workflows") },
.{ .label = "integration", .args = &.{"integration"} },
.{ .label = "smoke", .args = &.{"smoke"} },
},
});
That call produces test-workflows (build), test-workflows-run (every case),
and one test-workflows-<label> step per case. Because hook_test_step
defaults to true, zig build test runs the cases too.
A RunCase has four fields. label names the run step and its per-case step.
args are passed to the process. env is a list of { name, value } pairs.
cwd is an optional LazyPath for the working directory. Only label is
required.
The compiler and optimize mode come from the CppExample.configs the target
carries, the same way the rest of Zaza chooses them. A test compiles with the
same flags as the normal build because it is built through the same
buildWithTarget.
Benchmarks
addBench has the same shape and different defaults. It builds in release (the
target sets .configs = cpp.BuildConfigs.release_only), stays off the test
step, inherits stdio so timings reach the terminal, and forwards
zig build <step> -- --reps 9 to every case.
const bench = cpp.CppExample.executable(.{
.name = "bench_suite_demo",
.description = "benchmark example",
.source_files = &.{"examples/bench_suite/src/main.cpp"},
.cpp_std = "17",
.configs = cpp.BuildConfigs.release_only,
});
_ = try test_suite.addBench(b, target, .{
.name = "bench-suite",
.target = bench,
.cases = &.{.{ .label = "compute" }},
});
zig build bench-suite-run # default reps
zig build bench-suite-run -- --reps 9 # forwarded to the process
A test asserts and belongs on test. A benchmark measures and does not, so it
stays off test and prints its numbers. The two examples this API drives are
examples/test_workflows and examples/bench_suite, both in
zig build example-matrix.