测试驱动开发(TDD)已经不是一个新话题,在现在的项目开发中得到各种程度的运用,资深开发者 Paulo总结了自己在实施TDD 时的经验教训,值得读者借鉴。
1. 不要在没有尝试之前,就在实际的项目中直接应用测试驱动开发,这不会有好结果。首先要搞清楚测试驱动开发的流程是什么样的,如何模拟测试对象,如何模拟框架内部的各个部分,如何组织测试等等。如果你的团队对此没有做好准备,那么盲目实施测试驱动开发会降低开发速度并超过交付期限。
2. 编程道场(Coding Dojo)是训练测试驱动开发的好办法。我们会举办相关的会议,发现通过这些方式能够教育新入门的开发人员并及时更新技术。
3. 在实施测试驱动开发之前要努力说服整个团队。最让人失望的莫过于有些开发人员会毁了我们的测试成果。我之前的团队曾近有过类似的经历。向同事们解释测试驱动开发的好处、为什么会降低我们的缺陷率、为什么可以无忧地重构代码。
4. 编写足够的测试。构建一个测试集就像是建造一个隔绝错误的屏障,团队应该能够充分信任这道屏障,特别是在我们重构或者演进软件时。如果屏障存在漏洞,那么我们就会增加出现错误的风险。你不需要百分之百的涵盖所有的代码,这几乎是不可能的,而且浪费了很多时间,但是最好能够覆盖大部分代码。经验就是测试一切可能会出错的地方。
5. 使用代码覆盖率工具。这些工具会检查测试集与实际代码之间的差距。大多数工具会提供直观的展示,比如,测试过的地方标为绿色,而未测试的部分则是红色。如果你是一个.NET 开发人员,Visual Studio 旗舰版提供了类似的功能,而 Java 开发者可以使用 EclEmma。
6. 测试要快。快速运行、快速编写。开发项目总是面临最后期限,我们的测试必须是促进开发而不是拖后腿。如果测试编写时间太长,那么团队会在最后期限临近的时候停止该项工作。如果测试运行时间太长,那么团队在更改代码时不会保证每次都运行测试。
7. 不会忽略失败的测试。一旦团队开始接受 1 个测试的构建失败,那么他们渐渐地适应 2、3、4 或者更多的失败。在这种情况下,测试集就不再起作用。
8. 结对编程会帮助团队实施测试驱动开发,当首次尝试或者项目期限临近时,我们会下意识地忘记测试,只编写生产代码。结对编程会防止团队偷工减料,持续编写测试。
9. 测试代码简洁。曾经有一次,我们决定测试代码可以不像生产代码那么干净。乍一看,这是个好主意,但是随着软件变化,测试也会发生变化。测试代码会越来越难以维护。
10. 测试应该只测试一个函数或者类,在生产代码开发中,我们要求模块化,对测试代码同样如此。通过这种方式,我们会更容易分析测试的失败点在哪里。
11. 编写单元测试会节省调试时间。大量的时间都花在调试代码中。一旦编写了单元测试代码,你会在开发时得到实时的反馈,容易找到错误。
有关测试驱动开发,资深敏捷测试专家 Lisa 和 Janet 在“敏捷测试指南”一书中也提出了自己的建议,比如“从简单入手”:
作为测试人员,我们很容易被有趣的代码问题和边界情况吸引。但是,如果使用测试指导开发,那么必须从基本的情况开始。编写最简单的常用路径测试以证明核心功能运转正常。为何编写可执行的测试?因为开发日程异常紧张,开发人员和测试人员都没有时间一遍又一遍地停下来运行手动测试。但是,他们有时间点击按钮执行自动化测试。如果测试失败,那么必须能够把失败原因尽可能明确显示出来。理想情况下,我们会把这些测试交给开发人员以便他们在开发时随时执行测试。因此,选择正确的自动化框架非常重要。对于某些故事,自动化测试可能需要很长时间。确保第一个测试简单些,就能集中精力计自动化方案。当简单测试通过时,才值得花时间实施更复杂的测试用例。
一旦常用路径测试通过,那么就可以开始增加更多测试用例,添加边界和极端情况。测试可能会表明开发人员误解了一项需求、或者理解并实现了需求、或者所有人都误解了需求的真实含义。重要的是每个人都在讨论它并保证项目运行在正确的轨道上。在测试人员考虑采用可执行测试验证新场景时,他们也会想到手动探索性测试的潜在场景。把这些都记录下来,以便随后使用。请记住这些测试的目的。它们应该提供实例告诉开发人员编写什么代码。随着编码进展,测试应该更具挑战性,但是请注意克制“立即陷入追踪极端情况”的冲动。先让基本功能运转起来。如果根据风险分析想到了更多用例,可以之后再添加其他测试。
不过,Jim Bird 最近在一篇文章中指出,某些敏捷最佳实践其实可以无需遵循,因为它们不会给你带来太多好处,有时甚至是负面影响,这些“不重要”的实践包括就测试驱动开发:
微软和 IBM 的研究团队发现,虽然 TDD 增加了 15%-35%前期成本(TDD 要求开发人员改变他们的想法和工作方式,这减缓了他们的的开发速度,至少在一开始他们的开发速度慢了很多),但是跟没有采取单元测试的团队相比缺陷密度降低了 40%(IBM)或多达 60%-90%(微软)。
由 Burak Turhan 主导的研究表明虽然 TDD 表面上提高了质量并且可以提高测试的质量,但 TDD 并不能一直提高设计质量。TDD 似乎可以降低代码的复杂度,提高代码的重用率,但是它也能给耦合内聚带来负面的影响。虽然使用测试驱动的开发可以使得方法级和类级的复杂度降低,但包级和项目级却为之变得更加复杂。
评论