编写自动化测试

Edsger W. Dijkstra 在他 1972 年的论文“简陋的程序员”中说道:“程序测试可以非常有效地证明 bug 的存在,但它对于证明 bug 的不存在却毫无用处。”但这并不意味着我们不应该尽可能多地进行测试!

程序的正确性是指我们的代码在多大程度上按照我们的预期执行。Rust 在设计时高度关注程序的正确性,但正确性是一个复杂且难以证明的问题。Rust 的类型系统承担了这方面的大部分责任,但类型系统并不能捕捉到所有问题。因此,Rust 包含了对编写自动化软件测试的支持。

假设我们编写了一个函数 add_two,它将传递给它的任何数字加 2。此函数的签名接受一个整数作为参数,并返回一个整数作为结果。当我们实现和编译该函数时,Rust 会执行您目前为止学到的所有类型检查和借用检查,以确保例如我们没有传递 String 值或无效引用给此函数。但 Rust 无法 检查此函数是否会完全按照我们的预期执行,即返回参数加 2,而不是例如参数加 10 或参数减 50!这就是测试的用武之地。

我们可以编写测试来断言,例如,当我们将 3 传递给 add_two 函数时,返回值为 5。每当我们对代码进行更改时,我们都可以运行这些测试,以确保任何现有的正确行为没有改变。

测试是一项复杂的技能:尽管我们无法在一章中涵盖有关如何编写良好测试的所有细节,但我们将讨论 Rust 测试工具的机制。我们将讨论编写测试时可用的注释和宏、运行测试时提供的默认行为和选项,以及如何将测试组织成单元测试和集成测试。