0

I have some utility functions in tests/utils/mod.rs that are used by my integration tests, but I also want to create a testing binary that isn't run as part of cargo test but can use the functions in tests/utils/mod.rs. It's a utility that is useful for manual testing, but it only makes sense to run it manually; not using libtest.

The only solution I can think of is to put tests/utils/mod.rs in its own crate, but I'd really like to avoid that because publishing multi-crate workspaces to crates.io is a real pain. Another option would be to just move tests/utils/mod.rs to src/test_utils/mod.rs but that is a bit gross.

Is there a better solution? Maybe something using harness somehow?

Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • 1
    Have you thought about using [`#[path]`](https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute) – Cryptjar Jun 10 '21 at 01:37
  • 1
    Aha nice one! `#[path]` works great. There's a slight issue in that `bin` programs can't have their own dependencies, but I worked around it by making it an example instead of a `bin` [as described here](https://stackoverflow.com/a/46017284/265521). That has another slight downside in that examples aren't built by default, but I can live with that. – Timmmm Jun 10 '21 at 13:28
  • I also though about examples, so I wrapped it up in a full-blown answer. – Cryptjar Jun 10 '21 at 18:01
  • I'm a bit confused about your statement of "examples aren't built by default", I mean they are _not_ built via `cargo build` but your tests aren't built either. And actually this is a good thing, if the crate is a library. On the other hand, `cargo test` *does* build examples by default, they just aren't executed. – Cryptjar Jun 10 '21 at 18:07
  • Yeah that's what I meant - things in `bin` are built by `cargo build` but examples aren't. Correct behaviour for actual examples, but my tool isn't *really* an example. It's not a big deal though. – Timmmm Jun 12 '21 at 15:29

1 Answers1

1

If you have a library crate with the following set up, for instance:

├── Cargo.toml
├── src
│   └── lib.rs
└── tests
    ├── foo.rs
    └── utils
        └── mod.rs

You can add an executable that is compiled but not run via cargo test as an example, and then use the #[path] attribute to point to your utils module.

For example, you can add a bar example:

└── examples
    └── bar.rs

with the following code:

// using the testing utilities
#[path="../tests/utils/mod.rs"]
mod utils;

fn main() {
    // do something useful with `utils`
}

Notice, the #[path] attribute, which includes the utils module from the integration tests.

And you can conveniently run it manually with:

cargo run --example bar

Also, you can add additional dependencies for bar.rs below [dev-dependencies] in Cargo.toml.

Cryptjar
  • 1,079
  • 8
  • 13