Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

编写自动化测试

ch11-00-testing.md

Edsger W. Dijkstra 在其 1972 年的文章《谦卑的程序员》(“The Humble Programmer”)中说:“软件测试是证明 bug 存在的有效方法,而要证明 bug 不存在,它就显得远远不够。”(“Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence.”)这并不意味着我们不应尽可能地做测试!

程序的正确性,指的是代码在多大程度上实现了我们的预期。Rust 在设计上高度重视程序的正确性,不过正确性是一个复杂且不易证明的主题。Rust 的类型系统承担了这方面很大一部分工作,但类型系统不可能捕获所有问题。为此,Rust 提供了编写自动化软件测试的支持。

假设我们编写了一个叫做 add_two 的函数,它会把传给它的数字加上 2。这个函数的签名接受一个整数参数,并返回一个整数结果。当我们实现并编译这个函数时,Rust 会进行目前你已经见过的所有类型检查和借用检查,以确保例如我们不会向这个函数传递一个 String 值或无效引用。但 Rust 无法检查这个函数是否真的精确实现了我们的意图,也就是返回“参数加 2”,而不是比如“参数加 10”或“参数减 50”!这正是测试发挥作用的地方。

我们可以编写测试断言,比如说,当传递 3add_two 函数时,返回值是 5。无论何时对代码进行修改,都可以运行测试来确保任何现存的正确行为没有被改变。

测试是一项复杂的技能:虽然不能在一个章节的篇幅中介绍如何编写好的测试的每个细节,但我们还是会讨论 Rust 测试功能的机制。我们会讲到编写测试时会用到的注解和宏,运行测试的默认行为和选项,以及如何将测试组织成单元测试和集成测试。