首先抽象地描述一下项目背景,这个项目是一个面向消费者的Web系统(以下简称系统A)。用户访问系统A,输入数据,系统A 接收数据,然后调用系统B 的REST接口返回处理过的数据给用户。其中系统B 是由另一个团队开发和维护的。描述地够抽象的吧,不过你可以想象,比如一个电商网站。
该项目采用Java,框架是Spring,构建工具是Maven,技术不算很新啦。
好了,要说到自动化测试,肯定得先说说我们是如何按照需求进行开发的。
首先,我们不是按照一份全面的12页的需求说明文档来开发,那样的话,无休止的前期的设计讨论会、数据库设计、代码框架设计、架构讨论会,再加上编码和测试的时间,等全部功能都开发出来都已经是一个月以后了。对我们这个面向消费者的互联网应用来说,一个月太长了。等到一个月以后,这些一个月以前收集的需求和实现的功能,对消费者还有没有价值,都不一定呢。
我们的工作是价值拉动的,所以我们要快速响应变化,我们的哲学是:“先把应用跑起来,完成一小部分可以使用的业务功能,看看反馈再说”。
所以我们按照故事点来划分需求,比如这三天我们开发”登录功能“,这里面包括页面的登录框,页面JS校验,后台逻辑校验,数据库表字段调整,调用系统B 的验证接口等。这样,三天以后,团队能给产品经理/Boss演示“登录功能”,接受产品经理/Boss的反馈,并在第四天开始改进,第五天可以再给产品经理/Boss演示改进后的“登录功能”了。
而不像传统的软件开发方式,团队跟产品经理/Boss说,“一个月以后你才能看到全部功能中的登录功能,到时候你要是不满意,走需求变更流程,需要再等一个月!”。
那么,这个“登录功能”包括页面的登录框,页面JS校验,后台逻辑校验,数据库表字段调整,调用系统B 的验证接口,这些都是可以自动化验证的。页面的登录框我们用Selenium验证,JS校验逻辑我们用Jasmine验证,后台逻辑校验我们用JUnit验证,数据库表字段调整,我们用DBUnit验证,调用系统B 的接口,我们用Mockito来mock接口调用验证。
当开发人员对测试人员说,我们已经开发完成了“登录功能”,测试人员会问,“如何证明你们已经开发完成了登录功能?给我看下你们的自动化测试代码!”
是的,只有通过自动化测试的代码,才能证明功能是正确开发完成的。因为如果没有这些自动化测试,两个星期之后,代码被多处修改,当时写的代码还能不能工作,都不一定呢。
没错,这些自动化测试代码都是开发人员写的。我们的哲学是:“You build it, You test it!”
看到这里,你可能会问,Selenium 验证,Jasmine 验证,JUnit验证, DBUnit和 Mockito 验证,写了这么多的自动化测试代码,该怎么运行呢?
没问题,我们的构建工具是用的Maven嘛,这些测试都有对应的Maven插件,我们把这些测试都集成到了Maven的构建脚本里,这样,在本地命令行,仅仅运行 “mvn clean install” 能挨个运行这些测试了,当运行到Selenium测试时,我们的脚本还会在本地把Jetty服务器运行起来,打开本地的Firefox进行Web UI测试,运行完毕后退出Firefox,关闭Jett服务器。如果中途有测试失败的话,脚本会给出失败提示。
下面是我们项目中实际的自动化测试代码,在powershell中的运行截图:
上图是我们项目目前总共的532个JUnit测试运行结果。
上图是76个Jasmine测试运行结果
那么测试人员如何做测试?
开发人员都开始写自动化测试代码了,那么测试人员干什么呢?
我们是这么做的,测试人员负责故事点的测试策略分析,比如“登录功能”有一个要求是:“密码必须包含字母和数字”。
那么测试人员会事先设计至少三个测试用例:
1)密码全部是字母,不通过
2)密码全部是数字,不通过
3)密码有部分字母,部分数字,通过