Proper way to use simplelog in #[test] code

I have code that uses logger extensively. I'd like my #[test] sections to send their logger output to standard output, where it would be hidden unless the test fails.
There are some problems. First, if a test does an init of a CombinedLogger, that clashes with other tests in the same test run. There's only one test executable. We can get around that by ignoring the output from init(). Second, if I do this:

let _ = simplelog::CombinedLogger::init(
        vec![
            simplelog::TermLogger::new(LevelFilter::Debug, simplelog::Config::default(), simplelog::TerminalMode::Stdout, simplelog::ColorChoice::Auto),]
    );

it really logs to the terminal, not standard output, so all the logger output shows up rather than being captured for successful tests.

There's probably some simple way to do this.

Write a logger that sends the output where you want it.

struct LoggerForTests;

impl log::Log for LoggerForTests {
    fn enabled(&self, _: &log::Metadata<'_>) -> bool {
        true
    }
   fn log(&self, record: &log::Record<'_>) {
        eprintln!(
            "[{level}] {msg}",
            level = record.level(),
            msg = record.args()
        );
    }
    fn flush(&self) {}
}
1 Like