Skip to content
Development
Skill

/zig-testing

Zig testing skill for writing and running tests. Use when using zig build test, writing comptime tests, using test filters, working with test allocators to detect leaks, or using Zig's built-in fuzz testing (0.14+). Activates on queries about Zig tests, zig test, zig build test,

From plugin
low-level-dev-skills
159142 skills
Install
$ npx -y skills add mohitmishra786/low-level-dev-skills --skill zig-testing --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/zig-testing

Context preview

The summary Claude sees to decide when to auto-load this skill.

Zig testing skill for writing and running tests. Use when using zig build test, writing comptime tests, using test filters, working with test allocators to detect leaks, or using Zig's built-in fuzz testing (0.14+). Activates on queries about Zig tests, zig test, zig build test,

SKILL.md

zig-testing.SKILL.md
name: zig-testing
description: Zig testing skill for writing and running tests. Use when using zig build test, writing comptime tests, using test filters, working with test allocators to detect leaks, or using Zig's built-in fuzz testing (0.14+). Activates on queries about Zig tests, zig test, zig build test, comptime testing, test allocators, Zig fuzz testing, or detecting memory leaks in Zig tests.

Zig Testing

Purpose

Guide agents through Zig's testing system: `zig build test` and `zig test`, comptime testing patterns, test filters, the test allocator for leak detection, and Zig's built-in fuzz testing introduced in 0.14.

Triggers

  • "How do I write and run tests in Zig?"
  • "How do I filter which Zig tests run?"
  • "How do I detect memory leaks in Zig tests?"
  • "How do I write comptime tests in Zig?"
  • "How do I use Zig's built-in fuzzer?"
  • "How do I test a Zig library?"

Workflow

1. Writing and running tests

// src/math.zig
const std = @import("std");
const testing = std.testing;

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

pub fn divide(a: f64, b: f64) !f64 {
    if (b == 0.0) return error.DivisionByZero;
    return a / b;
}

// Tests live in the same file or a dedicated test file
test "add: basic addition" {
    try testing.expectEqual(@as(i32, 5), add(2, 3));
    try testing.expectEqual(@as(i32, -1), add(2, -3));
}

test "add: identity" {
    try testing.expectEqual(@as(i32, 42), add(42, 0));
}

test "divide: normal case" {
    const result = try divide(10.0, 2.0);
    try testing.expectApproxEqAbs(result, 5.0, 1e-9);
}

test "divide: by zero returns error" {
    try testing.expectError(error.DivisionByZero, divide(1.0, 0.0));
}
# Run all tests in a single file
zig test src/math.zig

# Run all tests via build system
zig build test

# Verbose output
zig build test -- --verbose

# Run specific test by name (substring match)
zig build test -- --test-filter "add"

2. build.zig test configuration

// build.zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // Unit test step
    const unit_tests = b.addTest(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    const run_unit_tests = b.addRunArtifact(unit_tests);

    // Integration tests (separate executable)
    const integration_tests = b.addTest(.{
        .root_source_file = b.path("tests/integration.zig"),
        .target = target,
        .optimize = optimize,
    });
    const run_integration = b.addRunArtifact(integration_tests);

    // `zig build test` runs both
    const test_step = b.step("test", "Run all tests");
    test_step.dependOn(&run_unit_tests.step);
    test_step.dependOn(&run_integration.step);

    // `zig build test-unit` runs only unit tests
    const unit_step = b.step("test-unit", "Run unit tests");
    unit_step.dependOn(&run_unit_tests.step);
}

3. Test allocator — leak detection

The `std.testing.allocator` wraps a `GeneralPurposeAllocator` in test mode and reports leaks at the end of each test:

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

test "ArrayList: no leaks" {
    // testing.allocator detects leaks and reports them
    var list = std.ArrayList(u32).init(testing.allocator);
    defer list.deinit();   // MUST defer to return memory

    try list.append(1);
    try list.append(2);
    try list.append(3);

    try testing.expectEqual(@as(usize, 3), list.items.len);
    // If you forget defer list.deinit(), test reports a leak
}

test "custom allocation" {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer {
        const leaked = gpa.deinit();
        // .ok means no leaks; .leak means memory was not freed
        testing.expect(leaked == .ok) catch @panic("memory leaked!");
    }
    const allocator = gpa.allocator();

    const buf = try allocator.alloc(u8, 1024);
    defer allocator.free(buf);  // leak if forgotten
}

4. Testing assertions

const testing = std.testing;

// Equality
try testing.expectEqual(expected, actual);
try testing.expectEqualStrings("hello", result_str);
try testing.expectEqualSlices(u8, expected_slice, actual_slice);

// Approximate equality (for floats)
try testing.expectApproxEqAbs(expected, actual, tolerance);
try testing.expectApproxEqRel(expected, actual, tolerance);

// Errors
try testing.expectError(error.MyError, might_fail());
try testing.expect(condition);    // basic boolean assertion

// Comparison
try testing.expect(a < b);
try testing.expectStringStartsWith(str, "prefix");
try testing.expectStringEndsWith(str, "suffix");

5. Comptime testing

Zig can run tests at comptime — useful for compile-time constants and type-level checks:

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

// Test comptime functions
fn isPowerOfTwo(n: comptime_int) bool {
    return n > 0 and (n & (n - 1)) == 0;
}

// Comptime assert (compile error if false)
comptime {
    std.debug.assert(isPowerOfTwo(16));
    std.debug.assert(!isPowerOfTwo(15));
    std.debug.assert(isPowerOfTwo(1024));
}

// Test with comptime-known values (runs at comptime in test mode)
test "isPowerOfTwo: comptime" {
    comptime {
        try testing.expect(isPowerOfTwo(8));
        try testing.expect(!isPowerOfTwo(7));
    }
}

// Type-level testing
test "type properties" {
    // Verify alignment and size at comptime
    comptime {
        try testing.expectEqual(8, @alignOf(u64));
        try testing.expectEqual(4, @sizeOf(u32));
        try testing.expectEqual(true, @typeInfo(u8).Int.signedness == .unsigned);
    }
}

6. Fuzz testing (Zig 0.14+)

Zig 0.14 introduced a built-in fuzzer using coverage-guided fuzzing:

// fuzz_target.zig
const std = @import("std");

// Fuzz entry point: receives arbitrary bytes
export fn fuzz(input: []const u8) void {
    // Ca
Read more
Ships withlow-level-dev-skills

A curated suite of AI agent skills for systems and low-level programming — C/C++, Rust, Zig, GPU, bare-metal firmware, Linux kernel/driver development, computer architecture, compiler internals, HPC, and more.

Get the whole plugin
Stats
172
Stars
24
Forks
Maintained
Maintenance
JavaScript
Language
MIT
License
1mo ago
Last commit
5mo ago
Created

Repo: mohitmishra786/low-level-dev-skills

Other skills on low-level-dev-skills.