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

后端 未结 5 819
天涯浪人
天涯浪人 2020-11-30 17:09

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) {
    l         


        
相关标签:
5条回答
  • 2020-11-30 17:55

    For current and future viewers of this question, --show-output is the way to go as mentioned by @l-f in a comment to another answer. But it seems to be missing from the documentation.

    So the full command is cargo test -- --show-output

    0 讨论(0)
  • 2020-11-30 17:56

    To include print outs with println!() and keep colors for the test results, use the color and nocapture flags in cargo test.

    $ cargo test -- --color always --nocapture
    

    (cargo version: 0.13.0 nightly)

    0 讨论(0)
  • 2020-11-30 18:04

    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.

    0 讨论(0)
  • 2020-11-30 18:06

    TL;DR

    $ cargo test -- --nocapture
    

    With the following code:

    #[derive(Copy, Clone, Debug, PartialEq, Eq)]
    pub enum PieceShape {
        King, Queen, Rook, Bishop, Knight, Pawn
    }
    
    fn main() {
        println!("Hello, world!");
    }
    
    #[test]
    fn demo_debug_format() {
        let q = PieceShape::Queen;
        let p = PieceShape::Pawn;
        let k = PieceShape::King;
        println!("q={:?} p={:?} k={:?}", q, p, k);
    }
    

    Then run the following:

     $ cargo test -- --nocapture
    

    And you should see

    Running target/debug/chess-5d475d8baa0176e4
    
    running 1 test
    q=Queen p=Pawn k=King
    test demo_debug_format ... ok
    
    test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
    
    0 讨论(0)
  • 2020-11-30 18:10

    While testing, standard output is not displayed. Don't use text messages for testing but assert!, assert_eq!, and fail! instead. Rust's unit test system can understand these but not text messages.

    The test you have written will pass even if something goes wrong. Let's see why:

    read_to_end's signature is fn read_to_end(&mut self) -> IoResult<Vec<u8>>

    It returns an IoResult to indicate success or error. This is just a type def for a Result whose error value is an IoError. It's up to you to decide how an error should be handled. In this case, we want the task to fail, which is done by calling unwrap on the Result.

    This will work:

    let contents = File::open(&Path::new("message.txt"))
        .read_to_end()
        .unwrap();
    

    unwrap should not be overused though.

    0 讨论(0)
提交回复
热议问题