TDD循环是测试、编码、重构(重复),然后交付。正如TDD名称所示,开发过程是由测试驱动的,具体意思是在开发或编写代码之前
先编写测试。
第一段纯粹是定义性的...从Kent Beck定义TDD...或者维基百科普遍理解TDD...我认为有必要通过这个定义来详细说明,因为我不确定是否每个人都在讨论同一个TDD,或者其他人是否真正理解了TDD定义中最重要的部分或者写测试的含义。换句话说,我认为更多关于这个问题的答案应该深入探讨TDD,而不是解释对UML的偏见。我的回答中较长的部分涉及到我使用UML支持TDD的观点... UML只是一种建模语言,当然不是必须的,如果不适当地应用,它可能会妨碍TDD;但是UML可以帮助理解编写测试所需的要求,如何通过建模进行重构以及如何收集过程的文档来加快发货代码的文档化。我欢迎任何评论、批评或建议,但请不要因为您同意或不同意第一段而投票赞成或反对我的答案...TDD缩写为测试驱动开发,这意味着先测试再开发。
首先编写测试意味着开发人员首先理解规格和要求......显然,任何测试都应该失败,直到编写代码,但在TDD中,必须首先编写测试--在编写测试之前,你不能进行TDD,因为你需要专注于在编写测试和代码之前理解需求规格。有时候根本没有需求;需求获取涉及对预先版本的一些黑客攻击来“扔泥巴看哪个粘住”......这种情况不应与开发混淆,当然也不是测试驱动开发的一种形式,它基本上只是一种针对未充分理解的应用领域进行需求获取的形式。
UML图是TDD的一种需求输入形式。虽然不是唯一的形式,但如果有熟悉创建UML图的人员,则可能比书面规格更好。通常最好使用视觉图表进行更好的沟通,在实现前的需求建模会话中探索问题领域[与用户/客户/其他系统提供商]......在需要模拟性能以真正理解需求的情况下(例如CAN总线网络交互);如果我们可以使用类似Rhapsody或Simulink RT Workshop这样的规范语言或CASE工具,那么最好是可执行、模块化和完整的......UML不一定是TDD的一部分,但它是一个设计综合方法的一部分,在编写任何代码之前更加努力地理解所需内容[然后浪费时间试图将该代码推销给关心的人];通常,更专注于了解系统需求为更高效、更有生产力的敏捷TDD迭代奠定了基础。
Refactoring是关于改进设计的——清理掉工作过且经过测试的代码,使其更简单、更易于维护。您想尽可能地收紧它,以消除混淆的纠结点,这些纠结点可能隐藏了错误或可能在未来版本中产生——您不会因为客户需要而进行重构;您重构是因为发布整洁的代码比继续支付支持/维护复杂混乱代码的成本更便宜。一般来说,大多数TDD更加注重代码方面;但是,您可以使用UML来查看更大范围或退后一步来看问题,例如创建一个类图来帮助识别[缺失的]测试或可能进行的重构。这不是您需要强制执行或普遍采用的事情,而是在适当的地方使用。
最后一步,“发货”是一个严肃的步骤……“发货”不是“把它扔到墙上然后忘了它,因为好的代码不需要支持”或“放弃并希望没有更多迭代”的简写。从财务或商业角度来看,“发货”是TDD中最重要的步骤,因为这是你得到报酬的地方。发货确实涉及“换挡”,因为它包括系统集成、准备支持和维护、为下一轮开发做准备等等。UML图表的主要用途将是以[抽象的术语]传达代码如何完成其工作……UML很有用,因为希望这些图表是需求和开发过程的产物;在代码发货时不必从头开始……作为一种沟通工具,UML适用于减少集成错误的多模块系统、涉及使用不同语言编写的模块的较大项目、需要在安全关键系统上进行协作但需要保护其“专有知识”的嵌入式系统网络。
就像你应该避免在适合使用小螺丝刀的情况下使用大锤子,或者你不会通过要求所有开发人员标准化使用Emacs作为编辑器来取得任何进展。有时候,视野不值得攀登——你不想总是挥舞UML的旗帜或成为那个总是推动UML的人……特别是在没有替代品的情况下编写测试或阅读代码。如果你坚持适当的情况,你就不应该害怕在所有语言有帮助的情况下使用UML作为沟通语言。