I have used env!(CARGO_BIN_EXE_<name>) to get the path of the executable for integration testing inside a package. But it seems like it did not work if the <name> refers to an executable from a sibling package in the same workspace. Is that expected?
basically my project has structure like this:
\package_1
\package_2
Cargo.toml
where Cargo.toml is basically this:
[workspace]
members = [
"package_1",
"package_2",
]
My goal is to run an integration test that brings up executables from both package_1 and package_2. What's the recommended way to identify the path of executables? Is it CARGO_BIN_EXE_<name> or something else?
Not sure if CARGO_BIN_PATH is something Cargo usually sets. But it falls back here to finding the current exe path (the test executable), and going up a directory (removing deps). This directory is the directory where the binaries would be found. Usually target/debug/ but sometimes different if --target is passed to Cargo.
Simplifying this a bit. You can have a workspace like this:
[workspace]
members = [
"package_1",
"package_2",
"tests",
]
With a tests/src/lib.rs file that looks like this
use std::env;
use std::path::PathBuf;
pub fn bin_dir() -> PathBuf {
let mut path = env::current_exe().unwrap();
path.pop();
path
}
#[test]
fn hello() {
let dir = bin_dir();
assert!(dir.join("package_1").exists());
assert!(dir.join("package_2").exists());
// now can run binaries with `std::process::Command::new(dir.join("package_1"))` etc
}
The only caveat is that you need to run cargo build --workspace before running cargo test --workspace otherwise the binaries won't be present.
I'm not sure about having tests as its own package in the workspace. That aside, In this case, I guess I can do a similar thing inside, say package_2, right? i.e. use bin_dir() as you described to help get the path of other executables, and use env!(CARGO_BIN_EXE_package_2 to get its own path.
Btw, I also found another way, a bit hacky, but works : Because package_1 and package_2 are always using the same target output directory, their path only diffs in the name part. We can do this:
suppose we are writing a test under package_2/tests/:
let pkg2_bin_path = env!("CARGO_BIN_EXE_package_2");
let pkg1_bin_path = pkg2_bin_path.replace("package_2", "package_1");