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?