2015-05-11 2 views
9

У меня есть ящик с производственным кодом в каталоге src и интеграционных тестах в каталоге tests. В производственном коде используются макросы log.Как инициализировать логгер для тестов интеграции?

Я хотел бы инициализировать глобальный регистратор при выполнении тестов интеграции (например env_logger::init().unwrap();) Есть несколько тестов, и порядок испытаний не определен, так что я не знаю, в каком тест я должен поставить команду инициализации.

Есть ли способ, я могу сделать это красиво? Возможно, путем переопределения тестов main функция?

ответ

5

В настоящее время нет хорошего способа сделать это, встроенное прямо сейчас.

Вы можете написать макрос, который вставляет какой-либо инициализационный вызов перед каждым тестом, но это так близко, как есть.

1

На данный момент вы можете просто повторно инициализировать регистратор в верхней части каждого теста и проигнорировать ошибку. Это не красивое решение, но оно работает и абсолютно безопасно.

let _ = env_logger::init(); 

// your test code... 
4

Вы можете использовать что-то вроде этого:

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.

0

Я наблюдал cargo test, пропустив тесты в алфавитном порядке, поэтому я разработал очень грязный взломать для инициализации регистратора.

  1. Я создал модуль под названием aaa_testing, расположенный внутри корня ящика.
  2. Внутри модуля я написал инициализатор журнала.

    #[test] 
    fn initialize_logger() { 
        env_logger::init(); 
    } 
    

Да я создать тест, который всегда будет проходить, но если вы хотите, чтобы тест для инициализации регистратора, вы можете сделать assert!(env_logger::try_init().is_ok());


Shepmaster отметил, что cargo test выполняет тесты асинхронно и может сделать запись первых тестов ненадежной. Чтобы этого избежать, тесты можно запускать в одном потоке. (Это может вызвать проблемы с производительностью, поэтому этот ответ не должен использоваться, если вам нужно несколько потоков для тестирования проекта.)

Если вы хотите, чтобы контролировать количество одновременных случаев работает тест, передайте опцию --test-threads испытуемым двоичные файлы:

cargo test -- --test-threads=1 
+0

Это очень плохая идея, потому что Карго запускает тесты параллельно по умолчанию. Вероятно, это приведет к тестированию flakiness для первых нескольких тестов, которые запускаются одновременно с этим. – Shepmaster

+0

Да, я не знал этого, они не параллельны мне. Спасибо за подсказку. Хорошо, я узнал из 'cargo test --help', что количество тестовых потоков - это количество процессоров, которые у меня есть. Я уточню ответ, чтобы отметить это. –

+0

[Они запускаются параллельно по умолчанию] (https://doc.rust-lang.org/stable/book/second-edition/ch11-02-running-tests.html#running-tests-in-parallel-or- последовательно), поэтому, если вы не отключили это явно, это все равно повлияет на тесты. – Shepmaster