# 编写自动化测试

在 Edsgar W. Dijkstra（迪杰斯特拉） 1972 年论文 [《谦卑的程序员（The Humble Programmer）》](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD03xx/EWD340.html)中，迪杰斯特拉指出 “程序测试可以是一种揭示代码存在的非常有效方式，但对于揭示代码错误存在，程序测试又显得不那么足够（Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absensce）。” 这并不意味着咱们就不要尽力进行尽可能多的测试！

所谓计算机程序正确，即为所编写代码，在多大程度上完成了想要他完成的事情。Rust 是以高度关注程序正确度而设计的，不过正确度是个复杂的问题，而不易于证明。Rust 的类型系统承担了保证正确性的很大部分，但类型系统并不能捕获到所有东西。由于这方面的原因，Rust 包括了编写自动化软件测试的支持。

这里假设说编写了一个将 `2` 加到所传入任何数字的一个函数 `add_two`。该函数的签名，会接受某个整数作为参数，并返回一个整数作为计算结果。在实现并编译那个函数时，Rust 会完成至此所掌握的全部类型检查与借用检查，来确保比如这里没有传递某个 `String` 值，或传递某个无效引用到该函数。但 Rust *无法* 就该函数将准确完成咱们所想要的操作，即返回参数加 `2`，而非参数加 `10` 或者参数减去 `50` 进行检查！这正是测试发挥作用的地方。

可编写出进行假定的一些测试来，比如，在将 `3` 传递给这个 `add_two` 函数时，返回的值就是 `5`。每当修改了代码时，就都可以运行这些测试，来确保车关系的任何既有正确行为，没有发生变化。

测试是门综合技能：尽管这里无法在一章中，涉及到怎样编写良好测试的方方面面，这里还是会对 Rust 各种测试设施的机制进行讨论。这里会讲到在编写测试时，可用的注解与宏，运行测试的默认动作与选项，以及怎样将一些测试，组织为单元测试与集成测试（unit tests and integration tests）。
