测试驱动开发是否将重点放在设计上?

Dan*_*iel 23 architecture tdd agile

我对TDD的看法很复杂.虽然我相信测试,但我对测试驱动我的开发工作的想法存在疑问.

当您编写代码来满足为接口编写的一些测试时,您可能会将重点从构建可维护代码,从简洁设计和声音架构转移到您.

我有一个问题,没有测试驱动.有什么想法吗?

Jon*_*jap 45

没有.

如果做得好,测试驱动开发是您的设计工具.

我希望您原谅我链接到我自己的博客条目,其中我讨论了测试驱动开发的缺陷,因为开发人员只是将测试视为测试.

在之前的项目中,开发人员使用了一种高度破坏性的单例模式,在整个项目中强制执行依赖项,这在需求发生变化时突破了整个过程:

TDD被视为一项任务,应该被视为一种方法.[...]

没有认识到TDD不是关于测试,而是关于设计.在单元测试中猖獗的单身滥用案例使这一点显而易见:而不是测试作者认为"WTF是这些单身=值; 在我的测试中做的语句?",测试编写者只是将单例传播到测试中.330次.

不幸的后果是,无论采取何种方式,构建服务器强制执行的测试都已通过.

正确的测试驱动开发应该让开发人员高度意识到紧耦合,违反DRY(不要重复自己),违反SRP(单一责任原则)等设计缺陷.

如果您为了通过测试而为测试编写传递代码,那么您已经失败了:您应该努力将测试编写为让您问的路标:为什么这样做?为什么我不能在不依赖其他代码的情况下测试此代码?为什么我不能重用这段代码?为什么这个代码在单独使用时会破坏?

此外,如果您的设计真正干净,并且您的代码真正可维护,为什么为它编写测试并不简单?


Pet*_*jan 13

总是存在过度使用TDD设计或前期设计的风险.所以答案是它取决于.我更喜欢从用户故事/验收测试开始,这是我的测试有助于生成的要求的基础.只有在我建立之后,我才开始编写TDD风格的详细单元测试.如果你所做的唯一设计和思考是通过TDD,那么你冒着太多的自下而上的方法,这可能会给你单独和类别隔离的优秀,但当你尝试将它们集成到用户故事中完成任务时做错了可能会感到惊讶.有关这方面的更多灵感,请参阅BDD.

罗伯特·C·马丁(Robert C. Martin)和詹姆斯·科普利恩(James Coplien)之间已经记录了一场关于此事的伟大"辩论",前者是TDD的倡导者,而后者则声称它破坏了系统的设计.这就是罗伯特关于TDD和设计的说法:

"从99年开始,敏捷社区就有了一种感觉,即架构是无关紧要的,我们不需要做架构,我们需要做的就是编写大量的测试并做大量的故事并快速迭代代码将神奇地组装起来,这一直是马屎.我甚至认为大多数原始的敏捷支持者会认为这是一种愚蠢."

James Coplien表示,仅仅从TDD推动您的设计风险很大:

"在很多项目中,我们看到的很多事情之一就是项目在他们的第3个冲刺点上走向南方,然后他们崩溃和燃烧,因为他们不能再进一步了,因为他们在建筑上已经走投无路.而且你不能重构你的方法因为重构必须跨类类,跨类层次结构,你不再能够保证拥有相同的功能."

此外,他还提供了一个很好的例子,说明如果您使用您的前期知识来驱动架构,那么如果您测试推出银行帐户可能会看起来如何:

"我记得曾经和肯特谈过一次,就在他提出TDD的早期,这是YAGNI意义上做的最简单的事情可能有用,他说:'好吧.让我们做一个银行账户,一个储蓄账户.' 什么是储蓄账户?这是一个数字,你可以添加到数字,你可以从数字中减去.那么储蓄账户是一个计算器.让我们做一个计算器,我们可以证明你可以添加到余额并且从平衡中减去.这是最简单的事情可能有效,其他一切都是这种演变.

如果你做一个真正的银行系统,储蓄账户甚至不是一个对象,你不会从那个重构到正确的架构.储蓄账户是一个过程,它对数据库交易,存款和利息集合以及其他资金转移的审计跟踪进行迭代.这并不是说储蓄账户是某个地方银行货架上的一些钱,即使这是用户的观点,你只需知道在银行系统的基础上有这些相对错综复杂的结构来支持税务人员和精算师以及所有这些其他人,你无法以增量方式获得.那么,你可以,因为银行业当然已经在40年后实现了这一目标.你想给自己40年?这不敏捷."

有趣的是,TDD支持者和TDD对手都说你需要预先设计.

如果您有时间,请观看视频.这是两位极具影响力的专家之间的精彩讨论,而且只有22分钟.


pjz*_*pjz 1

这始终是一个平衡:
- 太多的 TDD,最终会得到可以工作的代码,但工作起来很痛苦。
- 太多的“可维护代码、简洁的设计和健全的架构”,最终会导致架构宇航员陷入编码瘫痪

凡事适度。