pyk/exetest
CLI testing for Zig
CLI testing for Zig.
Fetch the latest release:
zig fetch --save=exetest https://github.com/pyk/exetest/archive/v0.1.0.tar.gz
This updates build.zig.zon.
Write your test file. Example: test/echo.zig.
const std = @import("std");
const exetest = @import("exetest");
const testing = std.testing;
test "echo" {
const argv = &[_][]const u8{"echo", "hello"};
var result = try exetest.run(.{ .argv = argv });
defer result.deinit();
try testing.expectEqualStrings("hello\n", result.stdout);
}
Register the test in build.zig:
const std = @import("std");
const exetest = @import("exetest");
pub fn build(b: *std.Build) void {
// ...
const echo_test = exetest.add(b, .{
.name = "echo",
.test_file = b.path("test/echo.zig"),
});
const test_step = b.step("test", "Run tests");
test_step.dependOn(&echo_test.step);
}
Run the tests:
zig build test --summary all
See minimal Zig project exetest-example.
There are only 2 functions:
add(b, options) registers a CLI test step in build.zig. zig build test
will run the tests.run(options) spawns a child process, captures stdout and stderr (up to a
limit), waits for the child to finish, and returns a RunResult.Basic run and stdout assertion:
const std = @import("std");
const exetest = @import("exetest");
const testing = std.testing;
test "echo" {
const argv = &[_][]const u8{"echo", "hello"};
var result = try exetest.run(.{ .argv = argv });
defer result.deinit();
try testing.expectEqualStrings("hello\n", result.stdout);
}
Write to stdin and capture stdout:
const std = @import("std");
const exetest = @import("exetest");
const testing = std.testing;
test "cat" {
const argv = &[_][]const u8{"cat"};
const input = "a\nb\n";
var result = try exetest.run(.{ .argv = argv, .stdin = input });
defer result.deinit();
try testing.expectEqualStrings(input, result.stdout);
}
Limit how many stdin bytes are sent:
const payload = large_slice; // some []const u8
var result = try exetest.run(.{
.argv = argv,
.stdin = payload,
.max_stdin_bytes = 1024, // truncate to 1 KiB
});
defer result.deinit();
And you can do much more:
stderr output.See src/test_exe.zig.
Some additional notes about the usage of allocator:
run uses testing.allocator by default.RunOptions.allocator to control where
captured buffers are allocated.Install the Zig toolchain via mise (optional):
mise trust
mise install
Run tests:
zig build test --summary all
Build library:
zig build
See LICENSE.