TDD和UML的结合

12

我对TDD方法还很陌生,所以想请一些有经验的人能够给我点建议。我希望了解如何将UML和TDD方法结合起来使用。

我之前的做法是:使用UML进行设计 --> 生成框架类(然后保持同步)--> 实现,最后进行测试。我必须承认测试部分是最糟糕的,因此我开始寻找其他方法 - TDD。我对它有些一般性的了解,但在进一步进行之前,我想知道它与软件设计特别是UML如何结合。

那么当我首次设计/创建测试时,UML如何适应呢?是否可能先设计类,从中创建框架类,再生成单元测试,在实现UML预生成类之前填充这些测试,这种方法会破坏整个TDD吗?还是有其他方法可以将UML和TDD结合在一起?

6个回答

16
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作为沟通语言。


10
如果您在编写第一个测试之前创建一个完整的骨架类,即指所有方法都定义为空,则我认为您并没有进行TDD,并失去了TDD的好处。在我们进行TDD时(即测试驱动设计),我们的测试会逐步引导我们到程序需要的下一个元素——方法和类。如果您预先在UML中预先指定了您的类和方法,那么您的设计已经完成了很大一部分,而您的后续开发要么受到其限制,要么就浪费了精力,而随后的工作将撤消这些努力。
可能有办法同时使用UML和TDD进行设计,但是如您所描述的,您正在UML中进行设计,而TDD从未有机会介入。这将无法使您充分获得TDD的好处。

9

还有其他方法可以将UML和TDD结合在一起吗?

UML和TDD非常适合结合使用:

  1. 在UML中进行初始设计 - 不必完整,只需一致,自包含
  2. 创建空测试。此步骤也可以自动化
  3. 所有测试最初都会失败,这是TDD所要求的(因为从UML生成的代码没有任何代码)
  4. 为每个类编写测试
    1. 如果您对软件架构和UML技能有信心,则从没有太多关联的类开始(不,您不是在做瀑布流,但有时您只知道自己在做什么 - 您已经了解了应用程序域或者在第1步使用了专业知识)
    2. 如果您对应用程序域的理解不确定,则从具有许多关联的类(“中央类”)开始 - 这将使尽早消除错误设计决策变得更容易,因为您将尽早注意到它们
  5. ... 测试仍然失败
  6. 与正在测试的每个单元并行进行(步骤4),在空方法体中编写实现。不要修改任何类,接口或方法名称或参数签名。您只被允许添加私有助手方法,而不能添加更多内容
  7. 如果在步骤6(与步骤4并行运行)中意识到需要在设计中进行更改:
    1. 返回步骤1,完善UML,然后再次生成代码(好的UML工具不会覆盖您的实现)。 注意:避免引入新类。您希望在几周内完成第13步
    2. 重新运行测试并修复之前正常的失败测试
    3. 继续进行步骤6
  8. 如果不是所有类测试都通过,请转到步骤6
  9. 继续进行组件,包和子系统测试
  10. 将部署添加到UML并部署到集成环境(http://en.wikipedia.org/wiki/Development_environment_%28software_development_process%29
  11. 继续进行集成测试
  12. 经历测试/QA阶段
  13. 经历用户验收测试
  14. 根据您的迭代开发过程需要,重复前面的步骤
  15. ... 几个月过去了
  16. 将版本1.0.0部署到生产环境

不要试图在第一步或第一轮迭代(完善设计)中做出太多的设计决策。你希望在几周后的第一次迭代中完成第13步。


8
尽管有些人认为UML是一种设计方法,但它首先是一种沟通工具。因此它被称为统一建模语言。其思想是拥有一种共同的词汇(形状),你可以将其插入书中,每个人都能理解。
另一方面,TDD是一种设计方法,从接口和消费者开始构建系统,然后再添加实现。
一旦您的设计通过应用TDD而出现,您可以使用UML来传达该设计。如果您不需要进行沟通(例如,如果您是唯一的开发人员),则可以说您不需要UML。
有些人认为域分析(识别关键名词、动词和形容词,并构建基本本体模型)是UML方法论的一部分,反映在用例和ER图上......在跳入TDD红/绿/重构周期之前执行这项工作可能很有用。严格来说,这是DDD(领域驱动设计),而不是UML本身。

编写接口、编写测试、开始实现代码,发现自己错过了一些基本的东西,然后你必须更改接口和测试,这可能会更加昂贵。我认为从编写一些UML并从中创建接口中你可以获益良多。 - Cristian Garcia

6
如果您使用UML设计类,那么您正在设计代码的样子。但是,如果您使用TDD创建代码,那么您所创建的就是现实。最好在最后使用UML来记录使用TDD创建的代码结果。

3
@Downvoter:除非你说明了_downvote_的原因,否则你并不重要。 - John Saunders
1
单元测试首先要求开发人员知道该单元需要做什么。因此,将代码的外观确定下来似乎是有用的,这样您至少可以了解每个类的职责可能是什么。如果最终它们变成完全不同的东西,那也没关系。只要不认为它是一成不变的,如果找不到开始的地方,UML似乎是一个很好的方法来启动整个过程。 - Tim Seguine

2

UML是设计的一部分,当然。

我只会在最终使用的系统上使用它。 在UML中渲染测试类对我来说似乎是荒谬的。

我会用它来大致了解我正在创建的内容。 然后我会开始使用TDD来实现它。

至于保持同步,我会获取一个能够导入和导出的UML工具。 我更关心代码,而不是UML。 它对于捕捉您的想法并稍后进行文档记录很有用,但其他方面帮助不大。 我总是更喜欢经过测试的代码而不是图表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接