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

Rust执行测试时如何打印tracing crate生成的日志输出?

Rust 测试场景下打印 tracing 日志的配置方法

Rust 内置测试框架默认会捕获测试线程的所有标准输出/标准错误,只有测试失败时才会把捕获的内容打印出来;加上 tracing 本身不会自动输出日志,必须提前注册日志收集器,所以默认跑测试看不到 tracing 打出来的日志,按下面步骤配置即可:

1. 引入测试场景需要的依赖

把日志输出相关的包加到开发依赖里,不会影响正式构建的体积:

[dev-dependencies]
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }

2. 写可复用的一次性初始化函数

tracing 的全局日志收集器只能设置一次,多测试并行跑的时候重复初始化会报错,所以写个通用初始化函数,用try_init避免重复初始化触发panic,同时用官方提供的测试专用输出适配器对接测试框架的捕获逻辑:

// 可以放在tests目录下的公共模块,或者每个测试文件的顶部
fn init_test_tracing() {
    let _ = tracing_subscriber::fmt()
        // 对接测试输出捕获机制,测试失败时自动带出捕获的日志
        .with_test_writer()
        // 支持通过RUST_LOG环境变量控制日志级别,也可以直接写死规则
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        // 用try_init而非init,重复初始化时不会panic
        .try_init();
}

.with_test_writer()是tracing-subscriber专门给测试场景做的适配,不用自己手动处理标准输出句柄,比直接往stdout写日志兼容性好很多。

3. 在测试用例开头调用初始化

每个测试用例执行前先调一遍初始化即可,重复调用也不会出问题:

#[test]
fn test_biz_logic() {
    init_test_tracing();

    // 正常写测试逻辑,用tracing的宏打日志即可
    tracing::info!("测试启动,当前入参:{:?}", test_params);
    tracing::debug!("中间计算结果:{}", mid_val);
    // ... 其余测试逻辑
}

4. 运行测试查看日志

分两种常用场景:

  • 需要实时看到所有日志(不管测试成功失败):跑测试时给测试二进制传--nocapture参数,关闭输出捕获:
    # 跑所有测试并实时打印日志
    cargo test -- --nocapture
    # 只跑指定测试并打印日志
    cargo test test_biz_logic -- --nocapture
    
  • 不需要实时看日志:不用加任何额外参数,默认配置下如果测试执行失败,框架会自动把这个测试运行期间捕获的所有tracing日志和失败报错、栈追踪一起打印出来,测试通过的话日志不会显示,不会干扰干净的测试结果输出。

如果需要调整日志级别,跑测试前加RUST_LOG环境变量即可,比如要打印debug及以上级别的日志:

RUST_LOG=debug cargo test -- --nocapture

要是不想每次跑都设环境变量,也可以在初始化的时候直接写死过滤规则,把from_default_env()替换成tracing_subscriber::EnvFilter::new("info")就会默认打印info及以上级别的日志。

常见踩坑提醒:别用init()替换try_init(),多线程并行跑测试的时候,多个测试同时触发初始化,init()会因为全局收集器已存在直接panic,导致测试无意义失败。

内容的提问来源于stack exchange,提问作者Thorkil Værge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:06:21