# 编写自动化测试
在 1972 年的论文《谦卑的程序员》中,Edsger W. Dijkstra 说:"程序测试可以非常有效地显示错误的存在,但它对于证明错误的不存在却是无能为力的。"这并不意味着我们不应该尽可能多地进行测试!
程序的正确性是指我们的代码按照我们的意图运行的程度。Rust 在设计时高度关注程序的正确性,但正确性是复杂的,并且不容易证明。Rust 的类型系统承担了这一负担的很大一部分,但类型系统无法捕获所有问题。因此,Rust 包含了对编写自动化软件测试的支持。
假设我们编写一个 add_two 函数,它将传入的任何数字加 2。这个函数的签名接受一个整数作为参数并返回一个整数作为结果。当我们实现并编译该函数时,Rust 会进行所有的类型检查和借用检查(你已经学过的),以确保,例如,我们没有向这个函数传递 String 值或无效的引用。但 Rust 无法检查这个函数是否会精确地按照我们的意图执行,即返回参数加 2,而不是,比如说,参数加 10 或参数减 50!这就是测试发挥作用的地方。
我们可以编写测试来断言,例如,当我们向 add_two 函数传递 3 时,返回值是 5。每当我们对代码进行更改时,我们都可以运行这些测试,以确保任何现有的正确行为没有改变。
测试是一项复杂的技能:虽然我们无法在一章中涵盖如何编写好测试的每一个细节,但在本章中,我们将讨论 Rust 测试工具的机制。我们将讨论编写测试时可用的注解和宏,运行测试时提供的默认行为和选项,以及如何将测试组织成单元测试和集成测试。