I would like to run the following command :
zig test --test-filter ‘Curve’ src/curve.zig
But when I do this I get the folllowing error message :
I linked my depedency with the run exe and the test exe in build.zig, however it won’t compile.
Btw if I use :
zig build test
It works.
1 Like
I think I have found a crude solution I’m sure there is a better one but here we go
const maybe_filters = b.args;
if (maybe_filters) |filters| {
const exe_unit_test_compile = b.addTest(.{
.name = "Project",
.root_source_file = b.path("src/main.zig"),
.optimize = optimize,
.target = target,
.filter = filters[0],
});
exe_unit_test_compile.linkLibrary(raylib_artifact);
exe_unit_test_compile.root_module.addImport("raylib", raylib);
const exe_unit_test_run_from_artifact = b.addRunArtifact(exe_unit_test_compile);
const exe_unit_test_step = b.step("test", "Test Project");
exe_unit_test_step.dependOn(&exe_unit_test_run_from_artifact.step);
} else {
const exe_unit_test_compile = b.addTest(.{
.name = "Project",
.root_source_file = b.path("src/main.zig"),
.optimize = optimize,
.target = target,
});
exe_unit_test_compile.linkLibrary(raylib_artifact);
exe_unit_test_compile.root_module.addImport("raylib", raylib);
const exe_unit_test_run_from_artifact = b.addRunArtifact(exe_unit_test_compile);
const exe_unit_test_step = b.step("test", "Test Project");
exe_unit_test_step.dependOn(&exe_unit_test_run_from_artifact.step);
}
When building (and running) a test executable via the build system you use the filters
field of std.Build.TestOption
(which is passed to b.addTest
) to filter the test cases. You can of course hard code the filter list, but if you want to take filters from the command line, you need to manually define a -D
option that takes a []const []const u8
, for example:
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// ...
const test_filters: []const []const u8 = b.option(
[]const []const u8,
"test_filter",
"Skip tests that do not match any of the specified filters",
) orelse &.{};
const lib_unit_tests = b.addTest(.{
.root_source_file = b.path("src/root.zig"),
.target = target,
.filters = test_filters,
.optimize = optimize,
});
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_lib_unit_tests.step);
}
With this option defined, you can invoke the build like zig build test -Dtest_filter=one -Dtest_filter=two
to only run tests with names containing the substrings one
and two
.
2 Likes
At tigerbeetle, we do
const unit_tests = b.addTest(.{
.root_source_file = b.path("src/unit_tests.zig"),
.target = target,
.optimize = mode,
.filters = b.args orelse &.{}, // <- this
});
the usage looks like
./zig/zig build test -- state_sync
7 Likes
That’s clever, though one drawback is that it’s less automatically discoverable by random users since they can’t just clone the project, run zig build --help
and discover it as a project-specific option that way. I think most users would assume that args after --
will be forwarded to the program being run.