Rust测试环境日志库test-env-log的使用,提供高效测试日志捕获与调试工具
Rust测试环境日志库test-env-log的使用,提供高效测试日志捕获与调试工具
test-env-log是一个用于自动初始化Rust测试中日志和追踪功能的库。它解决了测试环境中日志初始化的问题,使开发者能够方便地查看测试代码输出的日志消息。
使用示例
基本用法
use test_env_log::test;
#[test]
fn it_works() {
info!("Checking whether it still works...");
assert_eq!(2 + 2, 4);
info!("Looks good!");
}
选择性初始化日志
#[test_env_log::test]
fn it_still_works() {
// 只有这个测试会初始化日志
}
异步测试支持
use test_env_log::test;
#[test(tokio::test)]
async fn it_still_works() {
// 支持tokio异步测试
}
日志配置
默认情况下cargo test
会捕获输出,只在测试失败时显示。可以通过以下方式改变这一行为:
$ cargo test -- --nocapture
使用环境变量控制日志级别:
RUST_LOG=info cargo test -- --nocapture
特性配置
该库提供两个特性:
log
(默认启用):用于log
crate的初始化trace
(默认禁用):用于tracing
crate的初始化
完整示例代码
首先在Cargo.toml中添加依赖:
[dev-dependencies]
test-env-log = "0.2.8"
env_logger = "*" # 如果使用log特性
tracing = {version = "0.1", default-features = false} # 如果使用trace特性
tracing-subscriber = {version = "0.3", default-features = false, features = ["env-filter", "fmt"]}
然后编写测试代码:
use test_env_log::test;
use log::{info, error};
// 基本测试示例
#[test]
fn addition_test() {
info!("Starting addition test");
assert_eq!(1 + 1, 2);
info!("Addition test passed");
}
// 失败测试示例
#[test]
fn failing_test() {
error!("This test will fail");
assert_eq!(1 + 1, 3); // 故意制造失败
}
// 异步测试示例
#[test(tokio::test)]
async fn async_addition_test() {
info!("Starting async addition test");
let result = async { 2 + 2 }.await;
assert_eq!(result, 4);
info!("Async addition test passed");
}
// 选择性日志测试
#[test_env_log::test]
fn selected_logging_test() {
info!("This test has logging initialized separately");
assert!(true);
}
// 带日志级别的测试
#[test]
fn log_level_test() {
debug!("This debug message may not appear");
info!("This info message should appear");
warn!("This warning message should appear");
assert_eq!(3 * 3, 9);
}
运行测试时,可以使用不同日志级别查看输出:
# 显示info及以上级别日志
RUST_LOG=info cargo test -- --nocapture
# 显示debug及以上级别日志
RUST_LOG=debug cargo test -- --nocapture
# 显示特定模块的日志
RUST_LOG=my_module=info cargo test -- --nocapture
这个完整示例展示了test-env-log的各种用法,包括基本测试、异步测试、选择性日志初始化以及不同日志级别的控制。
1 回复
Rust测试环境日志库test-env-log使用指南
简介
test-env-log
是一个专为Rust测试环境设计的日志捕获库,它扩展了标准库的test
功能,提供了强大的日志捕获和调试能力。这个库特别适合在单元测试和集成测试中捕获和验证日志输出。
主要特性
- 自动初始化日志系统
- 捕获测试期间产生的所有日志
- 支持断言日志内容
- 与标准测试框架无缝集成
- 支持多种日志级别
使用方法
基本安装
在Cargo.toml中添加依赖:
[dev-dependencies]
test-env-log = "0.2"
基本使用示例
#[cfg(test)]
mod tests {
use test_env_log::test;
use log::{info, warn};
#[test]
fn test_basic_logging() {
info!("This is an info message");
warn!("This is a warning message");
// 测试会正常执行,日志会被捕获
}
}
验证日志输出
#[cfg(test)]
mod tests {
use test_env_log::test;
use log::info;
#[test]
fn test_log_content() {
info!("User logged in: {}", "john_doe");
let logs = test_env_log::capture_logs();
assert!(logs.iter().any(|log| log.contains("User logged in: john_doe")));
}
}
过滤特定日志级别
#[cfg(test)]
mod tests {
use test_env_log::test;
use log::{debug, info, error};
#[test]
fn test_error_logs() {
debug!("Debug message - not important");
info!("Info message - somewhat important");
error!("Error message - critical!");
let error_logs = test_env_log::capture_logs()
.into_iter()
.filter(|log| log.starts_with("[ERROR]"))
.collect::<Vec<_>>();
assert_eq!(error_logs.len(), 1);
assert!(error_logs[0].contains("Error message - critical!"));
}
}
初始化自定义日志配置
#[cfg(test)]
mod tests {
use test_env_log::{test, Config};
use log::LevelFilter;
#[test]
fn test_with_custom_config() {
let _ = test_env_log::init_with_config(
Config::default()
.with_default_level(LevelFilter::Debug)
.with_capture(true)
);
// 测试代码...
}
}
高级用法
测试失败时显示日志
#[cfg(test)]
mod tests {
use test_env_log::test;
use log::error;
#[test]
fn test_failure_with_logs() {
error!("Something went wrong!");
assert!(false, "Test failed intentionally to show logs");
}
}
当测试失败时,所有捕获的日志会自动输出,帮助调试问题。
测试并行执行时的日志隔离
#[cfg(test)]
mod tests {
use test_env_log::test;
use log::info;
#[test]
fn test_parallel_1() {
info!("Test 1 log");
// ...
}
#[test]
fn test_parallel_2() {
info!("Test 2 log");
// ...
}
}
test-env-log
会自动隔离并行测试的日志输出,确保不会交叉混淆。
注意事项
- 确保不要在非测试代码中使用
test-env-log
- 对于性能敏感的测试,可以考虑禁用日志捕获
- 使用
test_env_log::init_with_config(Config::default().with_capture(false))
可以初始化日志但不捕获
替代方案
如果你只需要简单的日志初始化而不需要捕获功能,可以考虑使用env_logger
或其他日志库。但test-env-log
提供了更完整的测试专用功能。
完整示例
下面是一个完整的测试示例,展示了test-env-log
的主要功能:
// 测试模块
#[cfg(test)]
mod tests {
use test_env_log::{test, Config};
use log::{debug, info, warn, error, LevelFilter};
// 基本日志测试
#[test]
fn test_log_levels() {
debug!("This debug message will be captured");
info!("This info message will be captured");
warn!("This warning message will be captured");
error!("This error message will be captured");
// 验证所有级别的日志都被捕获
let logs = test_env_log::capture_logs();
assert_eq!(logs.len(), 4);
}
// 自定义配置测试
#[test]
fn test_custom_config() {
let _ = test_env_log::init_with_config(
Config::default()
.with_default_level(LevelFilter::Info) // 只捕获info及以上级别的日志
.with_capture(true)
);
debug!("This debug message will NOT be captured");
info!("This info message will be captured");
let logs = test_env_log::capture_logs();
assert_eq!(logs.len(), 1);
assert!(logs[0].contains("info message"));
}
// 日志内容断言测试
#[test]
fn test_log_assertions() {
info!("Transaction started: ID=12345");
info!("Processing item: 42");
info!("Transaction completed: ID=12345");
let logs = test_env_log::capture_logs();
// 验证特定日志是否存在
assert!(logs.iter().any(|log| log.contains("Transaction started")));
assert!(logs.iter().any(|log| log.contains("Processing item")));
assert!(logs.iter().any(|log| log.contains("Transaction completed")));
// 验证日志顺序
assert!(logs[0].contains("started"));
assert!(logs[2].contains("completed"));
}
// 错误日志专项测试
#[test]
fn test_error_logging() {
info!("System starting up");
error!("Critical failure in module X");
warn!("Performance degradation detected");
error!("Secondary failure in module Y");
let error_logs = test_env_log::capture_logs()
.into_iter()
.filter(|log| log.starts_with("[ERROR]"))
.collect::<Vec<_>>();
assert_eq!(error_logs.len(), 2);
assert!(error_logs[0].contains("Critical failure"));
assert!(error_logs[1].contains("Secondary failure"));
}
// 测试失败时的日志输出
#[test]
fn test_failure_log_display() {
info!("Preparing test data");
warn!("Potential issue detected");
error!("Test is about to fail");
// 故意让测试失败以查看日志
assert!(false, "This test is expected to fail to demonstrate log output");
}
}
这个库特别适合需要验证日志输出或调试复杂测试场景的情况,能显著提高测试开发和调试的效率。