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

问题描述 投票:11回答:5

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

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

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

rust
5个回答
5
投票

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

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


6
投票

你可以使用这样的东西:

use std::sync::{Once, ONCE_INIT};

static INIT: Once = ONCE_INIT;

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

然后在每次测试开始时简单地调用setup()

最初基于this blogpost


1
投票

现在,您可以在每个测试的顶部重新初始化记录器并忽略错误。这不是一个漂亮的解决方案,但它的工作原理非常安全。

let _ = env_logger::init();

// your test code...

-1
投票

我已经观察到cargo test按字母顺序运行测试,因此我设计了一个非常脏的黑客来初始化记录器。

  1. 我制作了一个名为aaa_testing的模块,它位于箱子的根部。
  2. 在模块内部,我编写了logger初始化程序。 #[test] fn initialize_logger() { env_logger::init(); }

是的我确实创建了一个始终通过的测试,但是如果你想测试初始化​​记录器,你可以做一个assert!(env_logger::try_init().is_ok());


Shepmaster指出,cargo test异步运行测试,可能使前几个测试的记录不可靠。为了防止这种情况,可以在同一个线程中运行测试。 (这会导致性能问题,因此如果您需要多个线程来测试项目,则不应使用此答案。)

如果要控制同时运行的测试用例的数量,请将--test-threads选项传递给测试二进制文件:

cargo test -- --test-threads=1

-1
投票

latest documentation has a recommendation

#[cfg(test)]
mod tests {
    fn init() {
        let _ = env_logger::builder().is_test(true).try_init();
    }

    #[test]
    fn it_works() {
        info!("This record will be captured by `cargo test`");

        assert_eq!(2, 1 + 1);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.