How to filter test using --test-filter 'test-name' in conjunction with build.zig

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.

4 Likes