How do I suppress output from multiple threads when running cargo test?












2















If I execute the below testcases with cargo test, the output of one_thread_test will be suppressed as stated in the documentation.



However the output from multi_thread_test will appear on stdout. Is it possible to match the behavior of single- and multi-threaded testcases?



#[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();
}
}









share|improve this question




















  • 1





    @PeterHall The problem is that cargo does not hide stdout as in your link above in multi thread test case.

    – user1244932
    Nov 26 '18 at 12:21













  • Oh I see. You can workaround it by implementing your own print, which writes to a shared buffer, and only print from the buffer in the main thread. Could be overly complex though..

    – Peter Hall
    Nov 26 '18 at 12:23
















2















If I execute the below testcases with cargo test, the output of one_thread_test will be suppressed as stated in the documentation.



However the output from multi_thread_test will appear on stdout. Is it possible to match the behavior of single- and multi-threaded testcases?



#[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();
}
}









share|improve this question




















  • 1





    @PeterHall The problem is that cargo does not hide stdout as in your link above in multi thread test case.

    – user1244932
    Nov 26 '18 at 12:21













  • Oh I see. You can workaround it by implementing your own print, which writes to a shared buffer, and only print from the buffer in the main thread. Could be overly complex though..

    – Peter Hall
    Nov 26 '18 at 12:23














2












2








2








If I execute the below testcases with cargo test, the output of one_thread_test will be suppressed as stated in the documentation.



However the output from multi_thread_test will appear on stdout. Is it possible to match the behavior of single- and multi-threaded testcases?



#[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();
}
}









share|improve this question
















If I execute the below testcases with cargo test, the output of one_thread_test will be suppressed as stated in the documentation.



However the output from multi_thread_test will appear on stdout. Is it possible to match the behavior of single- and multi-threaded testcases?



#[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();
}
}






unit-testing debugging rust rust-cargo






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 8 at 13:56









Peter Hall

18k74597




18k74597










asked Nov 26 '18 at 12:17









user1244932user1244932

1,62511334




1,62511334








  • 1





    @PeterHall The problem is that cargo does not hide stdout as in your link above in multi thread test case.

    – user1244932
    Nov 26 '18 at 12:21













  • Oh I see. You can workaround it by implementing your own print, which writes to a shared buffer, and only print from the buffer in the main thread. Could be overly complex though..

    – Peter Hall
    Nov 26 '18 at 12:23














  • 1





    @PeterHall The problem is that cargo does not hide stdout as in your link above in multi thread test case.

    – user1244932
    Nov 26 '18 at 12:21













  • Oh I see. You can workaround it by implementing your own print, which writes to a shared buffer, and only print from the buffer in the main thread. Could be overly complex though..

    – Peter Hall
    Nov 26 '18 at 12:23








1




1





@PeterHall The problem is that cargo does not hide stdout as in your link above in multi thread test case.

– user1244932
Nov 26 '18 at 12:21







@PeterHall The problem is that cargo does not hide stdout as in your link above in multi thread test case.

– user1244932
Nov 26 '18 at 12:21















Oh I see. You can workaround it by implementing your own print, which writes to a shared buffer, and only print from the buffer in the main thread. Could be overly complex though..

– Peter Hall
Nov 26 '18 at 12:23





Oh I see. You can workaround it by implementing your own print, which writes to a shared buffer, and only print from the buffer in the main thread. Could be overly complex though..

– Peter Hall
Nov 26 '18 at 12:23












1 Answer
1






active

oldest

votes


















1














Here is a quick-and-dirty workaround.



It works by sending messages to a receiver owned by a struct in the main thread. The receiver prints all of the accumulated messages when it is dropped - this is important so that panics caused by failed assertions don't prevent the printing.



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);
}
}
}


And a convenience macro so it feels mostly like calling println!:



macro_rules! myprint {
($send: expr, $($arg:tt)*) => {
(*&$send).send(format!($($arg)*));
};
}


In order to send messages for printing, you have get a sender for each thread:



#[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();
}
}


The actual printing happens when printer goes out of scope. It's in the main thread so it won't print during successful tests unless --nocapture is specified.






share|improve this answer


























  • But is this bug in cargo and I should reports the issue, or this intented behaviour and should use your hack always when for some reason I need multiply threads in my test?

    – user1244932
    Nov 26 '18 at 13:30











  • I'm not sure if it's technically a bug. But it might be seen that way, and there is no harm in reporting it.

    – Peter Hall
    Nov 26 '18 at 13:35











  • Thank your for answer and reply, I submit issue here: github.com/rust-lang/cargo/issues/6350 and will wait one day before accept answer, may be somebody suggest something else.

    – user1244932
    Nov 26 '18 at 14:59












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53480972%2fhow-do-i-suppress-output-from-multiple-threads-when-running-cargo-test%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Here is a quick-and-dirty workaround.



It works by sending messages to a receiver owned by a struct in the main thread. The receiver prints all of the accumulated messages when it is dropped - this is important so that panics caused by failed assertions don't prevent the printing.



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);
}
}
}


And a convenience macro so it feels mostly like calling println!:



macro_rules! myprint {
($send: expr, $($arg:tt)*) => {
(*&$send).send(format!($($arg)*));
};
}


In order to send messages for printing, you have get a sender for each thread:



#[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();
}
}


The actual printing happens when printer goes out of scope. It's in the main thread so it won't print during successful tests unless --nocapture is specified.






share|improve this answer


























  • But is this bug in cargo and I should reports the issue, or this intented behaviour and should use your hack always when for some reason I need multiply threads in my test?

    – user1244932
    Nov 26 '18 at 13:30











  • I'm not sure if it's technically a bug. But it might be seen that way, and there is no harm in reporting it.

    – Peter Hall
    Nov 26 '18 at 13:35











  • Thank your for answer and reply, I submit issue here: github.com/rust-lang/cargo/issues/6350 and will wait one day before accept answer, may be somebody suggest something else.

    – user1244932
    Nov 26 '18 at 14:59
















1














Here is a quick-and-dirty workaround.



It works by sending messages to a receiver owned by a struct in the main thread. The receiver prints all of the accumulated messages when it is dropped - this is important so that panics caused by failed assertions don't prevent the printing.



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);
}
}
}


And a convenience macro so it feels mostly like calling println!:



macro_rules! myprint {
($send: expr, $($arg:tt)*) => {
(*&$send).send(format!($($arg)*));
};
}


In order to send messages for printing, you have get a sender for each thread:



#[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();
}
}


The actual printing happens when printer goes out of scope. It's in the main thread so it won't print during successful tests unless --nocapture is specified.






share|improve this answer


























  • But is this bug in cargo and I should reports the issue, or this intented behaviour and should use your hack always when for some reason I need multiply threads in my test?

    – user1244932
    Nov 26 '18 at 13:30











  • I'm not sure if it's technically a bug. But it might be seen that way, and there is no harm in reporting it.

    – Peter Hall
    Nov 26 '18 at 13:35











  • Thank your for answer and reply, I submit issue here: github.com/rust-lang/cargo/issues/6350 and will wait one day before accept answer, may be somebody suggest something else.

    – user1244932
    Nov 26 '18 at 14:59














1












1








1







Here is a quick-and-dirty workaround.



It works by sending messages to a receiver owned by a struct in the main thread. The receiver prints all of the accumulated messages when it is dropped - this is important so that panics caused by failed assertions don't prevent the printing.



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);
}
}
}


And a convenience macro so it feels mostly like calling println!:



macro_rules! myprint {
($send: expr, $($arg:tt)*) => {
(*&$send).send(format!($($arg)*));
};
}


In order to send messages for printing, you have get a sender for each thread:



#[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();
}
}


The actual printing happens when printer goes out of scope. It's in the main thread so it won't print during successful tests unless --nocapture is specified.






share|improve this answer















Here is a quick-and-dirty workaround.



It works by sending messages to a receiver owned by a struct in the main thread. The receiver prints all of the accumulated messages when it is dropped - this is important so that panics caused by failed assertions don't prevent the printing.



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);
}
}
}


And a convenience macro so it feels mostly like calling println!:



macro_rules! myprint {
($send: expr, $($arg:tt)*) => {
(*&$send).send(format!($($arg)*));
};
}


In order to send messages for printing, you have get a sender for each thread:



#[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();
}
}


The actual printing happens when printer goes out of scope. It's in the main thread so it won't print during successful tests unless --nocapture is specified.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 26 '18 at 13:09

























answered Nov 26 '18 at 13:02









Peter HallPeter Hall

18k74597




18k74597













  • But is this bug in cargo and I should reports the issue, or this intented behaviour and should use your hack always when for some reason I need multiply threads in my test?

    – user1244932
    Nov 26 '18 at 13:30











  • I'm not sure if it's technically a bug. But it might be seen that way, and there is no harm in reporting it.

    – Peter Hall
    Nov 26 '18 at 13:35











  • Thank your for answer and reply, I submit issue here: github.com/rust-lang/cargo/issues/6350 and will wait one day before accept answer, may be somebody suggest something else.

    – user1244932
    Nov 26 '18 at 14:59



















  • But is this bug in cargo and I should reports the issue, or this intented behaviour and should use your hack always when for some reason I need multiply threads in my test?

    – user1244932
    Nov 26 '18 at 13:30











  • I'm not sure if it's technically a bug. But it might be seen that way, and there is no harm in reporting it.

    – Peter Hall
    Nov 26 '18 at 13:35











  • Thank your for answer and reply, I submit issue here: github.com/rust-lang/cargo/issues/6350 and will wait one day before accept answer, may be somebody suggest something else.

    – user1244932
    Nov 26 '18 at 14:59

















But is this bug in cargo and I should reports the issue, or this intented behaviour and should use your hack always when for some reason I need multiply threads in my test?

– user1244932
Nov 26 '18 at 13:30





But is this bug in cargo and I should reports the issue, or this intented behaviour and should use your hack always when for some reason I need multiply threads in my test?

– user1244932
Nov 26 '18 at 13:30













I'm not sure if it's technically a bug. But it might be seen that way, and there is no harm in reporting it.

– Peter Hall
Nov 26 '18 at 13:35





I'm not sure if it's technically a bug. But it might be seen that way, and there is no harm in reporting it.

– Peter Hall
Nov 26 '18 at 13:35













Thank your for answer and reply, I submit issue here: github.com/rust-lang/cargo/issues/6350 and will wait one day before accept answer, may be somebody suggest something else.

– user1244932
Nov 26 '18 at 14:59





Thank your for answer and reply, I submit issue here: github.com/rust-lang/cargo/issues/6350 and will wait one day before accept answer, may be somebody suggest something else.

– user1244932
Nov 26 '18 at 14:59




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53480972%2fhow-do-i-suppress-output-from-multiple-threads-when-running-cargo-test%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Ottavio Pratesi

Tricia Helfer

15 giugno