#How to test a module that depends on other modules

1 messages · Page 1 of 1 (latest)

robust wolf
#

I have a module dag that depends on another module sys. The source code works fine, but when I execute my tests for the dag module I get the following error:

src/dag/node.zig:3:21: error: no module named 'sys' available within module test
const sys = @import("sys");

I figured that I just needed to add sys as an import to the test executable in the same way that I added it as an import to the main executable in my build.zig. Here is the code I tried:

const sys = b.createModule(.{
    .root_source_file = .{ .path = "src/sys/sys.zig" },
    .target = target,
    .optimize = optimize,
});

exe.root_module.addImport("sys", sys);
exe_unit_tests.root_module.addImport("sys", sys); // added this line

However, this did not resolve the error. Is this even possible or am I a bad person for trying to put non-unit tests in a file that uses multiple modules?

Minimal example: https://github.com/mitchelldw01/tmp/tree/main

GitHub

Contribute to mitchelldw01/tmp development by creating an account on GitHub.

#

I also have the following code in my test, which did not fix the error.

const testing = std.testing;
testing.refAllDecls(@This());
random turret
#

not sure if this is the best way, but you can do sys.addImport("sys", sys);

#

oh i think i misunderstood the question. maybe you need to add sys to the dag module?

robust wolf
#

yeah I have sys as import in the dag module, and it works fine in the source code

const dag = b.createModule(.{
    .root_source_file = .{ .path = "src/dag/dag.zig" },
    .target = target,
    .optimize = optimize,
    .imports = &.{
        .{ .name = "diag", .module = diag },
        .{ .name = "sys", .module = sys },
    },
});

exe.root_module.addImport("dag", dag);
random turret
#

could you show how you init exe_unit_tests?

robust wolf
#

just the way zig init does it

// Creates a step for unit testing. This only builds the test executable
// but does not run it.
const exe_unit_tests = b.addTest(.{
    .root_source_file = .{ .path = "src/main.zig" },
    .target = target,
    .optimize = optimize,
});

const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);

// Similar to creating the run step earlier, this exposes a `test` step to
// the `zig build --help` menu, providing a way for the user to request
// running the unit tests.
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_exe_unit_tests.step);
random turret
#

not sure but you might have to add the dag module to exe_unit_tests?

robust wolf
#

I'm doing that like this exe_unit_tests.root_module.addImport("dag", dag); but no luck

random turret
#

if you add dag, can you access sys through it?

#

ie const sys = @import("dag").sys;

robust wolf
#

nope I can't

random turret
#

if its not too big, maybe post you whole buld.zig. otherwise could you post it to https://zigbin.io/ ?

robust wolf
#

build.zig in that repo ^

random turret
#

oh nevermind. thanks will have a look

#

oic. you're running zig test src/dag.zig. if you want to just test the one file on the command line, you'll need to also add flags for the module.

#

it appears that zig build test works fine. if you want to see the flags, run zig build test --verbose

#

does that make sense? the issue was that you're using zig test ... which doesn't use the build.zig

#

you need to run zig build test for that to happen

robust wolf
#

zig build test doesn't look like it's running the actual test though unless I'm confused

#

The output of zig built test --verbose looks the same before and after adding testing.expectEqual(1, 2); to my test just to make it fail

random turret
#

try adding zig build test --summary all to see a report

#

it might be cached in which case it won't run.

#

and if you want to make sure it always runs, even when cached: run_exe_unit_tests.has_side_effects = true;

random turret
#

which file is this in?

robust wolf
#

No worries. I just pushed my updates: I added the line to make the test fail in src/dag.zig. I also added run_exe_unit_tests.has_side_effects = true; to thet build.zig

random turret
#

ok i'll pull and try again.

robust wolf
#

I also commented out the test in main.zig

random turret
#

i think i see the problem. you'll need to reference the files you want to test from a test block in main.zig or whatever file you specify as root_source_file for your tests.

#

something like this

test {
    _ = @import("dag.zig");
}
robust wolf
#

Oooh that was it for the minimal example. However when I try to do the same in my main project I get the error

src/sys/sys.zig:1:1: error: file exists in multiple modules
src/sys/sys.zig:1:1: note: root of module sys
src/main.zig:112:17: note: imported from module root
    _ = @import("sys/sys.zig");
random turret
#

maybe change that line to @import("sys")

robust wolf
#

yup tried that too but same error

random turret
#

i'm a little worried you might have added some unnecessary stuff at this point. i've been there fighting with the module system before. i would recommend removing all the modules and trying to just import files. and then maybe you can add back modules only where necessary?

robust wolf
#

I made a silly mistake in the main project. sys/sys.zig is the root of the module but didn't contain the tests so I just needed to import the correct file. So your solution worked in my main project as well 🙏

#

Yeah the module system has been annoying as a zig beginner it just feels more "right" for some things as opposed to importing from files only

random turret
#

good news! yeah i agree. the module system can seem a little restrictive sometimes with the 'multiple modules' error. but i think after a while i stopped having problems with it.