Почему не печатает! работать в блочных тестах Rust?
Я реализовал следующий метод и unit test:
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);
}
Я запускаю unit test следующим образом:
rustc --test app.rs; ./app
Я мог бы также запустить это с помощью
cargo test
Я получаю сообщение, в котором говорится, что тест прошел, но println!
никогда не отображается на экране. Почему бы и нет?
Ответы
Ответ 1
Это происходит из-за того, что программы тестирования Rust скрывают stdout успешных тестов, чтобы тестовый результат был аккуратным. Вы можете отключить это поведение, передав параметр --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 будет напечатано независимо от того, присутствует ли этот параметр или нет.
Ответ 2
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
Ответ 3
Во время тестирования стандартный вывод не отображается. Не используйте текстовые сообщения для тестирования, а assert!
, assert_eq!
и fail!
. Система Rust unit test может понимать эти, но не текстовые сообщения.
Тест, который вы написали, пройдет, даже если что-то пойдет не так. Давайте посмотрим, почему:
Подпись read_to_end
fn read_to_end(&mut self) -> IoResult<Vec<u8>>
Он возвращает IoResult
для указания успеха или ошибки. Это просто тип def для Result
, значение ошибки которого равно IoError
. Вам решать, как следует обрабатывать ошибки. В этом случае мы хотим, чтобы задача завершилась неудачей, что делается путем вызова unwrap
на Result
.
Это будет работать:
let contents = File::open(&Path::new("message.txt"))
.read_to_end()
.unwrap();
unwrap
не следует переоценивать.
Ответ 4
Чтобы включить распечатывание с println!()
и сохранить цвета для результатов теста, используйте флаги color
и nocapture
в cargo test
.
$ cargo test -- --color always --nocapture
(грузовая версия: 0.13.0 в ночное время)