Friday, 16 June 2017

Why doesn't println! work in Rust unit tests?



I've implemented the following method and unit test:



use std::fs::File;
use std::path::Path;
use std::io::prelude::*;


fn read_file(path: &Path) {
let mut file = File::open(path).unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
println!("{}", contents);
}

#[test]
fn test_read_file() {

let path = &Path::new("/etc/hosts");
println!("{:?}", path);
read_file(path);
}


I run the unit test this way:



rustc --test app.rs; ./app



I could also run this with



cargo test


I get a message back saying the test passed but the println! is never displayed on screen. Why not?


Answer



This happens because Rust test programs hide the stdout of successful tests in order for the test output to be tidy. You can disable this behavior by passing the --nocapture option to the test binary or to cargo test:




#[test]
fn test() {
println!("Hidden output")
}


Invoking tests:



% rustc --test main.rs; ./main


running 1 test
test test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

% ./main --nocapture

running 1 test
Hidden output
test test ... ok


test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

% cargo test -- --nocapture

running 1 test
Hidden output
test test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured



If tests fail, however, their stdout will be printed regardless if this option is present or not.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...