Reading 03-Testing
目标
这篇内容结束后,你应该:
- 了解测试的价值,了解测试优先程序的过程;
- 能够判断测试套件的正确性、彻底性和大小;
- 能够通过划分方法的输入空间和选择好的测试用例来设计方法的测试套件;
Validation(验证)
Testing is an example of a more general process called validation.
验证的目的是发现程序中的问题,从而提高您对程序正确性的信心。审定工作包括:
- 形式推理(Formal reasoning)关于一个程序,通常称为核(verification)。verification构建了程序正确的证明。
- 代码评审(Code review)。让其他人仔细阅读您的代码,并对其进行非正式的推理,是发现bug的好方法。
- 测试(Testing)。在精心选择的输入上运行程序并检查结果。
Even with the best validation, it’s very hard to achieve perfect quality in software.
Test-first programming(测试优先编程)
在深入研究之前,需要定义一些术语:
- 模块(module)是软件系统的一部分,可以与系统的其他部分分别设计、实现、测试和推理。
- 规格(specification or spec)描述模块的行为。对于函数,规范给出了参数的类型和对它们的任何附加约束(例如,sqrt其参数必须是非负的)。它还给出了返回值的类型以及返回值与输入的关系。在Java代码中,规范由方法签名和上面描述它所做工作的注释组成。
- 模块具有实施(implementation)提供它的行为,以及客户(client)使用模块的人。对于函数,实现是方法的主体,客户端是调用该方法的其他代码。模块的规范限制了客户端和实现。从现在开始,我们将有更多关于规范、实现和客户端的信息。
- 测试用例(test case)是一种特定的输入选择,以及规范所要求的预期输出。
- 测试套件(test suite)是模块的一组测试用例。
In test-first-programming, you write the spec and the tests before you even write any code. The development of a single function proceeds in this order:
- Spec: Write a specification for the function.
- Test: Write tests that exercise the specification.
- Implement: Write the implementation.
Once your implementation passes the tests you wrote, you’re done.
The biggest benefit of test-first programming is safety from bugs. 不要等到开发结束时才进行测试,因为那时有大量未经验证的代码。将测试保留到最后只会使调试变得更长和更痛苦,因为bug可能在代码中的任何位置。
Systematic testing
Systematic testing意味着我们以一种有原则的方式选择测试用例,目的是设计一个具有三个理想属性的测试套件: