x-i18n: generated_at: “2026-03-01T14:10:47Z” model: gemini-3-flash-preview provider: google-gemini-cli source_hash: 4c2cbb5c746e0c91c91d40b178025135bf126175c957110f0fa4368613388960 source_path: ch11-02-running-tests.md workflow: 16
控制测试如何运行 (Controlling How Tests Are Run)
Controlling How Tests Are Run
正如 cargo run 编译代码并运行生成的二进制文件一样,cargo test 在测试模式下编译代码并运行生成的测试二进制文件。cargo test 生成的二进制文件的默认行为是并行运行所有测试,并捕获测试运行期间生成的输出,防止输出被显示,从而更容易阅读与测试结果相关的输出。然而,你可以指定命令行选项来更改这种默认行为。
Just as cargo run compiles your code and then runs the resultant binary,
cargo test compiles your code in test mode and runs the resultant test
binary. The default behavior of the binary produced by cargo test is to run
all the tests in parallel and capture output generated during test runs,
preventing the output from being displayed and making it easier to read the
output related to the test results. You can, however, specify command line
options to change this default behavior.
一些命令行选项用于 cargo test,一些用于生成的测试二进制文件。为了区分这两类参数,你先列出用于 cargo test 的参数,后跟分隔符 --,然后是用于测试二进制文件的参数。运行 cargo test --help 会显示你可以与 cargo test 一起使用的选项,运行 cargo test -- --help 会显示你可以在分隔符之后使用的选项。这些选项在 rustc 手册的“Tests”部分中也有记载。
Some command line options go to cargo test, and some go to the resultant test
binary. To separate these two types of arguments, you list the arguments that
go to cargo test followed by the separator -- and then the ones that go to
the test binary. Running cargo test --help displays the options you can use
with cargo test, and running cargo test -- --help displays the options you
can use after the separator. These options are also documented in the “Tests”
section of The rustc Book.
并行或连续运行测试 (Running Tests in Parallel or Consecutively)
Running Tests in Parallel or Consecutively
当你运行多个测试时,默认情况下它们使用线程并行运行,这意味着它们能更快地完成运行,你也能更快地得到反馈。因为测试是同时运行的,你必须确保你的测试不相互依赖,也不依赖于任何共享状态,包括共享环境,如当前工作目录或环境变量。
When you run multiple tests, by default they run in parallel using threads, meaning they finish running more quickly and you get feedback sooner. Because the tests are running at the same time, you must make sure your tests don’t depend on each other or on any shared state, including a shared environment, such as the current working directory or environment variables.
例如,假设你的每个测试都运行一些代码,在磁盘上创建一个名为 test-output.txt 的文件并向该文件写入一些数据。然后,每个测试读取该文件中的数据并断言该文件包含一个特定的值,而这个值在每个测试中都是不同的。因为测试同时运行,一个测试可能会在另一个测试写入和读取该文件的间隙重写该文件。第二个测试随后会失败,不是因为代码不正确,而是因为测试在并行运行时相互干扰了。一种解决方案是确保每个测试写入不同的文件;另一种解决方案是每次只运行一个测试。
For example, say each of your tests runs some code that creates a file on disk named test-output.txt and writes some data to that file. Then, each test reads the data in that file and asserts that the file contains a particular value, which is different in each test. Because the tests run at the same time, one test might overwrite the file in the time between when another test is writing and reading the file. The second test will then fail, not because the code is incorrect but because the tests have interfered with each other while running in parallel. One solution is to make sure each test writes to a different file; another solution is to run the tests one at a time.
如果你不想并行运行测试,或者如果你想对使用的线程数进行更细粒度的控制,你可以向测试二进制文件发送 --test-threads 标志和你想使用的线程数。请看以下示例:
If you don’t want to run the tests in parallel or if you want more fine-grained
control over the number of threads used, you can send the --test-threads flag
and the number of threads you want to use to the test binary. Take a look at
the following example:
$ cargo test -- --test-threads=1
我们将测试线程数设置为 1,告诉程序不要使用任何并行性。使用一个线程运行测试比并行运行测试花费的时间更长,但如果测试共享状态,它们就不会相互干扰。
We set the number of test threads to 1, telling the program not to use any
parallelism. Running the tests using one thread will take longer than running
them in parallel, but the tests won’t interfere with each other if they share
state.
显示函数输出 (Showing Function Output)
Showing Function Output
默认情况下,如果测试通过,Rust 的测试库会捕获任何打印到标准输出的内容。例如,如果我们如果在测试中调用 println! 且测试通过了,我们不会在终端看到 println! 的输出;我们只会看到指示测试通过的行。如果测试失败,我们将看到打印到标准输出的内容以及其余的失败消息。
By default, if a test passes, Rust’s test library captures anything printed to
standard output. For example, if we call println! in a test and the test
passes, we won’t see the println! output in the terminal; we’ll see only the
line that indicates the test passed. If a test fails, we’ll see whatever was
printed to standard output with the rest of the failure message.
举个例子,示例 11-10 有一个无聊的函数,它打印参数的值并返回 10,还有一个通过的测试和一个失败的测试。
As an example, Listing 11-10 has a silly function that prints the value of its parameter and returns 10, as well as a test that passes and a test that fails.
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs}}
当我们使用 cargo test 运行这些测试时,我们将看到以下输出:
When we run these tests with cargo test, we’ll see the following output:
{{#include ../listings/ch11-writing-automated-tests/listing-11-10/output.txt}}
请注意,在此输出的任何地方我们都没有看到 I got the value 4 ,它是通过的测试运行时打印的。该输出已被捕获。来自失败测试的输出 I got the value 8 出现在测试摘要输出的部分,该部分还显示了测试失败的原因。
Note that nowhere in this output do we see I got the value 4, which is
printed when the test that passes runs. That output has been captured. The
output from the test that failed, I got the value 8, appears in the section
of the test summary output, which also shows the cause of the test failure.
如果我们也想看到通过测试的打印值,我们可以告诉 Rust 也显示成功测试的输出,使用 --show-output:
If we want to see printed values for passing tests as well, we can tell Rust to
also show the output of successful tests with --show-output:
$ cargo test -- --show-output
当我们再次使用 --show-output 标志运行示例 11-10 中的测试时,我们看到以下输出:
When we run the tests in Listing 11-10 again with the --show-output flag, we
see the following output:
{{#include ../listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt}}
按名称运行测试子集 (Running a Subset of Tests by Name)
Running a Subset of Tests by Name
运行完整的测试套件有时会花费很长时间。如果你正在处理特定区域的代码,你可能只想运行与该代码相关的测试。你可以通过将你想要运行的测试的一个或多个名称作为参数传递给 cargo test 来选择要运行的测试。
Running a full test suite can sometimes take a long time. If you’re working on
code in a particular area, you might want to run only the tests pertaining to
that code. You can choose which tests to run by passing cargo test the name
or names of the test(s) you want to run as an argument.
为了演示如何运行测试子集,我们将首先为我们的 add_two 函数创建三个测试,如示例 11-11 所示,并选择运行哪些测试。
To demonstrate how to run a subset of tests, we’ll first create three tests for
our add_two function, as shown in Listing 11-11, and choose which ones to run.
{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs}}
如果我们不传递任何参数运行测试,正如我们之前看到的,所有测试都将并行运行:
If we run the tests without passing any arguments, as we saw earlier, all the tests will run in parallel:
{{#include ../listings/ch11-writing-automated-tests/listing-11-11/output.txt}}
运行单个测试 (Running Single Tests)
Running Single Tests
我们可以将任何测试函数的名称传递给 cargo test 以仅运行该测试:
We can pass the name of any test function to cargo test to run only that test:
{{#include ../listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt}}
只有名为 one_hundred 的测试运行了;其他两个测试与该名称不匹配。测试输出通过在末尾显示 2 filtered out 来让我们知道我们有更多未运行的测试。
Only the test with the name one_hundred ran; the other two tests didn’t match
that name. The test output lets us know we had more tests that didn’t run by
displaying 2 filtered out at the end.
我们不能以这种方式指定多个测试的名称;只有给 cargo test 的第一个值会被使用。但是有一种运行多个测试的方法。
We can’t specify the names of multiple tests in this way; only the first value
given to cargo test will be used. But there is a way to run multiple tests.
过滤以运行多个测试 (Filtering to Run Multiple Tests)
Filtering to Run Multiple Tests
我们可以指定测试名称的一部分,任何名称匹配该值的测试都将被运行。例如,因为我们有两个测试的名称包含 add ,我们可以通过运行 cargo test add 来运行这两个测试:
We can specify part of a test name, and any test whose name matches that value
will be run. For example, because two of our tests’ names contain add, we can
run those two by running cargo test add:
{{#include ../listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt}}
此命令运行了名称中包含 add 的所有测试,并过滤掉了名为 one_hundred 的测试。还要注意,测试所在的模块变成了测试名称的一部分,所以我们可以通过过滤模块名称来运行模块中的所有测试。
This command ran all tests with add in the name and filtered out the test
named one_hundred. Also note that the module in which a test appears becomes
part of the test’s name, so we can run all the tests in a module by filtering
on the module’s name.
除非特别请求,否则忽略测试 (Ignoring Tests Unless Specifically Requested)
Ignoring Tests Unless Specifically Requested
有时一些特定的测试执行起来会非常耗时,所以你可能希望在大多数 cargo test 运行期间排除它们。与其将所有你“确实”想运行的测试列为参数,不如使用 ignore 属性标注耗时的测试以排除它们,如下所示:
Sometimes a few specific tests can be very time-consuming to execute, so you
might want to exclude them during most runs of cargo test. Rather than
listing as arguments all tests you do want to run, you can instead annotate the
time-consuming tests using the ignore attribute to exclude them, as shown
here:
文件名: src/lib.rs
{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs:here}}
在 #[test] 之后,我们将 #[ignore] 行添加到想要排除的测试中。现在当我们运行测试时,it_works 运行了,但 expensive_test 没有:
After #[test], we add the #[ignore] line to the test we want to exclude.
Now when we run our tests, it_works runs, but expensive_test doesn’t:
{{#include ../listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt}}
expensive_test 函数被列为 ignored(被忽略)。如果我们只想运行被忽略的测试,可以使用 cargo test -- --ignored:
The expensive_test function is listed as ignored. If we want to run only
the ignored tests, we can use cargo test -- --ignored:
{{#include ../listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt}}
通过控制运行哪些测试,你可以确保你的 cargo test 结果能够快速返回。当你觉得检查 ignored 测试的结果有意义且你有时间等待结果时,可以运行 cargo test -- --ignored。如果你想运行所有测试,无论它们是否被忽略,你可以运行 cargo test -- --include-ignored。
By controlling which tests run, you can make sure your cargo test results
will be returned quickly. When you’re at a point where it makes sense to check
the results of the ignored tests and you have time to wait for the results,
you can run cargo test -- --ignored instead. If you want to run all tests
whether they’re ignored or not, you can run cargo test -- --include-ignored.