Zig build test cannot find module named "token" available within module "root"

I have been attempting to write a lexer in zig. I wanted to add some unit tests for the lexer and so i added this to the default build.zig generated with zig init.

const lexer_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/assembler/lexer/test.zig"),
            .optimize = optimize,
            .target = target
        })
    });
    const run_lexer_tests = b.addRunArtifact(lexer_tests);

// ...

test_step.dependOn(&run_lexer_tests.step);

I also declared two important modules that will be used within my project widely:

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

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

const exe = b.addExecutable(.{
        .name = "irvm",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
            .imports = &.{
                .{ .name = "irvm", .module = root_mod },
                .{ .name = "token", .module = token_mod },
                .{ .name = "isa", .module = isa_mod },
            },
        }),
    });

when attempting to run zig build test i get this error:

src/assembler/lexer/test.zig:5:27: error: no module named 'token' available within module 'root'
const TokenKind = @import("token").TokenKind;

I have been attempting to fix this for a while, but my lack of knowledge on how zig’s build system works has stopped me from making any progress. Does anyone know where I went wrong?

you need to add the imports to your test

Could you please clarify?

The module you create for testing doesn’t add the import(s) that the test code requires.

You add imports the same way you did with your main executable.

thank you! This has fixed the issue.

Just as a follow-up:

These can be ‘hoisted’ like so:

const module_imports: []const Import = &.{
    .{ .name = "irvm", .module = root_mod },
    .{ .name = "token", .module = token_mod },
    .{ .name = "isa", .module = isa_mod },
};

Then reused everywhere they’re needed. Less fussing about if and when more imports happen (as they tend to).

1 Like