Daniel's blog

.Net - Just cool!

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  23 随笔 :: 0 文章 :: 108 评论 :: 1 引用

公告

2005年9月26日 #

这里主要想讨论一下单元测试,目前Unit Test越来越被主流开发平台看好,先是Eclipse、NetBeans,现在又是VisualStudio 2005,甚至在Team System中还能施加强制Unit Test的Policy,将来的Weblogic Workshop 9可能也会进行相关集成,业界对此重视程度可见一斑。虽然Unit Test的好处不言而喻,但至今在中国,多数的项目开发仍然不会实施单元测试,即使有实施的,很多也是在外部Policy的压制下被迫进行单元测试的编写,以满足那字面上的测试用例代码覆盖率,真正程序员主动给程序配上单元测试的项目少之又少。其中很重要的一个原因便是多数人认为单元测试极大地浪费了他/她们的开发时间,降低工作效率。其实自从前段时间对XP的实践之后,我能清晰地感觉到Unit Test带来的不仅是软件质量的提升,更是开发效率的提高,这是什么道理呢?看完本文便有答案了。

一个不能忽视的问题是,目前很多软件开发过程中的测试仍然只是随便搞点数据,跑过算数,所谓测试用例的个数毛估估的也是个别现象,我认为这不能算是成功的测试,而且也会为日后项目的进展埋下隐患。说老实话,单元测试并不容易,当然如果我程序的每个类实现的都是加法减法这样的操作,那单元测试或许是相当好写的,可现实世界纷繁复杂的业务逻辑、大量的数据库操作占据了绝对主流,如何进行单元测试呢?

单元测试也有一些原则,首先便是测试先行!无论要实现什么功能,XP的主张:先写测试。在书写测试的过程中,程序员学习并深入了解需要实现的业务逻辑,发现疑问并寻求解答。这是Test Driven Development(TDD)的基本实践,可以避免程序员盲目书写程序代码可能蕴藏的隐患,在没有完全了解或自以为完全了解业务逻辑的情况下写出来的代码很有可能会在将来的某一天被重构或修正掉,与其到那个时候去费工作量,还不如静下心来考虑考虑将要做的程序到底是怎样运作的,有哪些意外情况可能会发生。

其次是无依赖原则,即任何一个单元测试的运行及其结果都不依赖于外部环境,这些环境可能包括操作系统环境变量的配置、数据库中的数据、运行的时间等等。无论何时运行,只要代码不变,结果都应该是一致的。其中接触最多的可能就属数据库了,在单元测试中,开始对代码进行测试之前,首先要准备好测试可能需要的数据,通过把准备数据的代码写入单元测试中,可以达到一劳永逸的效果,一次编写,多次执行,也为自动测试提供了可能。当然设计这些数据往往很费脑筋,要能做出足够量的能测出所有相关业务逻辑的数据并不是很轻松的工作,但也正是在这样的设计过程中,充分考验程序员对需求的认知程度,最大程度避免程序的漏洞和死角。

然后是无踪迹原则,即测试运行前后系统状态保持一致,数据库的数据也不因测试而发生增减,所有测试生成的数据一律删除。这就如同是MGS中的Snake不能留下任何潜入的足迹一样,XP主张单元测试也要不留痕迹,这也是多次自动运行结果一致的重要保障。所以在编写单元测试时,清场的代码千万不可忽视,尤其是那些由正常的业务逻辑代码生成的数据,一定要想办法抓住特征,予以删除。

最后是进化原则,这也是XP的简单教条在测试方面的体现。无论何时都不应期望在一开始就写出面面俱到毫无破绽的测试用例。随着经验的增长,首次测试案例的质量会愈加提升,但在一开始就进行过度测试是不可取的实践。在集成测试中必然会暴露单元测试未能成功捕捉的bug,此时对原先的单元测试进行修改,并通过衰退测试(即用新的测试代码捕捉原有程序的漏洞)验证新的单元测试是有效的。单元测试也和业务代码一样始终处于不断修正、充构、进化的道路上。

说到这里,再来总结一下为什么单元测试提高了开发效率,首先是其一次编写多次自动执行的特征使得准备完善测试数据的工作量得到大大减轻,其次在发生代码重构时,把单元测试全部运行一遍便足以保证重构没有给系统带来破坏性的打击,这种情况下若是没有单元测试,那某些牵一发而动全身的重构或代码修改可能导致的后果就没人能说清楚了,组织人力对所有可能受影响的模块进行人工测试又是另一个庞大的工作量。看似单元测试使程序员多写了很多代码,事实上在很大程度上降低了可能的工作强度,而且使程序员也更为自信,做到面对任何代码修正都心中有底。

当然,单元测试只是测试的一个方面,之后还有界面测试、压力测试等等,我并不想以偏概全,因为自己也曾经吃过光重视单元测试忽视其它测试的苦头,我想说明的是单元测试在目前国内开发实践中的运用还是相当欠缺,而它能解决的问题却是最多的,希望有更多程序员出于自身的需要、发自内心地投入到单元测试的队伍中来。

posted @ 2005-09-26 13:32 Daniel 阅读(859) 评论(1) 编辑

NO.1 Omnicom (天联广告 李岱艾 恒美 浩腾媒体等)

NO.2 WPP集团  (奥美 JWT 达彼思 百帝 电扬 精信 传立媒体 尚扬媒体 迈势媒体 灵立媒体等)

NO.3 IPG集团   (麦肯 FCB 灵狮 优势麦肯等)

NO.4 Publics集团   (盛世长城 李奥贝纳 阳狮恒威 实力媒体 星传媒体等)

NO.5 Dentsu集团  (***广告)

NO.6 Havas集团   (灵智大洋等)

posted @ 2005-09-26 13:04 Daniel 阅读(575) 评论(0) 编辑

重构一词时下颇为流行,各路IDE都纷纷集成Refactor功能,VB.NET的那个Refector插件更是让人眼前一亮,不过在五彩缤纷的重构工具面前,我的想法还是思想起决定性作用,工具只是形式,更何况最有价值的重构是无法通过工具完成的。

首先,为什么要重构?
XP的一条主要原则是简单,而简单意味着代码很难始终适应业务逻辑的变更和程序规模的膨胀,重构是不可避免的。所以重构也是简单原则得以实践的重要保障。积极重构作为XP的重要教条之一,希望程序员在尽可能多的情况下去重构代码,以优化代码的质量,提高代码的可读性和可维护性。例如有些代码在开发初期并没有意识到其公用性,随着项目的进行,发现类似的功能在多处实现,XP的原则是不在最初就去揣测可能的公用方法,直到发现其公用性后再予以抽出,而且是积极地抽出。与此相比,体系架构的重构更为痛苦和繁琐,这就不是单纯能靠Refactor工具所能达成的了。这就引出了下一个问题:如何保证成功地重构?

XP提倡的积极重构由两大基础予以支撑-“勇气”和“测试”。在很多情况下,程序员面对业务逻辑重构往往充满恐惧,不仅因为重构的工作量,同时也存在着对重构之后系统是否仍能够正常工作的担忧,于是乎头痛医头,脚痛医脚,原本逻辑清晰的程序被打上重重补丁,满目疮痍。业务逻辑重构通常牵涉多个代码文件,此时千万不可被可能的重构工作量吓倒,充满勇气推翻先前的代码,并不断告诉自己,长痛不如短痛,今天的重构很有可能会避免日后更大规模的重构,优质的代码就是这样产生出来的。当然,光有心理上的勇气绝对无法造就优秀的代码,更需要技术上的保障,那便是“单元测试”。无论哪位程序员对代码做过什么样的修改,只要最终所有的单元测试都能跑通,那他/她的重构就是成功的。通过单元测试这一有力的基石,为程序员大胆重构给予了现实保障。关于单元测试,下一篇文章中予以详细说明。

XP之所以能达到比较高的代码质量,其重要原因之一便是程序员持续地重构代码,通过持续集成保证不仅代码可以正常运作,而且具有比较高的质素。不过积极重构也并不是在所有场合都适用的。首先,如果开发团队对提高代码质量没有任何兴趣,那重构对他/她们的意义就很小;另一种情况是明天就要交付一个build,完成一次迭代,此时进行重构可能会影响项目的进展,所以XP提出延迟重构,即将重构任务放到下一次迭代中完成,若重构工作量的确很大,甚至可以将重构单独列为一个任务,记如下一次的迭代计划中。

一方面希望程序员能抛开浮躁的开发心情,另一方面也希望项目管理人员、企业能更多地考虑软件的质量而不是单纯的工程周期,始终把维护成本和时间都计算在内,创造一个鼓励重构的大环境。

posted @ 2005-09-26 10:24 Daniel 阅读(748) 评论(5) 编辑