Hi, I’m trying to write unit tests for my project that depends on itself:
./src
├── me.zig
├── mod_a.zig
├── mod_b.zig
└── test.zig
me.zig exposes mod_a.zig and mod_b.zig:
pub const mod_a = @import("mod_a.zig");
pub const mod_b = @import("mod_b.zig");
mod_a has a function and a test that calls a function from mod_b:
const mod_b = @import("me").mod_b;
pub fn mod_a_fn() void {
@import("std").log.info("hello mod_a", .{});
mod_b.mod_b_fn();
}
test "mod_a_test" {
mod_b.mod_b_fn();
try @import("std").testing.expect(true);
}
mod_b does not have any dependencies, so I don’t write here.
I added me as a module to my executable by addImport(), and it works completely fine for main executable:
const me = b.createModule(.{
.root_source_file = b.path("src/me.zig"),
});
const exe = b.addExecutable(.{
.name = "main",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("me", me);
me.addImport("me", me);
However, when I tried to add me module to my unit test, problem occurs.
Try 1: Import me module to the test executable
First, I tried to add me module to my test executable in the same way as a main executable. My build.zig is:
const exe_unit_tests = b.addTest(.{
.name = "unit",
.root_source_file = .{ .path = "src/test.zig" },
.target = target,
.optimize = optimize,
});
exe_unit_tests.root_module.addImport("me", me);
test.zig is:
pub const me = @import("me");
comptime {
@import("std").testing.refAllDeclsRecursive(@This());
@import("std").testing.refAllDeclsRecursive(me);
}
In this case, no tests were run. I guess this is because Zig does not run tests in a dependent modules (though I want it to be tested).
Try 2: Add me module and import me.zig
I tried to import mod_a.zig or me.zig instead of me module in test.zig:
comptime {
_ = @import("me.zig");
@import("std").testing.refAllDeclsRecursive(@This());
}
However, the build fails saying that error: file exists in multiple modules. I know that this is because me.zig is imported twice in test.zig and root module (me itself).
Try 3: Do not add module me
Finally, I removed addImport() from the test executable and used relative imports. build.zig is:
const exe_unit_tests = b.addTest(.{
.name = "unit",
.root_source_file = .{ .path = "src/test.zig" },
.target = target,
.optimize = optimize,
});
test.zig is:
comptime {
_ = @import("me.zig"); // or mod_a.zig
@import("std").testing.refAllDeclsRecursive(@This());
}
It fails of course, because module me is not defined.
So all my tries resulted in failures. Could you tell me how to add unit tests to the project that imports itself?