You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中#[cfg(test)]与#[cfg(feature = "test")]的区别是什么?

Rust中#[cfg(test)]与#[cfg(feature = "test")]的差异

两者本质属于完全不同的条件编译体系,触发逻辑、适用场景没有任何关联,唯一的相似点只是名字里都带test而已。


核心机制差异

  • #[cfg(test)]是Rust编译器内置的条件编译标记
    不需要在项目配置里做任何声明,只要执行cargo test命令编译测试目标时,rustc会自动传入--cfg test参数开启该标记。这个标记仅对当前正在测试的包生效,不会传递给依赖项,正常执行cargo build/cargo run时默认关闭,除非手动通过RUSTFLAGS强行传入该配置(常规开发不会这么做)。

  • #[cfg(feature = "test")]是Cargo提供的自定义功能开关
    它属于Cargo feature机制的一部分,必须先在项目的Cargo.toml的[features]区块明确定义名为test的feature,该标记才有可能生效。它的开启/关闭完全由手动控制:要么执行命令时加--features test参数指定,要么被其他feature/依赖项引入开启,和是否在跑测试没有任何默认绑定关系——哪怕跑cargo test,只要没手动开这个feature,对应代码就不会被编译。

注意:非常不推荐把自定义feature命名为test,和内置cfg重名是极高概率出混淆bug的做法,测试类的辅助功能一般命名为test-utils/mock-support这类辨识度高的名字。


实际效果演示

用一个最小示例验证两者的区别:

  1. 首先在Cargo.toml中声明test feature(不声明的话#[cfg(feature = "test")]永远不生效):
[package]
name = "cfg-demo"
version = "0.1.0"
edition = "2021"

[features]
test = [] # 显式定义自定义test feature
  1. 在src/main.rs中写入测试代码:
// 仅在内置test cfg开启时编译
#[cfg(test)]
fn test_cfg_only() {
    println!("内置test cfg已触发,函数编译生效");
}

// 仅在自定义test feature开启时编译
#[cfg(feature = "test")]
fn feature_test_only() {
    println!("自定义test feature已触发,函数编译生效");
}

#[test]
fn check_cfg() {
    #[cfg(test)]
    println!("测试流程:内置test cfg 已开启");
    #[cfg(feature = "test")]
    println!("测试流程:自定义test feature 已开启");
}

fn main() {
    println!("main函数正常运行");
}
  1. 不同命令的执行结果对比:
  • 执行cargo run(普通运行):两个标记都不开启,只会输出main函数正常运行,两个条件编译的函数都不会被编入二进制。
  • 执行cargo test(普通测试,不带feature参数):仅内置testcfg自动开启,测试输出会打印测试流程:内置test cfg 已开启,自定义feature对应的代码完全不参与编译。
  • 执行cargo run --features test(普通运行+开test feature):内置test cfg不开启,仅自定义feature生效,这时候如果在main里调用feature_test_only()可以正常编译运行,调用test_cfg_only()则会报函数不存在的编译错误。
  • 执行cargo test --features test(测试+开test feature):两个标记同时生效,测试里两条日志都会打印,两个条件编译函数都存在。

适用场景区别

  • #[cfg(test)]:用于写单元测试专属代码,比如测试辅助函数、mock逻辑、只在测试时引入的依赖,这部分代码完全不会进入正式release构建,不会增加产物体积,是Rust单测的标准写法。
  • #[cfg(feature = "xxx")](不管是不是命名为test):用于可选功能的按需编译,比如给库的使用者暴露测试辅助工具、可选的扩展功能、兼容不同环境的逻辑,和测试流程本身没有绑定关系,需要用户手动选择是否开启。

内容的提问来源于stack exchange,提问作者savx2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:15:49