测试

我们都知道,测试是任何软件不可或缺的一部分!Rust 对单元测试和集成测试提供了一流的支持(请参阅 TRPL 中的这一章)。

从上面链接的测试章节中,我们了解了如何编写单元测试和集成测试。在组织结构上,我们可以将单元测试放置在它们测试的模块中,并将集成测试放置在它们自己的tests/目录中。

foo ├── Cargo.toml ├── src │ └── main.rs │ └── lib.rs └── tests ├── my_test.rs └── my_other_test.rs

tests 中的每个文件都是一个单独的集成测试,即旨在测试你的库,就好像它被从一个依赖的 crate 调用一样。

测试章节详细阐述了三种不同的测试风格:单元文档集成

cargo 自然地提供了一种简单的方法来运行所有的测试!

$ cargo test

你应该看到像这样的输出

$ cargo test Compiling blah v0.1.0 (file:///nobackup/blah) Finished dev [unoptimized + debuginfo] target(s) in 0.89 secs Running target/debug/deps/blah-d3b32b97275ec472 running 4 tests test test_bar ... ok test test_baz ... ok test test_foo_bar ... ok test test_foo ... ok test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

你也可以运行名称与模式匹配的测试

$ cargo test test_foo
$ cargo test test_foo Compiling blah v0.1.0 (file:///nobackup/blah) Finished dev [unoptimized + debuginfo] target(s) in 0.35 secs Running target/debug/deps/blah-d3b32b97275ec472 running 2 tests test test_foo ... ok test test_foo_bar ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out

一个需要注意的事项:Cargo 可能会同时运行多个测试,所以请确保它们之间不会发生竞争。

这种并发导致问题的一个例子是,如果两个测试都输出到一个文件,如下所示

#![allow(unused)] fn main() { #[cfg(test)] mod tests { // Import the necessary modules use std::fs::OpenOptions; use std::io::Write; // This test writes to a file #[test] fn test_file() { // Opens the file ferris.txt or creates one if it doesn't exist. let mut file = OpenOptions::new() .append(true) .create(true) .open("ferris.txt") .expect("Failed to open ferris.txt"); // Print "Ferris" 5 times. for _ in 0..5 { file.write_all("Ferris\n".as_bytes()) .expect("Could not write to ferris.txt"); } } // This test tries to write to the same file #[test] fn test_file_also() { // Opens the file ferris.txt or creates one if it doesn't exist. let mut file = OpenOptions::new() .append(true) .create(true) .open("ferris.txt") .expect("Failed to open ferris.txt"); // Print "Corro" 5 times. for _ in 0..5 { file.write_all("Corro\n".as_bytes()) .expect("Could not write to ferris.txt"); } } } }

虽然目的是得到以下内容

$ cat ferris.txt Ferris Ferris Ferris Ferris Ferris Corro Corro Corro Corro Corro

但实际上放入 ferris.txt 中的却是这个

$ cargo test test_file && cat ferris.txt Corro Ferris Corro Ferris Corro Ferris Corro Ferris Corro Ferris