我实现了以下方法和单元测试:

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

我以这样的方式运行单元测试:

rustc --test app.rs; ./app

我也可以运行这个

cargo test

我得到一条消息,说测试通过了,但是println!永远不会显示在屏幕上。为什么不呢?


测试时,不显示标准输出。不要使用短信进行测试,而是断言!, assert_eq !,失败了!代替。Rust的单元测试系统可以理解这些信息,但不能理解文本消息。

即使出现问题,您编写的测试也会通过。让我们来看看原因:

Read_to_end的签名为 fn read_to_end(&mut self) -> IoResult<Vec<u8>>

它返回一个IoResult来指示成功或错误。这只是一个error值为IoError的Result的类型定义。如何处理错误由您决定。在本例中,我们希望任务失败,这可以通过在Result上调用unwrap来实现。

这是可行的:

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

不过,不应该过度使用Unwrap。


这是因为Rust测试程序隐藏了成功测试的标准输出,以使测试输出整齐。你可以通过将——nocapture选项传递给测试二进制文件或cargo test来禁用这种行为(但是,在这种情况下,在——-见下文):

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

调用测试:

% 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

但是,如果测试失败,则无论是否存在此选项,都将打印它们的标准输出。


博士TL;

$ cargo test -- --nocapture

使用以下代码:

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

然后执行如下命令:

 $ cargo test -- --nocapture

你们应该看到

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

要使用println!()包含打印结果并为测试结果保留颜色,请在货物测试中使用颜色和不捕获标志。

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

(载货版:0.13.0每晚)


正如L. F.提到的,——show-output是正确的方法。

$ cargo test -- --show-output

其他显示标志在显示选项中的货物测试文档中提到。


为什么?我不知道,但有一个小黑客eprintln!("将打印在{}","测试")


请注意,现代解决方案(cargo test -- --show-output)在函数文档字符串中的Markdown代码-fence中定义的doctest中不起作用。只有println !(等等)在一个具体的#[测试]块中完成的语句将被尊重。


测试输出很可能被测试框架捕获,而没有被打印到标准输出中。在运行带有货物测试的测试时,仅在测试失败时才捕获并显示每个测试的输出。如果您希望看到测试的输出,您可以在运行带有cargo测试的测试时使用——nocapture标志。像这样:

cargo test -- --nocapture

或者你可以使用println!宏内部的测试函数将输出打印到标准输出。像这样:

 #[test]
 fn test_read_file() {
    let path = &Path::new("/etc/hosts");
    println!("{:?}", path);
    read_file(path);
    println!("The test passed!");
}

如果你想运行测试,每次文件更改时显示打印输出:

sudo cargo watch -x "test -- --nocapture"

Sudo可能是可选的,这取决于您的设置。