这两个想法听起来与我非常相似,但可能存在微妙的差异或完全相同的事情,以不同的方式解释.TDD与测试第一开发/编程之间有什么关系?
在驱动因素方面存在差异.
你有一个模糊的想法,关于什么类(或系统 - 这当然可以在不同的尺度上发生)看起来应该是什么样的,然后想出给它提供实际形状的测试?这是TDD.
您是否确切知道该类的公共API应该是什么,并且只是在实现之前编写测试?这是测试优先开发.
我的风格往往是两者的混合.在编写任何测试之前,有时候API应该是显而易见的 - 在其他情况下,可测试性确实推动了设计.
换句话说,TDD以"我想问什么问题?"开头.而非TDD(无论是否先测试)的开头是"我想给出什么答案?"
它们基本上是不同的名称描述相同的东西 - 实际上,五个名称,因为最后的D可以代表设计和开发.
Test First是最初使用的术语,特别是在极限编程的上下文中,用于测试代码重构循环.测试驱动开发这个名称已被提出 - 并且很快被采用 - 后来强调TFD是 - 并且一直是 - 更多的是设计策略而不是测试策略.
显然今天有些人对这两个词有不同的含义,但这不是他们存在的意图,我不会依赖它是常识(因为它不是).事实上,我宁愿将TFD这个词视为已被弃用.
这些术语包括测试优先编程,测试优先开发,测试驱动开发甚至测试驱动设计.澄清几点很重要:
1.测试第一编程(TFP)
术语测试优先编程是编程最佳实践.肯特贝克在他的书"极限编程解释"中重新引入了(如果没有创造出来的话):"在编程之前编写单元测试,并始终保持所有测试运行".因此,在谈论测试优先编程时,我们正在谈论由开发人员编写自动化单元测试,编写代码以满足这些测试.该单元测试堆积并构建一个可以定期运行的自动回归测试套件.
2.测试驱动开发(TDD)
测试驱动开发(TDD)是Kent Beck在他的书"按示例进行测试驱动开发"中介绍的方法的名称.它是一个软件开发过程,它不仅仅是在代码之前编写测试.整本书试图通过模式,工作流程,文化等来解释它.其中一个重要方面是强调重构.
有些人使用术语测试优先开发,测试驱动设计或测试驱动编程......有一件事是肯定的:完善的方法是测试驱动开发,编程技术是测试优先编程.其余的通常是指在代码之前编写测试或错误地引用测试驱动开发或测试优先编程的想法.
TDD = TFD +重构.
当您执行TFD时,您应用一些重构来使代码更通用和更健壮.
在XP(极限编程)这个使测试优先编程和测试驱动开发流行的软件开发过程中,测试优先编程被重命名为测试驱动开发,然后是测试驱动设计.首先编写测试对软件体系结构和软件系统设计有非常积极的影响.
这种对架构和设计的影响是或多或少令人惊讶的同义词的结果:
可测试
解耦
可重复使用
独立可部署
独立发展
独立合理
软件实体只能轻松地重复使用,测试,独立部署,独立开发,或者如果它们分离,则可以单独轻松推理.在实际实施之前编写测试是一种几乎防弹的方法,以确保连续解耦.
这种对软件设计和架构的影响变得如此重要,除了创造者发现值得将其从测试优先编程重新命名为测试驱动开发的其他积极影响.
测试驱动开发这一名称也有助于在接受和正确理解方面更好地推广该方法,因为测试驱动开发这一名称比测试优先编程更强调该方法的整体方面.
不是历史上正确但有用的虽然历史上不正确,但我发现以下区别非常有用:
...是在测试代码之前编写测试代码的测试的任何方法.
...是测试优先编程的一个特定子集,遵循Robert C. Martin描述的测试驱动开发的3个定律:
在您第一次编写失败的单元测试之前,您不能编写任何生产代码.
你不能写更多的单元测试而不是足以失败,而不是编译失败.
您不能编写超过足以通过当前失败的单元测试的生产代码.- Robert C. Martin,测试驱动开发的三个定律
按照这三条规则,您将进入所谓的Red-Green-Refactor循环.你写了一个失败的考试.你让它通过了.现在它通过了,你可以在编写下一个失败的测试之前无情地重构.
请注意,重构安全需要测试.重构意味着在不改变重要行为的情况下改变源代码的结构.但是,我们怎么知道我们没有意外改变重要行为?什么定义了重要行为?这是测试有用的众多内容之一.
顺便说一句,如果你的测试妨碍了重构,你的测试太低级,耦合太紧,也许你使用了太多的嘲弄.
极限编程中的其他有趣的重命名
持续集成 - >持续交付 - >持续部署; 严格来说,它们意味着不同的东西,然而,在XP的精神中,它意味着从一开始就进行持续部署,当人们跳上这个潮流时,人们意识到整合是按字面意思进行的,人们在完成之前就已经停止了.
持续重构 - >持续改进设计; 重构本身并不是达到目的的手段,而是遵循更高的目的.
每周40小时 - >可持续步伐(城市传奇:这一重命名发生在法国软件开发商的抗议之后.)