Testing

23.1 Test Blocks

Test blocks are stripped from non-test builds. Tests run in parallel by the build system.

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

fn add(a: i32, b: i32) i32 { return a + b; }

test "add works" {
    try testing.expect(add(2, 3) == 5);
    try testing.expectEqual(@as(i32, 5), add(2, 3));
}

test "strings and slices" {
    try testing.expectEqualStrings("hello", "hello");
    try testing.expectEqualSlices(u8, &.{ 1, 2 }, &.{ 1, 2 });
    try testing.expectStringStartsWith("hello", "he");
}

test "errors" {
    try testing.expectError(error.InvalidChar, parseDigit('x'));
}

test "no leaks with testing.allocator" {
    const alloc = testing.allocator;              // fails the test on leaks
    var list: std.ArrayList(u8) = .empty;
    defer list.deinit(alloc);
    try list.append(alloc, 1);
    try testing.expect(list.items.len == 1);
}

test "approximate floats" {
    try testing.expectApproxEqAbs(@as(f64, 0.3), 0.1 + 0.2, 1e-9);
}

test "skip" {
    if (@import("builtin").os.tag == .windows) return error.SkipZigTest;
}

test add {                                         // doctest: a test named after a decl (shows in docs)
    try testing.expect(add(1, 1) == 2);
}
zig test src/main.zig
zig test src/main.zig --test-filter "add"
zig build test
zig build test --summary all

23.2 Testing Allocation Failures

std.testing.FailingAllocator fails after N allocations, which verifies errdefer cleanup paths.

test "handles OOM" {
    try testing.checkAllAllocationFailures(testing.allocator, functionUnderTest, .{arg});
}

23.3 Fuzz Testing (0.14+, Integrated)

test "fuzz parser" {
    try std.testing.fuzz({}, struct {
        fn testOne(_: void, input: []const u8) anyerror!void {
            _ = parse(input) catch {};
        }
    }.testOne, .{});
}
zig build test --fuzz          # coverage-guided fuzzing with a web UI

23.4 Test Organization

Put unit tests next to the code in the same file. Use refAllDecls in root files. Put integration tests in separate files added as test artifacts in build.zig.

Snapshot testing: the Snaptest/ohsnap packages. Benchmarks: zBench or a manual std.time.Timer.