为什么不println!在Rust单元测试中工作?

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

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!从未显示在屏幕上。为什么不呢?

124976 次浏览

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

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

read_to_end的签名是 fn read_to_end(&mut self) -> IoResult<Vec<u8>> < / p >

它返回IoResult来表示成功或错误。这只是一个错误值为IoErrorResult的类型定义。如何处理错误由您决定。在这种情况下,我们希望任务失败,这是通过调用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中的colornocapture标记。

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

(载货版:0.13.0每晚)

作为L. F。--show-output是要走的路。

$ cargo test -- --show-output

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

为什么?我不知道,但有一个小hack eprintln!("will print in {}", "tests")

注意,现代解决方案(cargo test -- --show-output)在函数文档字符串中的Markdown代码围栏中定义的doctest中不起作用。只有在具体的#[test]块中执行的println!(等)语句才会被尊重。