`
ldb19890624
  • 浏览: 228181 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

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

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

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

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

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


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

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




[1] Jack W.Reecves. 什么是软件设计. 2002.


分享到:
评论

相关推荐

    TDD 测试驱动开发 文档 详细

    java TDD测试开发流程 包含mekito测试的整套教程。 敏捷开发 适用

    c语言TDD参考代码

    C语言的TDD参考示例代码,主要包含了书中所参考的源代码

    测试驱动开发(TDD)入门讲解及代码实例

    测试驱动开发(TDD)是极限编程的重要特点,它以不断的测试推动代码的开发,既简化了代码,又保证了软件质量。本文从开发人员使用的角度,介绍了 TDD 优势、原理、过程、原则、测试技术、Tips 等方面。 背景 一个...

    微信小程序-微信小程序TDD示例代码

    pages/tennis: tennis题目练习的简易TDD测试程序,只能满足当前tennis的单元测试,而且只有deep equals功能(A === B)的断言 pages/wxassert: 通用的单元测试程序,目前只有deep equals功能(A === B)的断言 pages...

    VS2005单元测试TDD代码

    TDD代码,其中包括如何进行单元测试的代码,VS2005

    TDD单元测试

    TDD 测试

    TDD测试驱动开发(Kent Beck) 讲解代码(C#)

    TDD测试驱动开发(Kent Beck) 讲解代码(C#) 不同种货币计算。

    软件测试中为什么要TDD?

    TDD测试驱动开发。在这两年中,我TDD了几个项目,但不时都有周围的人问我,为什么要TDD呢?开始的时候我就凭着感觉回答了,“用TDD写代码感觉好多了,效果也挺好的”。但随着后面更多的人问并看到他们听到这种回答后...

    TDD测试驱动开发

    TDD 测试驱动开发 测试驱动开发的艺术 Lasse Koskela 带目录结构

    TDD测试驱动开发.pptx

    TDD测试驱动开发.pptx

    重构?测试?TDD?Ant?

    NULL 博文链接:https://ivaneye.iteye.com/blog/365786

    LTE TDD系统原理

    华为LTE TDD系统原理培训PPT文档

    单元测试与TDD实践

    单元测试 TDD EASYMOCK 的一般用法说明 实例

    TDD驱动测试开发培训

    如何基于测试代码驱动目标代码的设计  有效执行单元测试  有效执行集成测试  对发现的缺陷进行变更管理  让测试驱动开发成为需求和开发之间的润滑剂  最后的质量检查方法  产品发布后的测试驱动开发  如何...

    TDD测试驱动开发PDF及源码.zip

    TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。

    基于Javascript的实现一个出租车计价器,使用TDD的方法实现+源代码+文档说明

    基于Javascript的实现一个出租车计价器,使用TDD的方法实现+源代码+文档说明 出租车计价: 不大于2公里时只收起步价6元。 超过2公里的部分每公里收取0.8元。 超过8公里的部分,每公里加收50%长途费。 停车等待时加收...

    TDD(Test-Driven Development)的Demo

    TDD得原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。 TDD得基本...

    TDD-learn-demo2

    我的博客 学习TDD(4)--实例2:基于ZooKeeper的服务器注册和探测类[实战ServerRegister]及 学习TDD(5)--实例2:基于ZooKeeper的服务器注册和探测类[实战ServerDetector] 的配套代码

Global site tag (gtag.js) - Google Analytics