为何测试环境中不存在CARGO_BIN_EXE_<name>环境变量?
解决cargo test中无法获取CARGO_BIN_EXE_环境变量的问题
问题根源
CARGO_BIN_EXE_*这类环境变量是Cargo专为集成测试(放在项目根目录tests文件夹下的测试代码)自动注入的。如果你的测试是写在src目录里的单元测试(比如带#[cfg(test)]标注的本地测试),Cargo不会自动设置这些变量,自然会抛出NotPresent错误。
另外也可能是你写错了二进制目标名称——环境变量里的<name>必须和Cargo.toml中[[bin]]字段的name值完全一致,连字符、大小写都不能错。
可行解决办法
办法1:把测试移到tests目录(推荐)
将测试代码从src目录迁移到项目根目录下的tests文件夹,Cargo会自动识别这是集成测试,注入对应的CARGO_BIN_EXE_*环境变量。
比如创建tests/pub_sub_test.rs,代码如下:
use std::env; use std::process::{Command, Stdio}; #[test] fn test_pub_sub() { let exe_filepath = env::var("CARGO_BIN_EXE_pub-sub-learning").unwrap(); let mut sub_command = Command::new(exe_filepath) .arg("sub") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .expect("Failed to start subscriber"); // 这里写后续测试逻辑 }
办法2:手动指定二进制路径(适用于不想移动的单元测试)
如果不想调整测试位置,可以手动构建二进制后直接引用路径:
- 先提前构建二进制:
cargo build
- 在测试代码里直接拼接路径,或者用
env!宏获取项目目录:
use std::path::Path; use std::process::{Command, Stdio}; #[cfg(test)] fn test_pub_sub() { // 注意根据操作系统调整后缀,Windows下要加.exe let exe_path = Path::new(env!("CARGO_MANIFEST_DIR")) .join("target/debug/pub-sub-learning"); let mut sub_command = Command::new(exe_path) .arg("sub") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .expect("Failed to start subscriber"); // 后续测试逻辑... }
或者也可以在运行测试前手动设置环境变量:
CARGO_BIN_EXE_pub-sub-learning=$(cargo build --message-format=json | jq -r '.executable' | grep -v null) cargo test
办法3:核对二进制目标名称
打开Cargo.toml,确认[[bin]]中的name字段和你代码里用的环境变量名称完全一致。比如:
[[bin]] name = "pub-sub-learning" path = "src/main.rs"
如果name是pub_sub_learning(下划线代替连字符),那环境变量就得写成CARGO_BIN_EXE_pub_sub_learning,大小写也必须完全匹配。
内容的提问来源于stack exchange,提问作者Daniel Butler
相关产品推荐
相关产品推荐

