如何在Tokio上下文环境中获取Rust测试的名称?
在Rust Tokio测试中获取当前测试名称(含子函数)
方法:利用traced_test的tracing span特性
既然你已经使用了#[traced_test]属性,它会自动为每个测试创建一个以**完整测试名称(含模块路径)**为标识的tracing span,异步任务会自动继承这个父span,因此可以直接通过tracing crate获取当前span的名称,无需手动传递参数。
步骤1:确认依赖配置
在Cargo.toml中确保包含以下依赖(版本可按需调整):
[dependencies] tracing = "0.1" traced-test = "0.2" tokio = { version = "1.0", features = ["full"] }
步骤2:修改测试代码
直接在测试函数和子函数中调用tracing::Span::current().name()获取测试名称:
use tracing::Span; #[traced_test] #[tokio::test] async fn foo() { assert!(true); println!("test name is: {}", Span::current().name()); bar().await; } async fn bar() { println!("bar: test name is: {}", Span::current().name()); }
输出示例
运行测试后会得到类似结果:
test name is: foo bar: test name is: foo
如果测试位于某个模块下(比如tests::my_module::foo),输出会自动包含完整路径:
test name is: tests::my_module::foo bar: test name is: tests::my_module::foo
备选方案:手动通过Tokio本地任务存储传递
如果不想依赖tracing,可以用Tokio的LocalKey实现测试名称的上下文传递:
定义本地存储键
use tokio::task::LocalKey; // 全局本地键,用于存储当前测试名称 static CURRENT_TEST_NAME: LocalKey<Option<&'static str>> = LocalKey::new(|| None);
包裹测试函数逻辑
在测试函数中用scope方法设置测试名称,作用域覆盖整个测试流程:
#[tokio::test] async fn foo() { CURRENT_TEST_NAME.scope(Some("foo"), async { println!("test name is: {}", CURRENT_TEST_NAME.get().unwrap()); bar().await; }).await; }
在子函数中获取名称
async fn bar() { match CURRENT_TEST_NAME.get() { Some(name) => println!("bar: test name is: {}", name), None => println!("bar: test name is: unknown"), } }
这个方案需要手动为每个测试添加scope包裹,适合不需要tracing的场景。
内容的提问来源于stack exchange,提问作者Thorkil Værge
相关产品推荐
相关产品推荐

