在敏捷实践中,“测试”毫无疑问地是一个经常谈论的话题。然而,它也是经常被过分谈论的术语,所以,当我们想讨论“测试的种类”时,应该先了解一些细节。
在敏捷开发中,测试以很多不同的方法扮演着同样的角色,而且不同的测试种类扮演着不同的角色。为了说明这些角色,你需要敏捷开发中一些基本思想作为基础。
为什么要测试?
测试是得到反馈的一个重要方法。测试对于确保代码做了它应该做的事是非常有用的,对于代码的修改反过来可以影响功能也是很有用的。测试也是开发人员知道什么时候算完成他所开发的一个特性。现在,我们有两个原则作为判断一个特性是否被描述的足够详细:
1、开发人员可以提供一个相当准确的估计
2、测试人员可以写出一个接受性测试
不但测试种类有所不同,产生测试的方法也不尽相同。
我们如何测试?
测试包括手工测试和自动化测试。关键要注意在开发过程中,每种技术所扮演的不同角色。尽管我们需要尽可能多地进行自动化测试,但并不意味着所有的手工测试就不再需要啦。因为即使软件通过了所有的自动化测试,它在用户刚开始使用时也可能出现错误。
根据敏捷原则(做聪明的事),要确保能用自动化测试的事情决不要用手工测试。同时要做到适合手工测试的内容决不要花高昂地成本做成自动化测试。另外,不要因为某方面不能自动化测试而不做测试。
你应该做哪些种类的测试?
我想,没有“放之四海皆准”的策略。象敏捷开发中的每个事情一样,测试也需要你用你的大脑!下面有一些测试的种类及它们在开发过程中扮演的角色,或者说是目的。
- 单元测试:一般是开发者在编写他们被分派的特性时建立的。目的是确保代码所完成的功能在任何变化时都是正确的。另外,单元测试的一个附加作用就是当作软件API的使用说明文档。
- 验收测试(或叫接受性测试):用于确保具体的功能是否正常工作。特别地,验收测试是一个具体的客户场景,用于完成用户所期望的功能。
- UI测试:一般包括一些页面流,提供已知输入并把得到的结果和期望的结果进行对照。有些UI测试是使用bitmap进行对比。
- 可用性测试:这可以说是另一个领域的测试,它常常需要人的参与!在这里不多陈述,但是可用性经常是做为“make-or-break”的验收条件。某些项目从自动化测试中得到了收益,这些自动化测试确保软件遵守了UI标准。
- 性能测试:对于很多应用来说,运行一套测试来确保多个非功能度量要求得到满足是非常关键的。如果你的应用需要很严格的性能度量要求,在初始的架构和设计阶段,你需要跟踪这些要求是否满足。在构建整个应用时,你要确保性能要求得到满足。通常,性能测试至少要在每个主构建时自动运行-也许你每星期五做一次或每次迭代做一次。
什么样的测试技术是有用的?
虽然自动化是一个关键,但它并不是唯一的一种测试!我更愿意使用手工与自动化相结合的测试。你可以自己定义自动化测试的频率的执行时间。 下面是几种不同类型的测试以及在敏捷项目中扮演的角色!
- “Smoke”测试:不可缺少的一小撮关键测试,用于确保基本的构建功能正常运行。其中一部分是自动化的,还有一些是手工的。运行“smoke”测试很容易的话,可以帮助开发团队了解每日构建是有用的。当需要一些手工测试时(一般来说成本比较昂贵),应该把它放在主构建中,也就是有质量保证人员参与的较为正试的构建。要避免做代价很大而没有太多意义的“bad”构建。
- Test Harness: 对于粗粒度的功能(特别是对于验收测试和主要的系统场景)进行制度化地测试来说,TestHarness常常是一个好方法。将一个TestHarness作为新的功能加入到原有的测试套装中是很容易的。您可根据捕获的用户输入、正确的输出建立一个TestHarness并使其自动化。每个捕获的测试用例都被加入到测试数据库中,并与后面的回归测试相配合。
- 自动化压力测试“机器人”:如果你做了分层式的架构设计,且各层之间较为有清晰的界线的话,你可以构建一些自动化的测试“机器人”。此时,对于那些基础服务的系统是非常容易地。你可以使用基于XML的配置文件来控制这些测试的运行。你可以执行针对某一层来建立自己的测试,并让它重复执行(UI这一层的部分测试,使用工具也可以做到)。这些测试可以分布在不同的地方进行。这样也就相当于做了非常简单的并发测试。这样做的前提是:让配置文件来控制测试的全过程。
- 手工测试:被认为一定要用手工才能对系统的某个方面进行测试的那部分内容。让测试人员集中精力于那些很难进行自动化测试的复杂的部分。
运行于构建服务器上的所有测试结果都应该以某种总结式的结果描述呈现出来,并可以根据需要对总结进行钻取(drilldown)。一个好的方法就是在Wiki上使用一个特别的位置来显示当前的构建结果。当新一轮的构建完成以后,我们还要发送email通知大家,特别是那些代码中有错误的开发人员,并自动创建需要修改的Bug列表。有很多工具可以帮助我们来实现这个发布过程。
把它们组成一体
一般来说,在开发期间,你应该一起使用手工和自动化两种方式。
- 拿起已定义好的特性(feature)
- 写接受性测试,写代码,写单元测试,写更多必须的代码,然后让测试通过,检入代码。
- 这个特性的性能是关键吗?
- 写性能测试来度量关键点
- 做进一步开发时,应确保测试通过。
- 加入关键点()
- 这个特性有UI要求吗?
- 可能需要一个手工测试来确保可用性,以及自动化测试无法完成的复杂功能测试
- 将接受性测试加入到测试套件(可以使用一个自动化工具)
- 如果这具特性通过了测试以及性能测试(如果有要求的话),你现在可以声称这个特性完成,关闭这个特性,进入下一个特性。
如果你正在使用其它的测试技术,你应该继续使用它们。
持续改进
从一小步做起。不要刚开始就覆盖全过程。这些测试和相关技术只要能够随着时间满足你的需要就可以了。如果你发现了一些Bug,那么应该增加新的接受性测试或单元测试,来阻止这些Bug再次发生。如果用户抱怨系统性能问题,那么再加入一批测试到你的性能测试套件中。这样可以对性能问题生成非常准确的文档,来定位问题所在,一旦开发人员修改了这些问题,用这些性能测试套件再测试一次,看一看效果就可以啦。如果一些测试不值得再去执行,注释掉它们好啦。
问题的关键是:使用你的大脑!
敏捷并非只是方法!
敏捷项目中的测试大深度和方式上有各种变化,但目标不会变化!构建一组由工具、技术、过程和自动化组成的组合工作方式来正确地做那些应该做的正确的测试!
(全文完)