公务员期刊网 论文中心 正文

TDD测试驱动在软件工程中的辩证思考

TDD测试驱动在软件工程中的辩证思考

摘要:TDD测试驱动开发模式本世纪初兴起以来,一直在争论中前进发展,支持者奉其为圭臬,反对者弃之如敝履。客观来说,TDD模式自有其优势,也有其问题,在多年的开发实践中,提出了一系列分支开发模式。在软件工程开发实践中,一方面,要辩证的看待该技术模式的优缺点,不能偏听偏信;另一方面,也要根据自身项目的组织结构、资金配置、人力资源、时间要求来选择开发模式.

关键词:TDD;测试驱动开发;软件工程

TDD全称TestDrivenDevelopment,中文翻译为测试驱动开发,上世纪九十年代中后期发起于敏捷开发(AgileDevelopment)思想中的极限编程(Extremeprogramming)理念。由KentBeck在2002年出版的《TestDrivenDevelopment:ByExample》和DavidAstels在2003年出版的《Test-DrivenDevelopment:APracticalGuide:APracticalGuide》共同奠定了TDD的理论基础和实践模型。从正式提出至今,TDD模式一直存在着两种不同的应用观点。一种观点认为TDD模式是一种软件工程规范而不是简单的技术验证,换而言之,TDD的基本思路就是通过测试来推动整个开发的进行,并不只是单纯的测试工作。另一种观点认为TDD是一种编程技术,目标是编写干净的代码,极限编程三位创始人之一的RonJeffries(另两位是KentBeck和WardCunningham)是这种观点的主要支持者。这两种观点并没有绝对的对与错,在生产、教学实践中体现出了它们在不同条件、环境下各自的价值。2004年DavidAstels的《TestDrivenDevelopment:ByExample》被翻译成中文,TDD模式开始在我国传播,并在2006年-2010年受到了计算机学界和信息产业界的普遍关注和广泛讨论。在这场实践检验理论的讨论中,学界和大企业普遍对TDD模式持认可态度,而中小企业普遍表示这种模式并不切实际。2011年,朱少民撰文《敏捷测试的思考和新发展》提出,TDD实践还存在较大困难,有比较多的争议,TDD模式进一步向ATDD、BDD等模式适应性转型,并提出测试开发模式应向本源回归,不拘泥于某种单一模式,应该持续质量反馈、持续改进方法、不断解决问题。2014年,DavidHansson(RubyonRails与Instiki的创始人),在自己的个人网站发表文章《TDDisdead.Longlivetesting.》否定TTD模式在软件工程领域的实践意义,从而引发了大量的讨论直至今天。下面关于TDD模式的优势和问题,我们通过正反两方面辩证的来分析思考,应该就能够对TDD模式有一个更加理性和准确的认识。

1TDD的理论模型和优势特性

1.1TDD的理论模型

TDD模式在理念上是以用户需求为导向,通过各级各类测试确保所有的需求都能被照顾到,在代码不断增加和重构的过程中,检查所有的功能是否正确。从开发流程上来说,首先根据需求编写一个测试,此时因为没有实现该功能,所以运行这个测试可预知其失败。然后编写最少量的代码不断迭代重复,直到测试通过为止。最后,根据简单代码的重复情况和代码之间的合理结构,考虑是否需要重构代码。简而言之,TDD是戴两顶帽子思考的开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码质量。测试驱动着整个开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。

1.2TDD的优势特性

1.2.1TDD在客观上提升了代码的质量

技术人员编写刚好满足需求又能通过测试的代码,将代码量和代码本身的出错概率降至最低,客观上保证了代码的质量。

1.2.2TDD在主观上要求了需求和开发的一致

测试是以业务需求为导向,促进了技术人员和业务客户之间的交流,所有需求测试能够通过,也即说明业务功能全部满足。

1.2.3TDD在构架上保证了简洁高效的类、库和API

由测试导向的功能调整,使得所有类、库和API都在围绕快速实现功能来设计,并且实现后马上测试,各项设计能够马上进行调整。

1.2.4TDD在开发上促进了代码优化重构

通过各层级的测试,有助于从系统中清除大量累计产生的寄生代码,整个开发流程在测试、通过、重构之间循环流转,螺旋渐进式的修正保证了代码不断优化重构,并且避免了递归错误的出现。

2TDD的实践问题和发展方向

2.1TDD的实践问题

以上关于TDD相对于传统软件工程开发先写功能再写测试的模式,无疑是具有先进性的,但是事物的两面性告诉我们,TDD模式也不是那么美好,更不是免费的午餐。在IT行业的生产实践中,特别是小微企业的实际开发工作中,很多程序员们抱怨——“自从用了TDD,工作量更大了”。TDD模式对于技术人员,有太多难以确定的问题,导致TDD模式难以使用、难以推广,理论强、实践弱的问题比较突出。

2.1.1测试本身难以确定

TDD是以需求为导向来确定测试,再以测试来规范功能开发。这里的问题就在于在开发工作中,业务需求是不确定的,开发最大的问题恰恰是很多时候客户自己都不确定需要什么样的功能,大部分情况是由技术人员做个初略样品,再由客户提出修改意见,如此反复迭代,甚至客户自己会经常性推翻自己前期的需求,造成业务需求无从确定,也导致测试本身的确定就是个问题。

2.1.2测试范围难以确定

TDD既然是测试规范功能,那么测试范围就非常重要,太大会导致不知道错误在哪,太小会导致测试变成了对应的功能模块,改改就能用,那还要测试干什么。所以好的TDD要求技术人员具有完备的测试用例的能力,这项能力需要丰富的理论与长期的实践,换而言之,能把TDD用好的人基本上是IT行业的高水平专家。那么这里出现了第一个模式悖论,如果使用门槛这么高、上手难度那么大,那么对于广大中小技术团队、技术人员,TDD的推广意义在哪里。

2.1.3测试目的难以确定

从表面看TDD测试的目的显然是为了实现功能开发,满足业务需求,而在实际工作中,由于TDD强调以最少的代码以满足测试通过的思路,很容易致使测试通过成为测试的目的。当大量的修改扑面而至,测试通过成为验证修改完成的主要指标,那么为了测试而测试,就会取代为了功能而测试。

2.1.4测试方向难以确定

在传统的软件开发瀑布流模式中,开发方向自上而下,一环扣一环,每一个环节都依赖于前面那个环节的正确性。那么TDD的方向只能依赖于不断变化的需求,既然前置条件就是需求在不断变化,那么谁也确定不了后期的方向会和前期的方向一致,换个角度说,就是谁也无法保证前面的测试会适用与后面的功能。

2.2TDD的发展方向

TDD模式在理论的美好和实践的困难这对矛盾中不断发展,为了增强其适用性和易用性,TDD逐步发展为ATDD与UTDD两个分支模式。通不过不断深化和细化测试模式,TDD已经不再是一种技术标准,更体现了其业务规范的一面,也不再是一种方法,而更多的是一种在软件开发过程中的模式理念,构成了一套更符合实际需求、更容易实践掌握的敏捷测试框架。

2.2.1ATDD(AcceptanceTestDrivenDevelopment)

验收驱动测试开发,首先业务分析师或者测试工程师根据客户需求编写验收测试用例,然后开发人员通过验收测试来理解需求和验收条件,并编写实现代码直到验收测试用例通过。由于验收方法和类型也是多种多样的,所以根据验收方法和类型的不同,ATDD其实是包含以软件的行为为验收标准的BDD(BehaviorDrivenDevelopment)、以特定的实例数据为验收标准的EDD(ExampleDrivenDevelopment),以特征模型为验收标准的FDD(FeatureDrivenDevelopment)、以WebServiceAPI消费者提出API契约来驱动API提供者开发API的CDCD(ConsumerDrivenContractDevelopment)等各种的实践方法。

2.2.2UTDD(UnitTestDrivenDevelopment)

单元驱动测试开发,首先将测试分为整体功能测试和功能模块单元测试,编写一个功能测试,“编写代码让它通过”:编写一个或多个单元测试,然后进入“单元测试/编写代码”循环,直到单元测试通过为止。然后回到功能测试,查看是否有进展,这一步还可以多编写一些应用代码,再编写更多的单元测试,如此一直循环下去。

3结语

纵观对TDD模式近十年来的争论,也可以看成是理论派和实践派之间的争论,是大中企业和小微团队之间的分歧,更是无限神话和一味贬低之间的矛盾。技术、市场、需要一直在进步和变化的当下,任何一种开发理论、开发模式都不可能“一招鲜吃遍天”,盲目的吹捧某种技术神而明之,或一概否定某件事物的进步之处,都是不实事求是的表现。TDD模式当然不是万能钥匙,一用就能马上解决软件开发中的任何问题,一种技术、理念、模式,只要它能够不断的发展、变革、修正,我们就应该看到它先进的地方和不足之处。至于某个具体项目需要什么样的开发模式,则要根据软件工程项目的资金、人力、时间、组织等实际情况,进行合理的选择。

作者:谢宇飞 彭霖 单位:江西应用技术职业学院