TDD,测试代码可以代替文档吗?

  曾经,我认为只要做好详细设计工作,软件编码就成为一种体力活。在我印象中传统软件工程理论好像是这么说得:分析和设计是软件生产过程中最重要的两个阶 段,好的设计产生好的结果,坏的设计产生坏的结果,详细设计文档是软件过程中最重要的部分,甚至比代码还重要。国内某人的书中还提到,“只要有了详细设 计,哪怕原来的开发人员都离开了,换一批人照着详细设计仍然能把软件做完”。一提到详细设计我的脑子里也已经出现了这样的影子:长长的(或者厚厚的)文 档,详细到每个函数,甚至是每个函数参数的名字都定义好了,用这样的详细设计指导代码编写应该是一件多么惬意的事情啊。我推崇这种事无巨细的详细设计,认 为只要是设计好就能够适应变化,并把软件项目的失败归咎与设计人员的知识、能力或经验不足。这种想法持续了很长时间,直到我有了实际软件项目的经验并开始 单独做设计为止。

    促使我思想转变的原因就是两个字:变化。我原来也知道变化对设计的影响,但是还是低估了变化对设计带来的冲击。现实中的详细设计只是一个看上去很美的东 西,开始编写代码一个月后的详细设计就基本上不能指导代码编写了,甚至变成和实际代码完全两回事的东西,成了一堆废纸,原因还是那两个字:变化。是的,变 化,在某个时间已经很缜密的设计,在下个时间就会变得漏洞百出,因为计划赶不上变化,通常情况下,详细设计文档从其完成的那一刻起就开始散发出“腐败”的 味道。只有没有任何软件开发经验的人才会天真地认为一次做好完备的详细设计,然后就可以在其指导下完成软件开发,最终得到产品。

    在传统的软件过程中,面对逐渐散发出“腐败”味道的设计文档,通常有两种对策,一种是安排专职的文档开发人员,每次在代码中修改设计都及时更新到设计文档 中,以保持文档的“新鲜”。其实这种方法也只是一种看上去很美的东西,且不说多数项目组都不会有多余的人手专职做文档开发(有哪个项目组敢在项目还在进行 中就说自己的人手足够了?),就算有这样一个文档开发人员,那么是否每次设计上的小修改都会通知到他(她)呢?显然不会,他(她)必须Review每一个 开发人员的代码,并与大家随时沟通,发现与原始设计不一致的修改,这样会累死人的。那么是否可以由开发人员自己负责维护与自己工作相关的那部分文档呢?试 想一下,当轰轰烈烈地代码编写开始后,或者头顶着产品交付倒计时牌,开发人员是否还有“闲情逸致”时不时停下正在Coding的手去重新修改一下设计文档 呢?另一种对策是任由设计文档慢慢“腐败”,把主要力量集中在代码上,毕竟最终交付产品依靠代码而不是设计文档。这种情况下原来花费大量时间完成设计文档 纯粹是浪费时间,哪怕是对自己人也没有丝毫用处,如果我是这个项目组中补充进来的新人,看到这样的文档和那样的代码,可能会得精神分裂症。

    所以在敏捷(Agile)的词汇表里已经没有详细设计这个词汇了,取而代之的是“够用设计”,就是所谓的Not less not more, just enough。那么在敏捷这种短迭代周期,快速反馈体系中,是否还有必要编写一份用自然语言或图表展示的详细设计文档呢?Jack W.Reecves在他的论文《什么是软件设计?》中提出了“源代码就是设计文档”的观点,Jack说得设计文档和我本文提到的设计文档还不是同一个概 念,我把他的观点引用在这里主要是为了和另一个观点做对比。Jack认为,“任何工程活动的最终目标都是某些类型的文档。当设计工作完成时,设计文档就被 转交给制造团队。该团队是一个和设计团队完全不同的群体,并且其技能也和设计团队完全不同”【1】,由此看来,如果源代码不是文档,那么软件开发人员就不 能被称为是工程师了,他们就和建筑工地上的工人一样,只是一群Builder。是否可以用源代码代替任何用自然语言描述的文档呢?我看还不太可行,源代码 相对于自然语言来说过于晦涩,只有开发人员能够读懂(即便是开发人员,也不是所有人都能理解所有代码),显然制约了源代码作为文档的用途。不是有人在研究 用自然语言编程序吗,如果这样的类似自然语言的源代码作为文档,倒是很合适。

    上文提到,有一个与之对比的观点,那就是用测试代码代替源代码作为设计文档,但是前提条件是:使用TDD作为开发模式。很显然,源代码产生以后做单元测试 用的测试代码已经失去了作为设计文档的前提,那就是每次迭代的设计文档必须早于或不晚于本次迭代的源代码产生出来。因为作为单元测试的测试代码是为已经存 在的源代码量身定做的,并且已经受到这些代码的思维定势影响,失去了“设计”的意义。做为测试先行的TDD本身就是一个分析、设计、实现的过程,而测试代 码又是这个过程的产物,测试代码理所当然的就是设计文档了。加之TDD要求在编写任何代码之前要先完成测试用例,这就是说任何新代码(新加的模块)都有配 套的测试代码,自然而然的,测试代码就成为了新代码的描述文档,其中包含了如何建立使用新模块以及期望达到什么样的效果,而这正式设计文档的主要功能。源 代码不适合取代自然语言的文档,因为源代码过于功能细化,逻辑纷繁复杂,分支和跳转加剧了理解代码的困难,缺乏对整个模块的宏观表达能力。与源代码相比, 测试代码显然“单纯”很多,测试代码侧重于使用源代码,通常可以用作源代码的一份sample,所以它对整个模块的宏观表达能力要强于源代码。另外,测试 代码通常是线性结构,比较容易看懂,从可理解性上看,测试代码比源代码更接近自然语言,因此测试代码比源代码更适合作为软件的设计文档。
    

    那么测试代码是否可以完全取代自然语言形式的设计文档呢?我看还不行,原因有三:
其一,测试代码虽然比源代码容易理解,但它仍然是代码,不是所有人都能理解的;
其二,测试代码的宏观表达能力还是不如自然语言或图表;
其三,很多人习惯看文字而不是看代码,彻底改变人的习惯很难。
所以在TDD开发过程中,比较好的形式是自然语言的文档和测试代码相结合,用自然语言的文档做一个够用的设计就行了,这个设计只要详细到模块关系这一级别就足够了,各个模块的详细设计就由测试代码充当。

    不管是“源代码就是文档”的观点还是“测试代码就是文档”的观点,目的都只有一个,那就是消除那些浪费人力物力做出来的、没用的、总是散发着“腐败”味道的东西。


转自:http://blog.csdn.net/orbit/archive/2008/11/25/3373405.aspx
 
测试驱动的编程是 XP 困扰程序员的一个方面。对于测试驱动的编程意味着什么以及如何去做,大多数人都做出了不正确的假设。这个月,XP 方面的讲师兼 Java 开发人员 Roy Miller 谈论了测试驱动的编程是什么,它为什么可以使程序员的生产力和质量发生巨大变化,以及编写测试的原理。请在与本文相随的 论坛中提出您就本文的想法,以飨笔者和其他读者。(您也可以单击本文顶部或底部的“讨论”来访问该论坛。) 最近 50 年来,测试一直被视为项目结束时要做的事。当然,可以在项目进行之中结合测试测试通常并不是在 所有编码工作结束后才开始,而是一般在稍后阶段进行测试。然而,XP 的提倡者建议完全逆转这个模型。作为一名程序员,应该在编写代码 之前编写测试,然后只编写足以让测试通过的代码即可。这样做将有助于使您的系统尽可能的简单。 先编写测试 XP 涉及两种测试: 程序员测试和 客户测试测试驱动的编程(也称为 测试为先编程)最常指第一种测试,至少我使用这个术语时是这样。测试驱动的编程是让 程序员测试(即单元测试 ― 重申一下,只是换用一个术语)决定您所编写的代码。这意味着您必须在编写代码之前进行测试测试指出您 需要编写的代码,从而也 决定了您要编写的代码。您只需编写足够通过测试的代码即可 ― 不用多,也不用少。XP 规则很简单:如果不进行程序员测试,则您不知道要编写什么代码,所以您不会去编写任何代码。 测试驱动开发(TDD)是极限编程的重要特点,它以不断的测试推动代码的开发,既简化了代码,又保证了软件质量。本文从开发人员使用的角度,介绍了 TDD 优势、原理、过程、原则、测试技术、Tips 等方面。 背景 一个高效的软件开发过程对软件开发人员来说是至关重要的,决定着开发是痛苦的挣扎,还是不断进步的喜悦。国人对软件蓝领的不屑,对繁琐冗长的传统开发过程的不耐,使大多数开发人员无所适从。最近兴起的一些软件开发过程相关的技术,提供一些比较高效、实用的软件过程开发方法。其中比较基础、关键的一个技术就是测试驱动开发(Test-Driven Development)。虽然TDD光大于极限编程,但测试驱动开发完全可以单独应用。下面就从开发人员使用的角度进行介绍,使开发人员用最少的代价尽快理解、掌握、应用这种技术。下面分优势,原理,过程,原则,测试技术,Tips等方面进行讨论。 1. 优势 TDD的基本思路就是通过测试来推动整个开发的进行。而测试驱动开发技术并不只是单纯的测试工作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值