When running the below test snippet against the binary with cargo test
the environmental variable CARGO_BIN_EXE_<name>
is not available.
Example Code
use std::env;
#[cfg(test)]
fn test_pub_sub() {
let exe_filepath: String = env::var("CARGO_BIN_EXE_pub-sub-learning").unwrap();
// Start a new process
let mut sub_command = Command::new(exe_filepath)
.arg("sub")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.expect("Failed to start pub");
// ...
}
Error message
called `Result::unwrap()` on an `Err` value: NotPresent
I was doing a few things wrong.
tests
directory next to src
. Additionally, validate that the target is a binary (not a library).Files located under the tests directory are integration tests. When you run cargo test, Cargo will compile each of these files as a separate crate, and execute them.
This is the Cargo.toml
file that worked. Importantly, the package is setup to run with the entry point in file src/main.rs
.
[package]
name = "pub-sub-learning"
version = "0.1.0"
edition = "2021"
[dependencies]
# skipping...
env!("CARGO_BIN_EXE_<name>")
instead of env::var("CARGO_BIN_EXE_<name>")
.This section of the Cargo Targets documentation hinted at the problem (emphasis added).
Binary targets are automatically built if there is an integration test. This allows an integration test to execute the binary to exercise and test its behavior. The
CARGO_BIN_EXE_<name>
environment variable is set when the integration test is built so that it can use the env macro to locate the executable.
An important note is that printing out the env::vars()
is misleading. The env macro has access to env variables that are not in env::vars()
!
cargo test
from the CLI instead of an IDE.