一、简介(Introduction)
你可能已经听说了这个新名词:测试驱动的开发(test-driven development),它在广大、各种杂志和网络中程序员常去的地方都非常流行。它究竟是什么呢?测试驱动的开发是一种方法理论,它强调把测试作为开发过程的一个主要部分。要是关心程序质量的话,在部署之前前就应该测试。几乎所有人都使用某种方法进行测试,所以你可能会问:测试不已经是开发过程的一个部分了吗?测试驱动的开发要让测试成为开发过程的主要部分。
二、手工测试(Manual Testing)
早期的软件开发时,许多人的测试方法就是运行程序,通过手工操作来指定输入然后观察输出。现在还有很多软件的开发继续着这种方式。它有一个关键的优点:非常容易学习和理解。如果你有键盘和鼠标,并且会操作图形界面,你就可以测试任何桌面应用。如果你有浏览器,你还可以测试应用。这根本谈不上什么技巧,你可以认为所有开发人员都能做到。手工操作时你看到的应用和最终用户看到的完全相同,这也是一个不错的主意,但并不是真正的优点,因为其它的测试方法也能做到。
手工测试的缺点就实在太多了:
手工测试需要反复进行。每一次修改程序,不管是增加新特征,改变已有行为,还是修改bug,你都必须重新测试被影响的部分,才能保证你增删改的代码不会造成破坏。
手工测试可能带来错误。人类不适合作重复性的工作,特别是这个工作还很烦人的话。人类经常忽略细节,这会导致代码被破坏。更可能造成的问题是:修改这个地方,可能会影响到另一些代码的行为,尽管它们的关系不是很明显。因此,即使你作了非常认真负责的测试,那也只限于你认为修改可能影响到的部分,你还是有可能会在其它地方漏掉一些bug或被破坏的功能,不是因为你不够仔细,而是因为软件开发是综合性的工作,软件的各个部分常常有关联,在现在的软件项目中,任何人都不可能详细了解某段代码所有的依赖和被依赖关系。
手工测试无法对不可视组件进行单独测试。如果你只测你能看到的,那你就没测你看不到的。这看上去是非常简单的一个命题,但它的意义重大。软件是复杂的,为了定位和解决错误或被破坏的代码,大量形态各异的bug需要通过“剥茧抽丝”式的测试去分析每一个组件的行为。对于端软件尤为如此。服务器端程序中,几乎所有的重要代码都在逻辑层,如基于web的程序。表示层测试只能间接的测试业务逻辑,可能忽略某些细节。你当然希望逻辑层和表示层都能很好的工作,但逻辑层正常工作是整个应用能正常运行的基础。
如果你的测试是手工进行的,别人就没法判断你的程序功能是否正确。其他人(例如其他开发人员或者甚至是最终用户)只能接受你的承诺:你作了测试,各方面都满足需求。除了你的书面或口头声明保证你对程序作过测试它满足所有可视的检查外,其他人没办法验证功能正确,除非他们自己辛苦的作一遍测试,但这个工作可能并不适合他们,因为他们不熟悉程序的边界条件和逻辑。
三、自动测试(Automated Testing)
自动测试解决了手工测试的不足。因此,要回答“除了软件开发中一直在做的那些事情外,测试驱动的开发到底意味着什么?”这个问题,测试驱动的开发在整个开发过程中引入自动测试,并不断改进这些测试以适应程序代码的扩展。注意这中间的两个要点,第一,测试是自动的表示它不但可以重复进行,还要很方便移植,可重复是指你可以一遍又一遍的对同样的代码进行测试,并且每次都得到同样的结果;方便移植是指别人可以使用你的测试,自己来验证你的程序是否能通过这些测试。第二点要求测试的改进包含到程序本身代码的改进中,测试落后于代码可不是件好事,因为这样测试就不能真正的验证程序功能正确与否,因此测试代码需要与应用本身的代码保持同步前进。
软件的自动测试有两个主要方法。第一个是通过可重现的recorded macros。Mercury Interactive (http://www.mercuryinteractive.com/products/winrunner/) 的WinRunner等就是用的这种方法。尽管很容易建立,但宏是很不稳定的,需要经常修改,因为它们通常依赖于按钮和组件的物理位置,而不是在parsed document中的结构位置。对开发人员来说,测试框架不管是产生不正确的错误信息,还是需要大量的工作才能保持和代码同步,都是非常痛苦的事情,
原文转自:http://www.uml.org.cn/Test/200911101.asp