如何在cargo test中运行示例并确保示例二进制文件更新?
Rust示例二进制测试时未更新的解决方法
问题描述
- 拥有包含示例代码的Rust库项目,希望通过测试示例间接验证库代码
- 使用
assert_cmd进行测试时,cargo test或cargo test --example ...无法更新示例二进制文件 - 测试能正常运行,但执行的是旧版本的示例二进制
- 确认示例会被构建(添加
compile_error!会阻止测试运行),但Command::cargo_bin(...)调用的二进制并未更新 - 项目目录结构:
project-dir - examples - example_one - main.rs - test.rs - src - lib.rs - Cargo.toml
解决方案
问题根源
Command::cargo_bin("example_one")默认查找target/debug/目录下的二进制文件,但cargo test构建示例时,输出路径是target/debug/examples/,而非根目录的target/debug/,所以调用的是旧的二进制。
修复方法1:指定示例二进制的正确路径
直接构造示例二进制的完整路径,替代cargo_bin:
use assert_cmd::Command; use std::path::Path; #[test] fn test_example_one() { let target_dir = std::env::var("CARGO_TARGET_DIR") .unwrap_or_else(|_| "target".to_string()); let example_path = Path::new(&target_dir) .join("debug") .join("examples") .join("example_one"); let mut cmd = Command::new(example_path); cmd.assert().success(); }
修复方法2:封装获取示例路径的辅助函数
重复使用的话可以封装函数,简化代码:
use assert_cmd::Command; use std::path::PathBuf; fn cargo_example(name: &str) -> PathBuf { let target_dir = std::env::var("CARGO_TARGET_DIR") .unwrap_or_else(|_| "target".to_string()); PathBuf::from(target_dir) .join("debug") .join("examples") .join(name) } #[test] fn test_example_one() { let mut cmd = Command::new(cargo_example("example_one")); cmd.assert().success(); }
修复方法3:确保测试与示例构建的依赖关联
在Cargo.toml中明确示例配置,确保测试运行前自动重新构建示例:
[dev-dependencies] assert_cmd = "2.0" [[example]] name = "example_one" path = "examples/example_one/main.rs"
运行测试时可使用cargo test --examples,或直接cargo test,Cargo会处理依赖关系,确保示例先构建完成。
额外清理步骤
如果缓存导致旧二进制残留,可手动清理示例构建目录:
rm -rf target/debug/examples/
或直接清理整个target目录:
cargo clean
内容的提问来源于stack exchange,提问作者Maurice Lam
相关产品推荐
相关产品推荐

