srjilarious/testz
A testing library for zig
#f7a41d
Testz is a testing library for zig that provides some extra features compared to the built in unit testing.
Color output with both a verbose mode and non-verbose mode
A non-verbose mode, where each test shows as a symbol for passed, skipped, or failed:
In verbose mode, you can see the name of each test run and how long it took to run.
In both cases a test run summary lets you know how many tests ran and the overall time.
Easy filtering by group tag or test name itself
Provides a test runner utility function with argument parsing for a default use case.
Has a test discovery helper that searches for tests by finding public functions in a passed in module, allowing tests to be skipped by prepending skip_
to the start of the function name.
[!Note] Stack traces with extra context not yet implemented for Zig 0.14.
testz
itself as well as main
where the test runner is called.Testz runners are just another executable you setup in your build.zig
, with the library providing a number of helpers to make it as easy as possible to create tests. Debugging is simple since you can run your debugger just like with any normal flat executable and use the built in filtering to narrow down what test or set of tests gets run.
Check the example program under example/
with a main program and a separate test program.
A module of tests looks like:
const std = @import("std");
const testz = @import("testz");
pub fn allowNonTestzErrorsTest() !void {
const mem = try std.heap.page_allocator.alloc(u8, 10);
defer std.heap.page_allocator.free(mem);
try testz.expectEqual(true, true);
}
pub fn alwaysFailTest() !void {
try testz.fail();
}
pub fn successTest() !void {
try testz.expectEqual(12, 12);
try testz.expectEqualStr("hello", "hello");
try testz.expectNotEqual(10, 20);
try testz.expectNotEqualStr("hello", "world");
try testz.expectTrue(true);
try testz.expectFalse(false);
}
pub fn skip_Test() !void {
// nothing to see here.
}
The test functions are simply any public function in a module you pass into discoverTests
. The testz
library has a number of expectXYZ
functions you can use to make assertions in your code. If one fails, testz
will capture the name of the failed test, error message, and stack trace (with contextual lines).
This is a test runner program using the built-in testzRunner
method that you could use in your project, which handles standard argument parsing. It also shows test discovery by passing in modules as groups to the discoverTests
method.
const std = @import("std");
const testz = @import("testz");
const DiscoveredTests = testz.discoverTests(.{
testz.Group{ .name = "Expect Tests", .tag = "expect", .mod = @import("./expect_tests.zig") },
testz.Group{ .name = "Misc Tests", .tag = "misc", .mod = @import("./misc_tests.zig") }
});
pub fn main() !void {
try testz.testzRunner(DiscoveredTests);
}
The function testsz.discoverTests
, takes a tuple of either direct module @import
s, or testz.Group
structs, which contain a group name and tag for filtering as well as the module to scan for test functions.
build.zig
SetupRun zig fetch --save https://github.com/srjilarious/testz
to add testz
as a dependency in your build.zig.zon
file.
Next, in your build.zig
, you would create a new exe for your tests and add:
const testzMod = b.dependency("testz", .{});
[...]
testsExe.root_module.addImport("testz", testzMod.module("testz"));
See the project under example/
for how this looks in a simple dummy project.
The library has all of the initial features I set out to implement. Feel free to open an issue or open a PR if there is a feature you'd like to see!
Capture number of assertions in each test