web-dev-qa-db-ja.com

なぜ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!は画面に表示されません。何故なの?

201
ruipacheco

これは、テスト出力が整頓されるように、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

ただし、テストが失敗すると、このオプションが存在するかどうかに関係なく、標準出力が出力されます。

234

TL; DR

$ 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
59
superlogical

println!()を含む印刷出力を含め、テスト結果の色を保持するには、cargo testcolorおよびnocaptureフラグを使用します。

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

(貨物バージョン:毎晩0.13.0)

5
nate

テスト中、標準出力は表示されません。テストにはテキストメッセージを使用せず、代わりにassert!assert_eq!、およびfail!を使用します。 Rustの単体テストシステムはこれらを理解できますが、テキストメッセージは理解できません。

何かがうまくいかなくても、書いたテストはパスします。理由を見てみましょう:

read_to_endの署名はfn read_to_end(&mut self) -> IoResult<Vec<u8>>です

成功またはエラーを示すIoResultを返します。これは、エラー値がResultであるIoErrorの単なる型定義です。エラーの処理方法を決定するのはユーザー次第です。この場合、タスクを失敗させます。これは、unwrapResultを呼び出すことによって実行されます。

これは動作します:

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

ただし、unwrapは使いすぎないようにしてください。

4
A.B.