谁在推动软件自动化测试?
做过一个单元测试自动化,我们开发了近百行的测试代码去测试一个代码行为10行的函数;在UI测试自动化,则调用了IE的COM接口去驱动IE application,以模拟在界面上的两个动作,输入“测所”和点击“搜索”按钮,总共9行代码(如果考虑自动化健壮性的话,还要增加错误处理代码)。
观察到这些,我们暂且不考虑自动化测试开发之后的维护,至少可以有一个直观的认识:从手工测试向自动化测试的转变是要付出的成本的,而且这个投入要远比做一次手工测试的代价要高,比如,一个有经验的自动化测试开发人员完成一段健壮的100行左右的测试脚本大概需要一天左右的时间,而手工完成这个功能点的测试则只需要10分钟。一天 VS十分钟,按理说,这是一个赔本的买卖,但为什么还有这么多的软件企业对测试自动化情有独钟呢?排除一些盲目跟风,试图提高测试技术含金量的情感因素,至少有以下几个理性的现实驱动力。
1. 测试自动化主要是做长线投资,而非一时之计
显而易见地,开发一个程序,只为了运行一次自动化测试是非常不划算的。那么要想能收回开发自动化测试的投资,就要尽可能多地运行测试程序,每多运行一次,就会多节省一份手工测试工作量。这个简单的道理可以说明为什么如今测试自动化应用最多的就是回归测试阶段。由于回归测试往往是验证软件bug的fix或者软件补丁的有效性,理论上,每一次bug的修复,都需要进行一次全面回归测试。如下图所示。
这样在软件测试流程里,回归测试包括在测试分支(Test Branch)上进行的bug验证测试,还有在发布分支(Release Branch)上进行的补丁更新测试(在实际的企业实践中,发布分支的更新远远比图中频繁),这样回归测试的重复性就非常高,而且持续时间长,直到软件在市场上的退出才结束。这对于手工测试人员来说,可以说是一个对耐心和毅力的巨大考验,再美好有趣的事情如果天天重复去做,而不做任何变化,最终也会成为枯燥乏味的代名词。所以手工测试人员是有愿望通过自动化测试来改变现状的。这就为回归测试自动化的实施同时提供了主观的动机和客观需求。
【案例】:
一些有经验的软件测试团队通常会采用一些激励或游戏规则来增加回归测试的趣味性,我曾看过一个TOP500的软件企业里的测试部门,每隔一段时间就会由高层发起一个“虫子打猎”(Bug hunting)的活动,通常在一个不太繁忙的周五午后,通知邮件一发出,全体部门立即行动,不论职务高低,不分经理,工程师,纷纷赤膊上阵。为了找到猎物,每人都各显神通,尽可能地设计一些平时想不到的测试场景去寻找软件里的bug,但有一个前提条件,就是他不能测试自己本来负责的系统模块,必须去测试别人的而且他不熟悉的的模块。比如小张是负责测Email的,那他在这次活动中,偏偏就要去测试Messenger;测试messenger的小李这次又要去测试calendar,这完全是一个网状交叉的测试。打猎活动结束后,高层还要召开“庆功会”,评定出“最好的bug”,“最有创意的bug”等等称号,虽然没有奖金,但是每个获得荣誉的人都会倍感自豪。而且,对于团队来说,打猎活动收到成效也是显著的,是一举三得的好事情。
第一,交叉测试会找到以往被忽略的bug。
第二,熟悉不同模块,测试人员将来可以在工作中互为备份。
第三,增强了团队凝聚力,并激发对测试工作的热情。
2. 测试自动化可以随时触发运行
测试自动化一旦开发完成,就可以在任何时间被触发运行,而没有下班或周末的概念,测试人员完全可以在下班之前触发某个自动化开关,把测试任务移交给自动化脚本,然后经过一夜的运行,第二天早上上班来查看自动化测试报告,这是自动化的独特优势所在。从这个意义上讲,测试自动化延伸了手工测试的工作时间和范围。
3. 测试自动化有助于知识的存储和移交
这是一个潜在的事实,在以前的手工测试一统天下的时候,测试人员的知识主要是靠文档存储,比如测试计划,测试案例说明书,bug数据库等等。因此,我们看到,当一个测试工程师离职的时候,他会把他的知识以文档的方式留给原来的团队。而随着自动化测试的发展,这种测试知识的形式也在发生变化,测试人员的技术可以通过测试程序保留下来。对整个测试团队来说,能够量化共享的知识越多,团队就越稳定,受到个体测试人员的影响就越少。这是老板愿意看到的场面,因此,从这个角度来说,测试经理比测试工程师更有动力去推动软件测试自动化。
4. 第三方自动化测试工具的使用提高了自动化测试开发的效率
如果说前三点已经讲清了自动化测试的合理性动机,那么自动化测试工具的应用则为自动化测试实施提供了保障,使得做自动化测试不在那么困难和复杂,而变得简单和有效率。
使用Junit来完成案例一
import junit.framework.TestCase;
public class funTest extends TestCase {
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void testFun() throws Throwable {
//调用被测函数
int i = Fun(2);
//使用junit提供的assert断言语句比较结果
assertTrue(1,i);
}
}
在以上代码中, funTest类,以及funTest类的setup函数和teardown函数(环境回收工作)是由Junit自动生成的,我们写的测试程序只有2条语句,其中断言语句assertTrue会通过比较,给出pass还是fail的结果报告。可以看出,使用Junit工具帮我们减少了自动化测试开发的工作量。
使用QTP来完成案例二,如下:
使用QTP录制同样的google搜索操作,只有两条语句生成:
Browser(”Google”).Page(”Google”).WebEdit(”q”).Set “测所”