Add ability for integration test to use items from other files

I have an integration test in tests/ folder that doesn't do that much, but the file is disproportionately large and noisy. This is because I have helper functions that:

  • configure each docker container used in the test
  • handle nested errors (each node in the error tree has its own dedicated helper function)
  • extract logs from each container to print it in a pretty format to output

The number of helper functions needed would significantly increase if I:

  • add more containers
  • add assertions for which values are expected in some container's log in various places along the flow of execution
  • add more granular configurations to each container

This results in poor signal/noise ratio when you have to put all this mess into one file in tests/. So I'd like to move the helper functions into a separate file in tests/ folder (perhaps tests/lib.rs) and perhaps reuse them across multiple integration tests.

I experimented with moving the helpers into a file in src/. The problem now is that these helpers would be included in the binary used in production so it bloats the binary. But if I add #![cfg(test)], then they are no longer available from tests/ folder.

Some options

  • Create a separate test library that you depend on
  • Use a single integration test binary with modules, rather than a integration test binary per file, see Delete Cargo Integration Tests
2 Likes

What I've seen people do is put the helpers inside a new folder within tests:

tests/
    one.rs
    two.rs
    helpers/
        helpers.rs

Then access helpers but putting this in each file:

#[path = "helpers/helpers.rs"]
mod helpers;

Please, avoid using #[path = "..."], it makes reasoning about modules even harder. Instead, put helper.rs inside the tests folder, or leave it inside the helpers folder but name it mod.rs.

Have you tried that? I wasn't sure if either of those would work, so I put something I knew would. I figure you don't want the helpers module interpreted as an integration test itself, and I don't have the experience to know whether the sibling module works for integration tests (like is each integration test treated like lib.rs?)

the 2nd one worked really nicely, thanks! (:

It would work when used, but tests/helpers.rs would get interpreted as another integration test, wasting compilation time and test target namespace. However, I also agree that #[path] is undesirable; using tests/helpers/mod.rs solves both problems.

and I don't have the experience to know whether the sibling module works for integration tests (like is each integration test treated like lib.rs?)

Yes, it is; rustc has only one set of rules for module lookup that apply equally to all kinds of crate root files.

4 Likes