测试驱动开发(Test-Driven Development)

1.背景

一个高效的软件开发过程对软件开发人员来说是至关重要的,决定着开发是痛苦的挣扎,还是不断进步的喜悦。国人对软件蓝领的不屑,对繁琐冗长的传统开发过程的不耐,使大多数开发人员无所适从。最近兴起的一些软件开发过程相关的技术,提供一些比较高效、实用的软件过程开发方法。其中比较基础、关键的一个技术就是测试驱动开发(Test-Driven Development)。虽然TDD光大于极限编程,但测试驱动开发完全可以单独应用。下面就从开发人员使用的角度进行介绍,使开发人员用最少的代价尽快理解、掌握、应用这种技术。

2.优势

2.1 先编写测试代码

测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码。

2.2 先考虑代码的使用需求

测试驱动开发就是通过编写测试用例,先考虑代码的使用需求(包括功能、过程、接口等),而且这个描述是无二义的,可执行验证的。

2.3 分解功能

通过编写这部分代码的测试用例,对其功能的分解、使用过程、接口都进行了设计。

2.4 测试代码即是文档

要使用、理解别人的代码时通常又希望能有文档进行指导,而测试驱动开发过程中产生的测试用例代码就是对代码的最好的解释。

2.5 正确性->信心

“代码是否正确?”“辛苦编写的代码还有没有严重bug?”“修改的新代码对其他部分有没有影响?”。测试驱动开发提供的测试集就可以作为你信心的来源。

2.6 迅速定位bug

当然测试驱动开发最重要的功能还在于保障代码的正确性,能够迅速发现、定位bug。

3 . 原理

测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码。也就是说在明确要开发某个功能后,首先思考如何对这个功能进行测试,并完成测试代码的编写,然后编写相关的代码满足这些测试用例。然后循环进行添加其他功能,直到完全部功能的开发。

3.1 V测试模型

3.2 X测试模型

4 . 过程

软件开发其他阶段的测试驱动开发,根据测试驱动开发的思想完成对应的测试文档即可。

1)明确当前要完成的功能。可以记录成一个 TODO 列表。

2)快速完成针对此功能的测试用例编写。

3)测试代码编译不通过。

4)编写对应的功能代码。

5)测试通过。

6)对代码进行重构,并保证测试通过。

7)循环完成所有功能的开发。

5 . 原则

5.1 测试隔离

不同代码的测试应该相互隔离。对一块代码的测试只考虑此代码的测试,不要考虑其实现细节(比如它使用了其他类的边界条件)。

5.2 一顶帽子

开发人员开发过程中要做不同的工作,比如:编写测试代码、开发功能代码、对代码重构等。做不同的事,承担不同的角色。开发人员完成对应的工作时应该保持注意力集中在当前工作上,而不要过多的考虑其他方面的细节,保证头上只有一顶帽子。避免考虑无关细节过多,无谓地增加复杂度。

5.3 测试列表

需要测试的功能点很多。应该在任何阶段想添加功能需求问题时,把相关功能点加到测试列表中,然后继续手头工作。然后不断的完成对应的测试用例、功能代码、重构。一是避免疏漏,也避免干扰当前进行的工作。

5.4 测试驱动

这个比较核心。完成某个功能,某个类,首先编写测试代码,考虑其如何使用、如何测试。然后在对其进行设计、编码。

5.5 先写断言

测试代码编写时,应该首先编写对功能代码的判断用的断言语句,然后编写相应的辅助语句。

5.6 可测试性

功能代码设计、开发时应该具有较强的可测试性。其实遵循比较好的设计原则的代码都具备较好的测试性。比如比较高的内聚性,尽量依赖于接口等。

5.7 及时重构

无论是功能代码还是测试代码,对结构不合理,重复的代码等情况,在测试通过后,及时进行重构。关于重构,我会另撰文详细分析。

5.8 小步前进

软件开发是个复杂性非常高的工作,开发过程中要考虑很多东西,包括代码的正确性、可扩展性、性能等等,很多问题都是因为复杂性太大导致的。极限编程提出了一个非常好的思路就是小步前进。把所有的规模大、复杂性高的工作,分解成小的任务来完成。对于一个类来说,一个功能一个功能的完成,如果太困难就再分解。每个功能的完成就走测试代码-功能代码-测试-重构的循环。通过分解降低整个系统开发的复杂性。这样的效果非常明显。几个小的功能代码完成后,大的功能代码几乎是不用调试就可以通过。一个个类方法的实现,很快就看到整个类很快就完成啦。本来感觉很多特性需要增加,很快就会看到没有几个啦。你甚至会为这个速度感到震惊。

6 . 测试技术

6.1 测试范围、粒度

对那些你认为应该测试的代码进行测试。就是说,要相信自己的感觉,自己的经验。那些重要的功能、核心的代码就应该重点测试。感到疲劳就应该停下来休息一下。感觉没有必要更详细的测试,就停止本轮测试。

测试驱动开发强调测试并不应该是负担,而应该是帮助我们减轻工作量的方法。而对于何时停止编写测试用例,也是应该根据你的经验,功能复杂、核心功能的代码就应该编写更全面、细致的测试用例,否则测试流程即可。

测试范围没有静态的标准,同时也应该可以随着时间改变。对于开始没有编写足够的测试的功能代码,随着bug的出现,根据bug补齐相关的测试用例即可。

小步前进的原则,要求我们对大的功能块测试时,应该先分拆成更小的功能块进行测试,比如一个类A使用了类B、C,就应该编写到A使用B、C功能的测试代码前,完成对B、C的测试和开发。

6.2 怎么编写测试用例

1)操作过程尽量模拟正常使用的过程。

2)全面的测试用例应该尽量做到分支覆盖,核心代码尽量做到路径覆盖。

3)测试数据尽量包括:真实数据、边界数据。

4)测试语句和测试数据应该尽量简单,容易理解。

5)为了避免对其他代码过多的依赖,可以实现简单的桩函数或桩类(Mock Object)。

6)如果内部状态非常复杂或者应该判断流程而不是状态,可以通过记录日志字符串的方式进行验证。

7 . Tips

软件开发过程中,除了遵守上面提到的测试驱动开发的几个原则外,一个需要注意的问题就是,谨防过度设计。编写功能代码时应该关注于完成当前功能点,通过测试,使用最简单、直接的方式来编码。过多的考虑后期的扩展,其他功能的添加,无疑增加了过多的复杂性,容易产生问题。应该等到要添加这些特性时在进行详细的测试驱动开发。到时候,有整套测试用例做基础,通过不断重构很容易添加相关特性。

时间: 2024-11-10 07:08:17

测试驱动开发(Test-Driven Development)的相关文章

测试驱动开发实践 - Test-Driven Development

一.前言 不知道大家有没听过“测试先行的开发”这一说法,作为一种开发实践,在过去进行开发时,一般是先开发用户界面或者是类,然后再在此基础上编写测试. 但在TDD中,首先是进行测试用例的编写,然后再进行类或者用户界面的开发.由于要先开发测试用例,那么开发人员就必须清楚测试的目的,所测功能模块的业务逻辑以及需要测试的场景. 这样TDD确保了项目的代码与所需的业务是匹配的,并且在日后的开发工作中也能确保之前所做的功能的可测试性. 很多同学问TDD是使用那种编程语言,或者是某种技术,这里需要明确的是,T

测试驱动开发实践 - Test-Driven Development(转)

一.前言 不知道大家有没听过“测试先行的开发”这一说法,作为一种开发实践,在过去进行开发时,一般是先开发用户界面或者是类,然后再在此基础上编写测试. 但在TDD中,首先是进行测试用例的编写,然后再进行类或者用户界面的开发.由于要先开发测试用例,那么开发人员就必须清楚测试的目的,所测功能模块的业务逻辑以及需要测试的场景. 这样TDD确保了项目的代码与所需的业务是匹配的,并且在日后的开发工作中也能确保之前所做的功能的可测试性. 很多同学问TDD是使用那种编程语言,或者是某种技术,这里需要明确的是,T

(转)浅谈测试驱动开发(TDD)

测试驱动开发(TDD)是极限编程的重要特点,它以不断的测试推动代码的开发,既简化了代码,又保证了软件质量.本文从开发人员使用的角度,介绍了 TDD 优势.原理.过程.原则.测试技术.Tips 等方面. 2 评论: 李群 ([email protected])www.ihere.org 背景 一个高效的软件开发过程对软件开发人员来说是至关重要的,决定着开发是痛苦的挣扎,还是不断进步的喜悦.国人对软件蓝领的不屑,对繁琐冗长的传统开发过程的不耐,使大多数开发人员无所适从.最近兴起的一些软件开发过程相关

测试驱动开发(TDD)

在编写程序之前,先确定程序中的变量.控件等元素允许的值.若在编写程序时,变量.控件中的值与事先确定的值不相符,就说明程序的某处有bug,这种测试方法就是TDD(Test Driven Development,测试驱动开发).TDD与OpenGL ES一样,只是一套标准或一套API.Android SDK中提供了一套测试框架(JUnit),可用于对Android应用程序进行TDD测试.测试框架的特性如下: Android的测试框架基于JUnit.可在无需调用Android SDK API的情况下测

测试驱动开发与Python

最近在看一本书<Test-Driven Development with Python>,里面非常详细的介绍了如何一步一步通过测试驱动开发(TDD)的方式开发Web项目.刚好这本书中使用了我之前所了解的一些技术,Django.selenium.unittest等.所以,读下来受益匪浅. 我相信不少开发都写单元测试,不过,一般是先写功能代码,然后,再写单元测试用例,在编写单元测试用例的过程中,可能需要调整功能代码,从而使单元测试用例通过.但是TDD就特别要求先写测试用例,后写实现代码.这一开始确

浅谈测试驱动开发(TDD)

1. 优势 TDD的基本思路就是通过测试来推动整个开发的进行.而测试驱动开发技术并不只是单纯的测试工作. 需求向来就是软件开发过程中感觉最不好明确描述.易变的东西.这里说的需求不只是指用户的需求,还包括对代码的使用需求.很多开发人员最害怕的就是后期还要修改某个类或者函数的接口进行修改或者扩展,为什么会发生这样的事情就是因为这部分代码的使用需求没有很好的描述.测试驱动开发就是通过编写测试用例,先考虑代码的使用需求(包括功能.过程.接口等),而且这个描述是无二义的,可执行验证的. 通过编写这部分代码

测试驱动开发(TDD)及测试框架Mocha.js入门学习

组里马上要转变开发模式,由传统的开发模式(Developer开发,QA测试),转变为尝试TDD(Test-driven development,测试驱动开发)的开发模型.由此将不存在QA的角色,或者仅存很少的QA用于系统模块间的集成测试. 因此代码的测试与开发都将由开发者(Developer)来保证. 这就需要借助优秀测试框架的帮助,尤其是支持TDD开发模式的自动化测试框架更为重要,因为我使用的编程是语言是Node.js,那么广泛使用的Mocha.js将成为我的首选. 在团队转型过程中,很多事情

简单了解测试驱动开发---单元测试

The idea is to begin development of a new software unit with its specification, followed by its implementation (which, by definition, must satisfy the specification). 测试驱动开发背后的理念是我们在开发之前定义一个标准(specification), 然后去实现它(implemention),当然实现要完全满足标准. 举一个现实生活

《测试驱动开发》之介绍

本书为<Test-Driven Development By Example>by Kent Beck[America].由人民出版社出版,孙方注释. 以下为学艺不精的我综合英文原文和注释对这本书的翻译.小部分参考了孙平平等人的译本. 介绍 早在星期五,老板到Ward这儿向他介绍一个WyCash的潜在客户,Peter.WyCash是公司正在销售的债券组合管理系统.Peter说,”我对我看到的功能印象深很刻.不管怎么说,我注意到你只办理美元计价的债券.我正在创办一种新的债券,我的战略需要办理不同