Почему не println! работа в модульных тестах ржавчины?
я реализовал следующий метод и блок тест:
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!
никогда не отображается на экране. Почему бы и нет?
4 ответа:
это происходит потому, что программы тестирования ржавчины скрывают 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 будет напечатан независимо от того, если эта опция присутствует или нет.
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
во время тестирования, стандартный вывод не отображается. Не используйте текстовые сообщения для тестирования, но
assert!
,assert_eq!
и . Система модульного тестирования Rust может понять эти, но не текстовые сообщения.тест вы написали пройдет, даже если что-то пойдет не так. Давайте посмотрим, почему:
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
не следует злоупотреблять.