왜 프린트하지 않습니까! 녹 단위 시험에서 일합니까?


285

다음 방법과 단위 테스트를 구현했습니다.

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!가 화면에 표시되지 않는다는 메시지가 다시 나타납니다. 왜 안돼?

답변:


327

이는 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

그러나 테스트에 실패하면이 옵션이 있는지 여부에 관계없이 stdout이 인쇄됩니다.


10
--nocapture옵션 전달을 언급 cargo test했지만화물이이 플래그를 인식하지 못합니다 (rustup.sh의 최신 야간 사용). 제대로 작동해야합니까?
Jim Garrison

42
@JimGarrison은 실제로 그것에 문제 가 있습니다. 한편 당신은 사용할 수 있습니다 cargo test -- --nocapture, 그것은 작동합니다.
Vladimir Matveev

4
감사! 이 질문과 관련이 없지만 cargo test [--] --bench작업을 수행 하는 방법을 알아내는 데 도움이 되었습니다.
Jim Garrison

6
@Nashenas에서는 옵션이 nocapture아닌 이라고 no-capture합니다.
Vladimir Matveev 5

1
Windows의 Visual Studio Code에서 디버깅 할 때 인쇄하는 방법을 아는 사람이 있습니까? "cargo test --no-run---nocapture"디버거 팝업 창에 다음 작업이 인쇄되지 않습니다. 실행되지 않는 인수는 차이가없는 것처럼 보이지만 사용하십시오. 내가 보는 것은 "1 개의 테스트를 실행하는 것"입니다. 어색한 툴링.
David

75

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

cargo test -- --no-capture더 이상 작동하지 않습니다. 다음과 같은 오류가 발생합니다.thread '<main>' panicked at '"Unrecognized option: \'no-capture\'."', ../src/libtest/lib.rs:249
Nashenas

이 문제가 github.com/rust-lang/cargo/issues/1377 문제 인지 궁금합니다 .
superlogical

5
이전 댓글에서 지적 된 바와 같이, 옵션입니다 --nocapture하지 --no-capture. 그러나 우리가 접하는 경향이있는 대부분의 명령 행 규칙을 적용하는 것은 완전히 명백한 실수입니다. 방금 rust 1.1 (cargo 0.2.0) 의이 답변에 설명 된 대로이 옵션을 사용했으며 광고 한대로 정확하게 작동했습니다.
Glenn McAllister

10

println!()테스트 결과에 인쇄물을 포함 하고 색상을 유지하려면 color및의 nocapture플래그를 사용하십시오 cargo test.

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

(화물 버전 : 야간 0.13.0)


6

테스트하는 동안 표준 출력이 표시되지 않습니다. 테스트하지만 문자 메시지를 사용하지 마십시오 assert!, assert_eq!그리고 fail!대신. Rust의 단위 테스트 시스템은 문자 메시지가 아닌 이러한 내용을 이해할 수 있습니다.

어떤 문제가 있어도 작성한 시험은 통과합니다. 이유를 보자 :

read_to_end의 서명은 fn read_to_end(&mut self) -> IoResult<Vec<u8>>

IoResult성공 또는 오류를 나타 내기 위해 를 반환합니다 . 이것은 Result오류 값이에 대한 유형 def입니다 IoError. 오류 처리 방법을 결정하는 것은 사용자의 책임입니다. 이 경우, 우리는 호출하여 수행됩니다 실패 작업, 원하는 unwrap온을 Result.

이것은 작동합니다 :

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

unwrap 그래도 남용해서는 안됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.