当前位置: 首页 > 科技观察

TDD已死?说说TDD

时间:2023-03-13 05:14:56 科技观察

近年来,“TDD已死”的声音不断涌现,尤其是DavidHeinemeierHansson的文章-《TDD is dead. Long live testing. (DHH)》引发了不小的讨论。其中最引人注目的是KentBeck、MartinFowler和David围绕这个话题举行的一系列对话(辩论)——IsTDDDead?(图片来自:image.slidesharcdn.com/)对TDD的认识比较模糊,大多数人并没有清晰自觉地实施TDD。因此,很多人都有不同的理解。最经典的理解就是基于某个代码单元写一个单元测试,使用Mock等技术,然后用这个单元测试来驱动开发,或者重构修改后帮助回归测试。现在大部分反对TDD的声音都是基于这样的认识,比如:工期紧,时间短,写TDD太费时间;业务需求变化太快,来不及修改功能,来不及写TDD;质量要求很高,一般开发人员不会写;TDD实现最大的问题是大部分程序员不会“写测试用例”和“重构”;由于大量使用Mock和Stub技术,UT没有办法测试集成的功能,对测试业务价值影响不大……总结一下,技术人员拒绝TDD的主要原因是难,工作量大,大量使用Mock导致业务价值难以测试等。这些认识主要是基于片面的认识和实践。在我看来,TDD的核心是:先写测试,用它来帮助开发人员驱动软件开发。首先是先写测试。这里的测试不仅仅是单元测试,也不代表一定要用mocks和stubs来测试。这里的测试是指软件测试本身,可以是基于代码单元的单元测试,也可以是基于业务需求的功能测试,也可以是基于特定验收条件的验收测试。二是帮助开发者,主要是帮助开发者了解软件的功能需求和验收条件,帮助他们思考和设计代码,从而达到驱动开发的目的,所以TDD包括两个部分:ATDD和UTDD。ATDD(AcceptanceTestDrivenDevelopment):验收驱动测试开发。先由BA或QA编写验收测试用例,然后Dev通过验收测试了解需求和验收条件,编写实现代码,直到验收测试用例通过。由于验收方式和类型多种多样,根据验收方式和类型的不同,ATDD实际上包括BDD(行为驱动开发)、EDD(示例驱动开发)、FDD(特征驱动开发)、CDCD(消费者驱动契约开发)等实用方法。例如,如果以软件行为作为验收准则,这就是BDD;如果使用特定实例数据作为验收标准,则为EDD;如果API契约是由WebServiceAPI消费者提出来驱动API提供者开发API,这就是CDCD等。因此ATDD的具体实现需要结合实际选择合适的验收测试方式和类型项目的情况。UTDD(UnitTestDrivenDevelopment):单元驱动测试开发,先Dev写单元测试用例,然后写实现代码,直到单元测试通过。这就是很多人所说的TDD,实用的TDD,喜欢的TDD,抱怨的TDD,但它只是真正意义上的TDD的一部分。让我们来看看David在TDD金字塔上的《TDD is dead. Long live testing》。他主要认为TDD使用了很多mock,导致软件连接数据库后无法测试其功能,从而无法测试其商业价值。其次,他建议使用“Longlivetesting”,但他没有具体说明这种测试是在写代码之前还是之后写,是否会作为客户对软件的验收标准。如果他不这样做,那么他就用“万岁测试”来做回归测试;如果他这样做了,那么他也使用了ATDD,从而使用了TDD。所以他对TDD的理解还是比较狭隘的,认为TDD就是UTDD,导致他写这篇文章来批判TDD。有可能他在实际工作中使用过ATDD,也就是TDD。***看看KentBeck、MartinFowler和David关于IsTDDDead?的辩论,我认为他们说的有道理而且合情合理。原因是他们的背景和行业不同。针对不同的行业、不同的背景,应该选择合适的测试驱动方式(可能会有所不同)。(图片来自:http://t.cn/RiHfT2q)我们先来看看KentBeck。他在Facebook工作,出版了很多书。他可以被定位为在大型IT公司工作的软件思想家。其次是大卫,标准的欧洲帅哥,ROR的创始人之一,Basecamp的创始人兼CTO,Basecamp是一家只有几十人的小型软件公司,所以他的定位可以是创业者和技术人。KentBeck的公司开发大型复杂的商业软件(Facebook平台),代码量巨大,需要很长的时间(几年)和大量的人(几十甚至上百)来开发和维护。DHH开发的中小企业软件(如CRM),代码量一般,需要快速开发和维护(数月),人数少(几人到十几人)。KentBeck在资金和人力资源相对充裕,时间相对充裕的情况下追求代码质量,大量人员的良好协作和稳定的平台。而DHH追求的是以相对较少的资金和人力资源实现客户商业价值的最大化,让一小部分人快速开发出软件卖给客户赚钱。所以在KentBeck所在的环境中,单元测试(UTDD)是非常有价值的;而在DHH所在的环境中,更适合进行功能测试或ATDD。国内很多人对TDD的狭隘理解也来自于很多网上的中文资料。百度百科对TDD的解释就是其中之一:TDD的原理是在开发功能代码之前先编写单元测试用例代码,测试代码决定了需要写什么。产品代码。虽然TDD是敏捷方法的核心实践,但它不仅适用于XP(极限编程),也适用于其他开发方法和流程。但是国外有很多网站对TDD的理解是正确的。比如下图就是一份敏捷问卷。从“Wetakeatest-drivendevelopment(TDD)approach”和“WetakeaTDDapproachattherequirementslevel”可以发现,其对TDD的理解包括UTDD和ATDD。TDD不是灵丹妙药。不要指望它能解决任何问题。不管是UTDD、EDD还是BDD,根据自己项目的实际情况,比如资金、人力资源、时间、组织架构等,做出合理的选择。今天又说到TDD,希望大家重新理解,重新思考和尝试,然后你会发现另一朵云。TDD没有死,死的是你不断的学习、思考、实践和总结。TDD其实已经融入到日常的软件开发工作中,只是很多人还没有意识到。TDD的客观存在和必然存在,将在下一篇文章?介绍。【本文为专栏作者“ThoughtWorks”原创稿件,微信公众号:Thinkworker,转载请联系原作者】点此查看该作者更多好文