Assuming following folder structure:
src/
lib.zig
module_a/
file_a.zig
file_a_test.zig
module_b/
file_b.zig
file_b_test.zig
tools/
tools.zig
tools_test.zig
How should I structure my build.zig in order to be somehow able to use:
const tools = @import("tools")
in my two other modules: module_a and module_b?
I also want to be able to run the tests somehow, so they don't break, for example in this fassion:
zig test src/module_a/file_a_test.zig
This is NOT an application, I don't have a main.zig file.
I can have a lib.zig file though somewhere under src directory if it's needed.
Tried to look for a simple answer on Reddit and on StackOverflow, but couldn't find any. All the solutions use either an old std.build.Pkg system, or b.addModule but with a main.zig build target.
Ok, so eventually I was able to figure this one out, but there could be some kind of a tutorial about this, because this was a trial and error.
So I've managed to add a main testing file to my file structure and it now looks like this:
src/
lib.zig
lib_test.zig
module_a/
file_a.zig
file_a_test.zig
module_b/
file_b.zig
file_b_test.zig
tools/
tools.zig
tools_test.zig
The content of lib_test.zig is as follows:
const std = @import("std");
test {
_ = @import("module_a/file_a_test.zig");
_ = @import("module_b/file_b_test.zig");
_ = @import("tools/tools_test.zig");
}
test "my custom lib test" {
try std.testing.assert(1 == 1)
}
And my content of build.zig is like this:
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const tools = b.addModule("tools", .{ .source_file = .{ .path = "src/tools/tools.zig" } });
const module_a = b.addModule("module-a", .{ .source_file = .{ .path = "src/module_a/file_a.zig" } });
const module_b = b.addModule("module-b", .{ .source_file = .{ .path = "src/module_b/file_b.zig" } });
const unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/lib_test.zig" },
.target = target,
.optimize = optimize,
});
unit_tests.addModule("tools", tools);
unit_tests.addModule("module-a", module_a);
unit_tests.addModule("module-b", module_b);
const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}
So we have to create our tools module by addModule, and then when adding another modules to the build "namespace" we have to provide all the dependencies that those modules (i.e. .zig files) use, we do that by providing them to unit_tests, because unit tests are in fact "ran".
We can gather all the tests into a single file with a special test syntax.
After that to run the tests we do:
zig build test
The tests are ran every time there is a change in the code, not every time we invoke the command.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With