1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,浅谈测试驱动开发(,TDD,),Test-Driven Development,TDD,概述,测试驱动开发,简称,TDD,,是一种不同于传统软件开发流程的新型的开发方法。,它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。,这有助于编写简洁可用和高质量的代码,并加速开发过程。,测试驱动开发的基本过程如下:,快速新增一个测试,运行所有的测试(有时候只需要运行一个或一部分),发现新增的测试不能通过,做一些小小的改动,尽快地让测试程序可运行,为此可以在程序
2、中使用一些不合情理的方法,运行所有的测试,并且全部通过,重构代码,以消除重复设计,优化设计 结构,简单来说,就是不可运行,/,可运行,/,重构,这正是测试驱动开发的口号。,写单元测试代码还需要遵循一定的原则,测试隔离。,不同代码的测试应该相互隔离。对一块代码的测试只考虑此代码的测试,不要考虑其实现细节(比如它使用了其他类的边界条件)。,一顶帽子。,开发人员开发过程中要做不同的工作,比如:编写测试代码、开发功能代码、对代码重构等。做不同的事,承担不同的角色。开发人员完成对应的工作时应该保持注意力集中在当前工作上,而不要过多的考虑其他方面的细节,保证头上只有一顶帽子。避免考虑无关细节过多,无谓地增
3、加复杂度。,测试列表。,需要测试的功能点很多。应该在任何阶段想添加功能需求问题时,把相关功能点加到测试列表中,然后继续手头工作。然后不断的完成对应的测试用例、功能代码、重构。一是避免疏漏,也避免干扰当前进行的工作。,测试驱动。,这个比较核心。完成某个功能,某个类,首先编写测试代码,考虑其如何使用、如何测试。然后在对其进行设计、编码。,先写断言。,测试代码编写时,应该首先编写对功能代码的判断用的断言语句,然后编写相应的辅助语句。,可测试性。,功能代码设计、开发时应该具有较强的可测试性。其实遵循比较好的设计原则的代码都具备较好的测试性。比如比较高的内聚性,尽量依赖于接口等。,及时重构。,无论是功能
4、代码还是测试代码,对结构不合理,重复的代码等情况,在测试通过后,及时进行重构。,小步前进。,软件开发是个复杂性非常高的工作,开发过程中要考虑很多东西,包括代码的正确性、可扩展性、性能等等,很多问题都是因为复杂性太大导致的。极限编程提出了一个非常好的思路就是小步前进。把所有的规模大、复杂性高的工作,分解成小的任务来完成。对于一个类来说,一个功能一个功能的完成,如果太困难就再分解。每个功能的完成就走测试代码功能代码测试重构的循环。通过分解降低整个系统开发的复杂性。这样的效果非常明显。几个小的功能代码完成后,大的功能代码几乎是不用调试就可以通过。一个个类方法的实现,很快就看到整个类很快就完成啦。本来
5、感觉很多特性需要增加,很快就会看到没有几个啦。你甚至会为这个速度感到震惊。(我理解,是大幅度减少调试、出错的时间产生的这种速度感),一个生动比喻,盖房子的时候,工人师傅砌墙,会先用桩子拉上线,以使砖能够垒的笔直,因为垒砖的时候都是以这根线为基准的。,TDD,就像这样,先写测试代码,就像工人师傅先用桩子拉上线,然后编码的时候以此为基准,只编写符合这个测试的功能代码。,这个比喻证明了 先写测试代码,然后实现功能的好处。,怎么编写测试用例,测试用例的编写就用上了传统的测试技术。,操作过程尽量模拟正常使用的过程。,全面的测试用例应该尽量做到分支覆盖,核心代码尽量做到路径覆盖。,测试数据尽量包括:真实数
6、据、边界数据。,测试语句和测试数据应该尽量简单,容易理解。,为了避免对其他代码过多的依赖,可以实现简单的桩函数或桩类(,Mock Object,)。,如果内部状态非常复杂或者应该判断流程而不是状态,可以通过记录日志字符串的方式进行验证。,本质和优势,本质:,测试驱动开发不是一种测试技术,它是一种分析技术、设计技术,更是一种组织所有开发活动的技术。,优势:,1)TDD,根据客户需求编写测试用例,对功能的过程和接口都进行了设计,而且这种从使用者角度对代码进行的设计通常更符合后期开发的需求。因为关注用户反馈,可以及时响应需求变更,同时因为从使用者角度出发的简单设计,也可以更快地适应变化。,2),出于
7、易测试和测试独立性的要求,将促使我们实现松耦合的设计,并更多地依赖于接口而非具体的类,提高系统的可扩展性和抗变性。而且,TDD,明显地缩短了设计决策的反馈循环,是我们几秒或几分钟之内就能获得反馈。,3),将测试工作提到编码之前,并频繁地运行所有测试,可以尽量地避免和尽早地发现错误,极大地降低了后续测试及修复的成本,提高了代码的质量。在测试的保护下,不断重构代码,以消除重复设计,优化设计结构,提高了代码的重用性,从而提高了软件产品的质量。,4)TDD,提供了持续的回归测试,使我们拥有重构的勇气,因为代码的改动导致系统其他部分产生任何异常,测试都会立刻通知我们。完整的测试会帮助我们持续地跟踪整个系
8、统的状态,因此我们就不需要担心会产生什么不可预知的副作用了。,5)TDD,所产生的单元测试代码就是最完美的开发者文档,它们展示了所有的,API,该如何使用以及是如何运作的,而且它们与工作代码保持同步,永远是最新的。,6)TDD,可以减轻压力、降低忧虑、提高我们对代码的信心、使我们拥有重构的勇气,这些都是快乐工作的重要前提。,目前最流行的单元测试框架是,JUnit,下面是对,JUnit,一些特性的总结:,1.,提供的,API,可以让你写出测试结果明确的可重用单元测试用例,2.,提供了三种方式来显示你的测试结果,而且还可以扩展,3.,提供了单元测试用例成批运行的功能,4.,超轻量级而且使用简单,没有商业性的欺骗和无用的向导,5.,整个框架设计良好,易扩展,对不同性质的被测对象,,Junit,有不同的使用技巧。,6.,使用断言方法判断期望值和实际值差异,返回,Boolean,值。,7.,测试驱动设备使用共同的初始化变量或者实例。,8.,测试包结构便于组织和集成运行。,9.,支持图型交互模式和文本交互模式。,