如何在util crate的#[cfg(test)]下导出类型供其他crate测试使用?
解决Rust工作区中测试专属类型跨crate访问问题
你的问题核心在于:#[cfg(test)]是针对当前编译的crate生效的。当foo或bar编译测试代码时,它们自身的test配置会激活,但作为依赖的util是按普通依赖编译的,util的test配置并未开启,所以ForTest根本没被编译进util的输出库,自然无法被引用。
下面是两种可靠的解决方案:
方案一:测试专属Feature(推荐)
通过给util添加一个默认关闭的测试专属feature,仅在foo/bar的测试构建中启用,既能让测试代码访问ForTest,又能保证非测试代码完全看不到它。
- 修改
util/Cargo.toml,添加测试专属feature:
[features] # 测试专属feature,默认不启用 test-utils = []
- 修改
util中的代码,用feature = "test-utils"替代#[cfg(test)]来控制ForTest的编译和导出:
#[cfg(feature = "test-utils")] mod for_test { pub struct ForTest { // 你的类型定义 } } #[cfg(feature = "test-utils")] pub use for_test::ForTest;
- 修改
foo/Cargo.toml和bar/Cargo.toml,仅在开发依赖(测试构建)中启用util的test-utilsfeature:
# 普通依赖,不启用test-utils [dependencies] util = { path = "../util" } # 测试构建时使用带test-utils的util版本 [dev-dependencies] util = { path = "../util", features = ["test-utils"] }
这样一来,foo/bar的非测试代码编译时,util不会包含ForTest;只有运行测试时,util才会编译并导出ForTest,完全符合你的需求。
方案二:利用cfg(test)的跨crate传递(进阶)
如果你不想额外添加feature,可以通过rustflags传递test cfg给依赖,但这种方式不够优雅,且需要统一工作区的构建配置:
在工作根目录的.cargo/config.toml中添加:
[build] rustflags = ["--cfg", "test"]
但这种方式会让所有依赖都开启test cfg,可能引入不必要的测试代码,不推荐用于生产环境,仅适合临时调试。
内容的提问来源于stack exchange,提问作者Kushagra Gupta
相关产品推荐
相关产品推荐

