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

时间:2015-05-11 21:19:54

标签: rust

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

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

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

6 个答案:

答案 0 :(得分: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 :(得分:5)

目前没有好办法做这种内置的事情。

您可以编写一个宏,在每次测试之前插入某种初始化调用,但是它与它一样接近。

答案 2 :(得分:1)

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

let _ = env_logger::init();

// your test code...

答案 3 :(得分:0)

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

use std::sync::Once;

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

fn setup() {
  INIT.call_once(env_logger::init);
}

答案 4 :(得分:-1)

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

  1. 我制作了一个名为aaa_testing的模块,位于箱子的根部。
  2. 在模块内部,我编写了记录器初始化程序。

    #[test]
    fn initialize_logger() {
        env_logger::init();
    }
    
  3. 是的,我确实创建了一个始终通过的测试,但是如果您想要初始化记录器的测试,可以执行assert!(env_logger::try_init().is_ok());

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

      

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

    cargo test -- --test-threads=1
    

答案 5 :(得分:-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);
    }
}