我正在努力改进我们小组的开发过程,我正在考虑如何最好地实现与测试驱动开发合同设计.看来这两种技术有很多重叠,我想知道是否有人对以下(相关)问题有所了解:
除非您使用某种代码生成器根据合同生成单元测试,否则是否违反DRY原则才能使用TDD和DbC?否则,你必须在两个地方维持合同(测试和合同本身),或者我错过了什么?
TDD在多大程度上使DbC变得多余?如果我写得很好,那么它们不等同于写合同吗?如果我在运行时以及通过测试执行合同,我是否只能获得额外的好处?
仅仅使用TDD而不是TDD与DbC相比,它更容易/更灵活吗?
这些问题的主要问题是这个更普遍的问题:如果我们已经正确地进行了TDD,如果我们也使用DbC,我们是否会从开销中获得显着的好处?
一些细节,虽然我认为这个问题主要与语言无关:
我们的团队非常小,<10名程序员.
我们大多使用Perl.
S.Lott.. 36
注意差异.
合同驱动的设计.合同驱动设计.
由测试驱动的开发.测试驱动开发.
它们之间的关系是一个先于另一个.他们描述了不同抽象层次的软件.
你去实施时丢弃了设计吗?您是否认为设计文件违反DRY?您是否单独维护合同和代码?
软件是合同的一种实现.测试是另一个.用户手册是第三个.操作指南是第四个.数据库备份/恢复过程是合同实施的一部分.
我看不到Design by Contract的任何开销.
如果您已经在进行设计,那么您可以将格式从太多单词更改为恰当的单词以概述合同关系.
如果您没有进行设计,那么签订合同将消除问题,降低成本和复杂性.
我看不出任何灵活性的损失.
从合同开始,
然后
一个.写测试和
湾 写代码.
看看这两个开发活动是如何交织在一起的,都来自合同.
注意差异.
合同驱动的设计.合同驱动设计.
由测试驱动的开发.测试驱动开发.
它们之间的关系是一个先于另一个.他们描述了不同抽象层次的软件.
你去实施时丢弃了设计吗?您是否认为设计文件违反DRY?您是否单独维护合同和代码?
软件是合同的一种实现.测试是另一个.用户手册是第三个.操作指南是第四个.数据库备份/恢复过程是合同实施的一部分.
我看不到Design by Contract的任何开销.
如果您已经在进行设计,那么您可以将格式从太多单词更改为恰当的单词以概述合同关系.
如果您没有进行设计,那么签订合同将消除问题,降低成本和复杂性.
我看不出任何灵活性的损失.
从合同开始,
然后
一个.写测试和
湾 写代码.
看看这两个开发活动是如何交织在一起的,都来自合同.
我认为DbC和TDD之间存在重叠,但是,我认为没有重复工作:引入DbC可能会导致测试用例减少.
让我解释.
在TDD中,测试并不是真正的测试.它们是行为规范.但是,它们也是设计工具:通过首先编写测试,您可以使用被测对象的外部API - 您还没有实际编写 - 与用户一样.这样,您可以以对用户有意义的方式设计API,而不是以最容易实现的方式设计API.有点像queue.full?
而不是queue.num_entries == queue.size
.
合同中不能替换第二部分.
第一部分可以部分替换为合同,至少对于单元测试.TDD测试用作其他开发人员(单元测试)和领域专家(验收测试)的行为规范.合同还指定了对其他开发人员,域专家的行为,以及编译器和运行时库的行为.
但是契约具有固定的粒度:你有方法前后条件,对象不变量,模块契约等等.也许是循环变体和不变量.然而,单元测试,测试行为单位.那些可能比方法小或由多种方法组成.这不是你可以用合同做的事情.而对于"大局",您仍然需要集成测试,功能测试和验收测试.
DbC还没有涵盖TDD的另一个重要部分:中间D.在TDD中,测试推动了您的开发过程:除非您有一个失败的测试,否则您永远不会编写一行实现代码,您永远不会写一行测试代码,除非你的测试全部通过,你只需要编写最少量的实现代码来使测试通过,你只需编写最少量的测试代码来产生失败的测试.
总之:使用测试来设计API的"流程","感觉".使用合同来设计API的合同.使用测试为开发过程提供"节奏".
像这样的东西:
为功能编写验收测试
为实现该功能的一部分的单元编写单元测试
使用您在步骤2中设计的方法签名,编写方法原型
添加后置条件
添加前提条件
实现方法体
如果验收测试通过,请转到1,否则转到2
如果你想知道Design by Contract的发明者Bertrand Meyer想到将TDD和DbC结合起来,他的小组就有一篇很好的论文,称为契约驱动设计=测试驱动开发 - 编写测试用例.基本前提是合同提供了所有可能情况的抽象表示,而测试用例仅测试特定情况.因此,可以从合同中自动生成合适的测试工具.
我想补充一下:
API是程序员的合同,UI定义是与客户的合同,协议是客户端 - 服务器交互的合同.首先获得这些,然后您可以利用并行开发轨道而不会迷失在杂草中.是的,定期检查以确保满足要求,但在没有合同的情况下永远不要开始新的轨道.而'合同'是一个强有力的词:一旦部署,它永远不会改变.您应该从一开始就包括版本管理和内省,合同的更改只能通过扩展集实现,版本号随之更改,然后您可以在处理混合或旧安装时执行优雅降级等操作.
我从困难的方式中吸取了这一教训,一个大型项目徘徊在永不落地的土地上,然后在严重的枪支,公司生存,短保险时间线下以正确的方式应用它.我们定义了协议,为事务的每一侧定义并编写了一组协议仿真(基本上是固定消息生成器和接收消息检查器,一个晚上值得进行双脑编码),然后分开编写服务器和客户端该应用程序.我们重新组织了节目之夜,它刚刚起作用.要求,设计,合同,测试,代码,集成.以该顺序.重复直到烘烤.
我对TLA的设计有点怀疑.与模式一样,符合流行语的配方是一个很好的指南,但根据我的经验,没有一个通用的设计或项目管理程序.如果你正在按照书本(tm)做事情,那么,除非它是与DOD程序要求的国防部合同,否则你可能会在某个地方遇到麻烦.阅读书籍,是的,但一定要了解它们,然后再考虑你团队的人员.仅由本书强制执行的规则将不会统一强制执行 - 即使在工具强制执行时,也可能存在辍学(例如,svn注释留空或隐藏简短).当工具链不仅强制执行它们而且使得跟随任何可能的捷径更容易时,程序往往会被遵循.相信我,