内容简介
《有效的单元测试》本书分为三部分,共9章。第一部分(第1~3章)主要阐述测试的目的与原因,并分析作为常用工具的测试替身的作用。第1章先从整体阐释测试先行所带来的价值,以及各种对测试和测试质量的影响。第2章定义如何才能写出的测试。第3章讨论现代程序员本的工具之一——测试替身。第二部分(第4~6章)的目标是帮助我们更好地识别并修复测试代码中的坏味道。第4章展示破坏测试可读性的坏味道。第5章继续对破坏可维护性的测试提供建议。第6章涉及有关脆弱或不可靠的测试坏味道。第三部分(第7~9章)涉及Java程序员在编写测试时随时可能碰到的话题。第7章介绍可测的设计的定义与作用。第8章探讨JVM语言的共生,以及如何用另一门语言来测试Java代码。第9章专门讨论对构建进行加速的问题。此外还包括两个附录,附录A介绍使用JUnit编写测试的入门知识。附录B探讨通过JUnit的API来扩展其内置功能。
目录
译者序
序言
前言
致谢
第一部分 基础
第1章 测试的承诺 2
1.1 国情咨文:编写更好的测试 3
1.2 测试的价值 3
1.2.1 生产力的因素 6
1.2.2 设计潜力的曲线 8
1.3 测试作为设计工具 9
1.3.1 测试驱动开发 9
1.3.2 行为驱动开发 11
1.4 小结 12
第2章 寻求 13
2.1 可读的代码才是可维护的代码 14
2.2 结构有助于理解事物 16
2.3 如果测试了错误的东西就不好了 17
2.4 独立的测试易于单独运行 18
2.5 可靠的测试才是可靠的 21
2.6 每个行业都有其工具而测试也不例外 22
2.7 小结 23
第3章 测试替身 24
3.1 测试替身的威力 25
3.1.1 隔离被测代码 26
3.1.2 加速执行测试 27
3.1.3 使执行变得确定 27
3.1.4 模拟特殊情况 28
3.1.5 暴露隐藏的信息 29
3.2 测试替身的类型 30
3.2.1 测试桩通常是短小的 30
3.2.2 伪造对象做事不产生副作用 31
3.2.3 测试间谍偷取秘密 32
3.2.4 模拟对象反对惊喜 34
3.3 使用测试替身的指南 35
3.3.1 为测试挑选合适的替身 35
3.3.2 准备、执行、断言 36
3.3.3 检查行为,而非实现 37
3.3.4 挑选你的工具 38
3.3.5 注入依赖 39
3.4 小结 39
第二部分 目录
第4章 可读性 42
4.1 基本断言 43
4.1.1 示例 43
4.1.2 该对它做点儿什么 44
4.1.3 小结 45
4.2 过度断言 46
4.2.1 示例 46
4.2.2 该对它做点儿什么 48
4.2.3 小结 50
4.3 按位断言 50
4.3.1 示例 50
4.3.2 该对它做点儿什么 51
4.3.3 小结 51
4.4 附加细节 52
4.4.1 示例 52
4.4.2 该对它做点儿什么 53
4.4.3 小结 54
4.5 人格分裂 55
4.5.1 示例 55
4.5.2 该对它做点儿什么 56
4.5.3 小结 58
4.6 逻辑分割 59
4.6.1 示例 59
4.6.2 该对它做点儿什么 61
4.6.3 小结 63
4.7 魔法数字 64
4.7.1 示例 64
4.7.2 该对它做点儿什么 64
4.7.3 小结 65
4.8 冗长安装 65
4.8.1 示例 66
4.8.2 该对它做点儿什么 67
4.8.3 小结 68
4.9 过分保护 68
4.9.1 示例 69
4.9.2 该对它做点儿什么 69
4.9.3 小结 70
4.10 总结 70
第5章 可维护性 71
5.1 重复 72
5.1.1 示例 72
5.1.2 该对它做点儿什么 73
5.1.3 小结 75
5.2 条件逻辑 75
5.2.1 示例 76
5.2.2 该对它做点儿什么 76
5.2.3 小结 77
5.3 脆弱的测试 78
5.3.1 示例 78
5.3.2 该对它做点儿什么 79
5.3.3 小结 80
5.4 残缺的文件路径 80
5.4.1 示例 81
5.4.2 该对它做点儿什么 81
5.4.3 小结 83
5.5 的临时文件 83
5.5.1 示例 84
5.5.2 该对它做点儿什么 85
5.5.3 小结 86
5.6 沉睡的蜗牛 86
5.6.1 示例 87
5.6.2 该对它做点儿什么 88
5.6.3 小结 89
5.7 像素 89
5.7.1 示例 89
5.7.2 该对它做点儿什么 90
5.7.3 小结 93
5.8 参数化混乱 94
5.8.1 示例 95
5.8.2 该对它做点儿什么 98
5.8.3 小结 99
5.9 方法间缺乏内聚 100
5.9.1 示例 100
5.9.2 该对它做点儿什么 101
5.9.3 小结 104
5.10 总结 104
第6章 可信赖 106
6.1 注释掉的测试 107
6.1.1 示例 107
6.1.2 该对它做点儿什么 108
6.1.3
摘要与插图
过去10余年间,Java开发者显著地青睐开发者测试。如今,计算机科学专业的毕业生无人不知自动化单元测试及其在软件开发中的重要性。这个想法很简单——确保我们的代码能工作并且一直能工作——但是该技能需要花很大力气去学习。编写测试、学习JUnit的测试框架,这些都不难。要真正地掌握编写自动化单元测试实践,需要花大量时间在阅读并改善测试代码上。这种持续的测试重构能够尝试用不同方式来表达意图、组织测试的不同行为、用测试构建各种用到的对象——这才是一种务实的方式,用来自我学习和培养对单元测试的感觉。
这种感觉是关于哪些是的单元测试,而哪些不那么。有些是的真理(比如在重复代码内容的注释就是冗余的,应该被删除),但大多数关于单元测试的知识都取决于上下文。通常意义上的在特定条件下可能却很糟糕。同样,一般认为糟糕和应当避免的想法有时却是正确的做法。
原来,找到方案的方式就是尝试一个看似可行的方法,识别该方法的问题,然后改变该方法从而消除讨厌的部分。通过重复这个过程,不断地评估和进化,你会找到一个可行的方案,它闻起来没那么臭。你甚至会说那是相当的方式!
考虑到这种复杂性,本书采用了一种风格和结构,那就是我们不会告诉你怎么做,也不会告诉你怎么编写单元测试。相反,我打算给你一个坚实的基础,让你知道哪些是我们希望测试表现出的属性,然后给你尽可能多的例子来培养你对测试坏味道的感觉——帮你注意到测试中的不合时宜之处。
受众
本书针对想要提高单元测试编写质量的各个层次的Java程序员。虽然我们提供了附录来教给你测试框架(JUnit),但我们的主要目标是帮助已经了解单元测试的Java程序员,用其喜欢的测试框架来编写更好的单元测试。不管你已经写了多少单元测试,我们肯定你仍然可以做得更好,阅读本书或许能带你揭示一些难以言喻的想法。
路线图
本书提到了多个方面的挑战,因此需要良好的结构来支撑这些方面。深思熟虑后(源自于多次迭代中的失败尝试),我们决定将本书分为三个部分。
关于更好的测试,第一部分先介绍了我们要达到的目标,以及它们为什么是可取的。其中的三章展示了编写测试的基本工具和简单指南。
第1章从自动化单元测试的价值主张开始。我们通过考虑程序员生产力的多种因素来建立价值,以及编写自动化单元测试如何有助于生产力,或避免耽误我们。
第2章提高了标准,尝试定义什么是的测试。该章中的属性和注意事项是第二部分的核心基础,涉及测试的可读性、可维护性和可靠性。
第3章进一步介绍测试替身,作为编写测试的重要工具。我们并不是为了使用测试替身而使用,而是深思熟虑地用好它们。(它们不是你想要的银弹。)
第二部分与第一部分形成鲜明对比,把一个测试坏味道的目录摆在你面前。除了描述测试代码中的可疑模式外,我们也给出了面对这些坏味道时的尝试方案。这些章节分为三个主题:令可读性退化的坏味道、暗示着潜在维护性梦魇的坏味道,以及带来信任危机的坏味道。第二部分的许多坏味道可以归为三大章节中的任何一个,但我们尝试根据其主要影响来归类。
第4章中的坏味道,主要侧重于过分不透明的测试意图或实现。我们涉及诸如模糊的断言、不恰当的抽象层次和测试代码的信息分散。
第5章中的坏味道会导致在办公室加班,因为要针对一个小的变更而没完没了地修改某个单元测试,或者为了一个小的变更要修改数百个测试。我们谈及了代码重复、测试代码中的逻辑和阐述触及文件系统的恐怖。我们也不会让缓慢的测试从眼皮底下