缺陷逃逸数量增多的另一个因素是测试结果的准确度。你若要能够依赖于测试套件去识别引入的错误,那么准确度是一个基本要求。剩下的两个影响生产力的测试相关根本原因,都会直接影响测试准确度,它们叫做可信赖性和可靠性。为了测试报告的准确性,测试需要断言它们的承诺,并以可靠、可重复的方式提供断言。
通过关注对生产力的影响力,你可以扩展质量稳态。使程序员变得高效的关键正是这些已经识别出的根本原因。高产的先决条件是你足够了解你的工具,而不是持续分散你的注意力。一旦你了解了编程语言,你可以浏览其核心API。当你熟悉了问题域,就专注于根本原因——可读性、可靠性、可信赖性和测试的速度。
这也是本书剩余大部分将要围绕的内容——帮助你提高对测试代码可读性、可信赖性和可靠性的意识和感觉,并确保你能持续使用这种工作方式,以确保可维护性。
在那之前,我们来解释图1.2中的第二条曲线。
1.2.2设计潜力的曲线
假设你先写了最重要的测试——针对最常见和基本的场景,以及软件架构中的关键部位。
你的测试质量很高,你大胆地将重复都重构掉,保持测试精益且可维护。现在想象一下,你积累了如此高的测试覆盖率,唯一没测到的地方只是那些直接针对字段的访问器。平心而论,为那些地方写测试没什么价值。因此,之前的做法倾向于收益递减——你已经不能再从“仅仅”编写测试这件事中获取价值了。
这是由于我们不做的事情而造成的质量稳态。之所以这么说是因为想要达到更高的生产力,你需要换个思路去考虑测试。为了找回丢掉的潜力,你需要从编写测试中找到完全不同的价值——价值来自于创新及设计导向,而非防止回归缺陷的保护及验证导向。
总而言之,为了能同时达到两个稳态,从而完全发挥测试的潜力,你需要:
1。像生产代码一样对待你的测试代码——大胆地重构、创建和维护高质量测试,你自己要对它们有信心。
2.开始将测试作为一种设计工具,指导代码针对实际用途进行设计。
如前所述,前者造成了大多数程序员在编写测试时会不知所措,无法顾及高质量,或降低编写、维护、运行测试的成本。这也是本书的重点——编写优秀的测试。
也就是说我们不会花很多时间去讨论利用测试作为设计的方面。我只是想让你对这种动态和工作方式有个全面的了解,那我们详细说说这个话题再前进吧。
1.3测试作为设计工具
传统上,程序员编写的自动化测试被看做是质量保证工作,用于在编写的时候验证实现的正确性,以及将来代码进化的时候验证正确性。这就是将测试作为验证工具——你设想一份设计,编写代码实现,编写测试验证实现是否正确。
使用自动化测试作为设计工具将世界颠倒过来了。当你用测试设计代码时,你将典型的“设计,编码,测试”序列变换为“测试,编码,设计”。是的,就是那样。测试先于编码,并以追溯性的设计活动来得出结论。那结论性的设计活动称为重构,序列变为“测试,编码,重构”.如图1.4所示。
1.3.1测试驱动开发
TDD,如图1.5所示,是一种很有章法的编程技术,它基于一个简单的想法:在编写出能够证明代码存在的失败测试之前,不写生产代码。这也是它有时被称为测试先行编程的原因。
不止这些。先写测试,会向测试所期望的方向来驱动生产代码的设计。这会带来以下令人满意的后果:
·代码变得可用——代码的设计和API适合于你的使用场景。
·代码变得精益——生产代码仅仅实现场景所需要的功能。
首先,无论你工作在系统蓝图的哪一部分,无论其他组件、类或接口存在与否,你一定是在为一个具体的场景来设计解决方案。你将该场景翻译为一个可执行的例子,以自动化单元测试的方式。运行测试,看着它失败,你具有了一个使之通过的清晰目标,只编写足够的生产代码——不要多写。
……