运行 cargo test 时如何抑制多个线程的输出?
How do I suppress output from multiple threads when running cargo test?
如果我使用 cargo test
执行以下测试用例,one_thread_test
的输出将被抑制,如文档中所述。
但是 multi_thread_test
的输出将出现在标准输出上。是否可以匹配单线程和多线程测试用例的行为?
#[test]
fn one_thread_test() {
println!("A");
println!("B");
}
#[test]
fn multi_thread_test() {
use std::thread;
let mut threads = vec![];
for _ in 0..100 {
let t = thread::spawn(move || {
println!("from thread");
});
threads.push(t);
}
for thread in threads {
thread.join().unwrap();
}
}
这是一个快速而简单的解决方法。
它的工作原理是将消息发送到主线程中结构所拥有的接收器。接收方在删除时打印所有累积的消息 - 这很重要,这样由失败的断言引起的恐慌就不会阻止打印。
use std::sync::mpsc::{channel, Sender, Receiver};
struct TestPrinter {
receiver: Receiver<String>,
sender: Sender<String>,
}
impl TestPrinter {
fn new() -> TestPrinter {
let (sender, receiver) = channel();
TestPrinter { receiver, sender }
}
fn sender(&self) -> Sender<String> {
self.sender.clone()
}
}
impl Drop for TestPrinter {
fn drop(&mut self) {
while let Some(v) = self.receiver.try_recv().ok() {
println!("later: {}", v);
}
}
}
还有一个方便的宏,所以感觉就像调用 println!
:
macro_rules! myprint {
($send: expr, $($arg:tt)*) => {
(*&$send).send(format!($($arg)*));
};
}
为了发送要打印的消息,您已为每个线程获得一个 sender
:
#[test]
fn multi_thread_test() {
use std::thread;
let mut threads = vec![];
let printer = TestPrinter::new();
for _ in 0..100 {
let sender = printer.sender();
let t = thread::spawn(move || {
myprint!(sender, "from thread");
});
threads.push(t);
}
for thread in threads {
thread.join().unwrap();
}
}
实际打印发生在 printer
超出范围时。它在主线程中,因此在成功测试期间不会打印,除非指定 --nocapture
。
如果我使用 cargo test
执行以下测试用例,one_thread_test
的输出将被抑制,如文档中所述。
但是 multi_thread_test
的输出将出现在标准输出上。是否可以匹配单线程和多线程测试用例的行为?
#[test]
fn one_thread_test() {
println!("A");
println!("B");
}
#[test]
fn multi_thread_test() {
use std::thread;
let mut threads = vec![];
for _ in 0..100 {
let t = thread::spawn(move || {
println!("from thread");
});
threads.push(t);
}
for thread in threads {
thread.join().unwrap();
}
}
这是一个快速而简单的解决方法。
它的工作原理是将消息发送到主线程中结构所拥有的接收器。接收方在删除时打印所有累积的消息 - 这很重要,这样由失败的断言引起的恐慌就不会阻止打印。
use std::sync::mpsc::{channel, Sender, Receiver};
struct TestPrinter {
receiver: Receiver<String>,
sender: Sender<String>,
}
impl TestPrinter {
fn new() -> TestPrinter {
let (sender, receiver) = channel();
TestPrinter { receiver, sender }
}
fn sender(&self) -> Sender<String> {
self.sender.clone()
}
}
impl Drop for TestPrinter {
fn drop(&mut self) {
while let Some(v) = self.receiver.try_recv().ok() {
println!("later: {}", v);
}
}
}
还有一个方便的宏,所以感觉就像调用 println!
:
macro_rules! myprint {
($send: expr, $($arg:tt)*) => {
(*&$send).send(format!($($arg)*));
};
}
为了发送要打印的消息,您已为每个线程获得一个 sender
:
#[test]
fn multi_thread_test() {
use std::thread;
let mut threads = vec![];
let printer = TestPrinter::new();
for _ in 0..100 {
let sender = printer.sender();
let t = thread::spawn(move || {
myprint!(sender, "from thread");
});
threads.push(t);
}
for thread in threads {
thread.join().unwrap();
}
}
实际打印发生在 printer
超出范围时。它在主线程中,因此在成功测试期间不会打印,除非指定 --nocapture
。