x-i18n: generated_at: “2026-03-01T14:08:36Z” model: gemini-3-flash-preview provider: google-gemini-cli source_hash: c65a2080c43a9f3d83a351779e059c6203b2c48285835c9fd277f7465fbd5192 source_path: ch11-00-testing.md workflow: 16
编写自动化测试 (Writing Automated Tests)
Writing Automated Tests
艾兹赫尔·韦伯·戴克斯特拉 (Edsger W. Dijkstra) 在其 1972 年的文章《谦卑的程序员》(The Humble Programmer) 中提到:“程序测试是证明存在漏洞的一种非常有效的方法,但对于证明不存在漏洞却显得无可奈何。”这并不意味着我们不应该尽力去测试!
In his 1972 essay “The Humble Programmer,” Edsger W. Dijkstra said that “program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence.” That doesn’t mean we shouldn’t try to test as much as we can!
程序的“正确性 (Correctness)”是指我们的代码在多大程度上符合我们的意图。Rust 在设计时就高度关注程序的正确性,但正确性极其复杂且不易证明。Rust 的类型系统承担了这一重担的大部分,但类型系统无法捕获所有问题。因此,Rust 包含了对编写自动化软件测试的支持。
Correctness in our programs is the extent to which our code does what we intend it to do. Rust is designed with a high degree of concern about the correctness of programs, but correctness is complex and not easy to prove. Rust’s type system shoulders a huge part of this burden, but the type system cannot catch everything. As such, Rust includes support for writing automated software tests.
假设我们编写了一个函数 add_two,它在传入的任何数字上加 2。该函数的签名接收一个整数作为参数并返回一个整数作为结果。当我们实现并编译该函数时,Rust 会执行你目前学到的所有类型检查和借用检查,以确保我们不会向该函数传递一个 String 值或一个无效引用。但 Rust “无法”检查这个函数是否完全符合我们的意图,即返回参数加 2,而不是参数加 10 或参数减 50!这就是测试派上用场的地方。
Say we write a function add_two that adds 2 to whatever number is passed to
it. This function’s signature accepts an integer as a parameter and returns an
integer as a result. When we implement and compile that function, Rust does all
the type checking and borrow checking that you’ve learned so far to ensure
that, for instance, we aren’t passing a String value or an invalid reference
to this function. But Rust can’t check that this function will do precisely
what we intend, which is return the parameter plus 2 rather than, say, the
parameter plus 10 or the parameter minus 50! That’s where tests come in.
我们可以编写测试来断言,例如,当我们向 add_two 函数传递 3 时,返回值是 5。每当我们更改代码时,我们都可以运行这些测试,以确保现有的正确行为没有发生变化。
We can write tests that assert, for example, that when we pass 3 to the
add_two function, the returned value is 5. We can run these tests whenever
we make changes to our code to make sure any existing correct behavior has not
changed.
测试是一项复杂的技能:虽然我们无法在一章中涵盖编写优秀测试的所有细节,但在本章中我们将讨论 Rust 测试设施的机制。我们将讨论你在编写测试时可用的注解和宏,运行测试时提供的默认行为和选项,以及如何将测试组织成单元测试和集成测试。
Testing is a complex skill: Although we can’t cover in one chapter every detail about how to write good tests, in this chapter we will discuss the mechanics of Rust’s testing facilities. We’ll talk about the annotations and macros available to you when writing your tests, the default behavior and options provided for running your tests, and how to organize tests into unit tests and integration tests.