如何在Cargo测试与示例间复用仅开发用代码?
Rust 测试工具代码复用方案(不增加主库体积)
核心实现思路
通过条件编译让test_utils仅在测试、文档编译阶段被引入,默认编译主库时完全排除该模块,同时保证测试和示例能直接复用代码,无需复杂命令。
1. 配置条件编译的模块引入
在lib.rs中添加如下代码,仅在测试或文档编译时启用test_utils:
// 仅在测试/文档模式下编译test_utils模块 #[cfg(any(test, doc))] mod test_utils; // 仅在测试/文档模式下将工具函数导入当前crate内部 #[cfg(any(test, doc))] pub(crate) use test_utils::*;
用pub(crate)确保工具仅在 crate 内部可见,不会对外暴露test_utils相关内容。
2. 编写测试工具代码
创建src/test_utils.rs文件,存放你的复用代码:
// 测试环境初始化工具 pub fn setup_test_env() { // 这里写测试环境的初始化逻辑 } // 测试数据生成工具 pub fn generate_sample_data() -> Vec<String> { // 生成测试用的样本数据 vec!["test1".into(), "test2".into()] }
3. 在测试和示例中直接使用
在测试模块或文档注释的示例里,直接调用工具函数即可:
#[cfg(test)] mod tests { use super::*; #[test] fn test_business_logic() { // 使用测试工具初始化环境 setup_test_env(); let data = generate_sample_data(); // 编写具体测试逻辑 assert!(!data.is_empty()); } }
文档示例中也能正常使用:
/// 示例:使用测试工具生成数据 /// ``` /// use your_crate::generate_sample_data; /// let data = generate_sample_data(); /// assert_eq!(data.len(), 2); /// ``` pub fn use_sample_data() { // 业务逻辑 }
4. 确保主库不包含该模块
由于使用了#[cfg(any(test, doc))]条件编译,执行cargo build编译主库时,test_utils模块会被完全跳过,不会增加主库体积,满足硬性要求。
可选优化:精细特性控制(非必需)
如果需要允许高级用户手动启用test_utils但默认不暴露,可添加特性条件:
在lib.rs中修改:
#[cfg(any(test, doc, feature = "internal-test-utils"))] mod test_utils; #[cfg(any(test, doc, feature = "internal-test-utils"))] pub(crate) use test_utils::*;
然后在Cargo.toml中声明特性并设为非默认:
[features] internal-test-utils = []
这样默认情况下test_utils仍不会被编译,也不会对外暴露该特性(除非用户主动指定--features internal-test-utils)。
效果验证
- 执行
cargo build后,检查产物体积,确认test_utils未被包含 - 执行
cargo test无需额外参数,直接可使用测试工具 - 文档示例可正常编译运行
内容的提问来源于stack exchange,提问作者mwlon
相关产品推荐
相关产品推荐

