如何初始化集成测试的记录器?

Dmi*_*rov 16 rust

我有一个包含src目录中的生产代码和目录中的集成测试的箱子tests.生产代码使用log宏.

我想在运行集成测试时初始化一个全局记录器(例如env_logger::init().unwrap();)有几个测试并且测试顺序没有定义,所以我不知道我应该在哪个测试中放置initialize命令.

有什么方法可以做得很好吗?也许通过覆盖测试main功能?

Pat*_*her 13

最新文档有关于在测试中捕获日志的建议:: env_logger

默认情况下,测试工具不会捕获货物测试期间记录的记录。Builder::is_test 方法可用于单元测试以确保捕获日志:

#[cfg(test)]
mod tests {
    fn init() {
        let _ = env_logger::builder().is_test(true).try_init();
    }
 
    #[test]
    fn it_works() {
        init();
        info!("This record will be captured by `cargo test`");
 
        assert_eq!(3, 1 + 2);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不知道文档试图显示什么,但是 `init` 函数永远不会被任何东西调用,并且当测试通过或失败时,不会打印 `info!` 行(通过 `RUST_LOG=info Cargo test` )。 (3认同)

Dan*_*gen 12

你可以使用这样的东西:

use std::sync::Once;

static INIT: Once = Once::new();

/// Setup function that is only run once, even if called multiple times.
fn setup() {
    INIT.call_once(|| {
        env_logger::init().unwrap();
    });
}
Run Code Online (Sandbox Code Playgroud)

然后只需setup()在每次测试开始时调用.

最初基于这篇博文.


Ste*_*nik 6

现在没有好办法做这种内置的东西.

您可以编写一个宏,在每次测试之前插入某种初始化调用,但这样就足够了.


Ste*_*ven 6

目前,您可以在每个测试的顶部重新初始化记录器并忽略错误。这不是一个很好的解决方案,但它有效并且非常安全。

let _ = env_logger::try_init();

// your test code...
Run Code Online (Sandbox Code Playgroud)

  • 这不再有效,多次调用 init 时会出现恐慌:“在记录器初始化后不应调用 'env_logger::init 时出现恐慌:SetLoggerError(())” (2认同)
  • 也许“try_init”? (2认同)

小智 6

除了 Danilo Bargen 的评论之外,您还可以写成更简短的形式:

use std::sync::Once;

static INIT: Once = Once::new();

fn setup() {
  INIT.call_once(env_logger::init);
}
Run Code Online (Sandbox Code Playgroud)