|
在测试部珠联璧合的大环境影响下,在参加过接口测试的一系列培训和分享之后,在海蕊的鼎力支持下,在蒋壮最初在方向和思路的引导下,我开始在内部流程平台尝试进行接口测试。刚开始我并不知道什么是接口测试,分不清楚和单元测试的区别,现在我的理解是,接口测试是一种思想,单元测试是一个测试阶段,两者的载体可以相同,方法也可以相同,但是侧重点和目的不同,关注的面不同,完成角色不同。目前手上这个项目刚刚接近尾声。在这里,我简单记录一下在这个项目过程中的一点点心得和自己对接口测试的认识。
1.本地环境准备
(1)安装Visual Studio2010
(2)安装TestDriven.NET 3.0
2.需求分析、设计与计划
需求分析阶段,接口测试工程师的工作与功能测试相同,主要有两个目标,一是充分理解需求,二是尽可能找出需求本身的问题,尽可能的减少后期的需求变更。
系统设计阶段,接口测试人员的主要工作:一是从测试的角度为系统设计提交一些方案或建议,并且优化设计,提交系统可测性;二是识别出被测接口,理解被测接口所在的层次,以及被测接口与需求的关联。
接口测试的测试计划制定基本上和功能测试差不多。这个阶段主要要明确有哪些测试资源,测试资源如何分配,在整个测试过程中需要完成哪些事情,每个时间点应该完成哪些事情,还有最重要的也是很容易被忽略掉的一点就是风险评估。
3.测试用例设计和评审
(1)用例设计的思路和方法
设计时需要重点关注接口输入和输出、异常情况。(1)用例要覆盖到所有的输入和输出的组合。(2)针对输入,需要考虑异常情况,比如数据格式、类型、边界、是否允许空等。至于接口内部实现的细节并不是我们需要关注的,所以并不需要去看开发的代码。
(2)接口用例包含的要素
用例标题 – 简要写明测试的关键点,最后对应为测试方法的方法名。
前提条件 – 执行这个用例所必须具备的条件,主要是准备一些数据,并且使这些数据的状态符合要求
输入参数 – 主要是针对接口入参的类型以及是否允许为空的情况进行设计。
执行过程 – 调用被测的接口
预期结果 – 执行接口以后所预期的结果,比如接口调用返回了什么内容,或者接口调用改变了什么内容,需要逐一去验证。如果是异常情况,则需要验证接口是否抛出正确的异常。
4.测试编码与调试
接口测试编码的主要依据测试用例,将测试用例的内容用代码实现出来。主要包括三部分工作:
(1)建立测试项目和环境
这个阶段的主要工作有:
1) 建立工程,并设计好结构。首先建立一个测试项目,并且设计好测试类和其他测试基础类之间的结构关系,一般来说,一个接口对应一个测试类,一个测试用例对应一个测试方法。
2) 引入测试框架,本项目采用的是NUnit,所以要添加对NUnit.Framework.dll的引用,并且在每个测试类中加入using NUnit.Framework语句
3) 引入其他的框架和依赖,比如Castle、NHibernate。这部分工作主要是针对于被测接口,调用被测接口所必须用到的引用。
4) 建立起该工程和待测工程的联系。一般来说,也是两件事,添加对待测项目的引用和using被测接口所在的命名空间。
5) 编写好必要的配置文件。
6) 运行通过一个最基本的测试,验证环境的可用性。
(2)测试类和测试方法编码
1) 建立测试类和测试方法
一个接口对应一个测试类,一个测试用例对应一个测试方法。在NUnit中,测试类使用TestFixture标记,测试方法使用Test标记。
2) 测试方法实现之数据准备
这部分就是将测试用例中前提条件中的内容用代码实现出来,主要内容就是对数据库的增、删、改操作。
操作数据库可以直接写sql语句,也可以采用一些OR映射框架,.NET平台下可以使用的OR映射框架有NHibernate、Castle ActiveRecord、LinQ等。如果使用框架有两种选择,一是调用开发项目中现有API,二是自己提供。使用前者的好处是,现拿现用,减少成本,实体类统一;坏处则是比较被动,如果开发的代码出现问题将导致测试方法运行不起来。自己提供则恰好相反,需要额外创建实体类,编码代码,需要进行类型转换。
从数据准备策略上来说,也有两种方式,一是将数据写在代码里面,二是写在外部文件中。写代码是最简单的方式,写在外部文件,则需要考虑一种良好的结构,以及这种结构的扩展性。
在项目中,我采取了最简单的做法,调用开发的API+硬编码,减少了成本,结果在实际开发过程中,因为开发代码结构的调整,导致底层方法经常不能用,结果测试代码迟迟不能调试。
3) 测试方法实现之输入参数
这部分代码其实和数据准备是结合在一起的,在准备数据的同时,同时定义好接口所需要的入参,并且进行初始化。
4) 测试方法实现之接口调用
接口调用需要用到依赖注入的技术,将接口和接口的实现移到程序外部,比如配置文件,这样使用者只需要关心接口就行了,这个需要与开发统一。开发用的是Castle。使用步骤如下:a) 添加引用;b) 准备配置文件,主要将接口和它的实现注册到容器中;c) 获取接口实例。前两步准备好后,获取接口实例只有一行代码:ITaskService taskService = IoC.GetService<ITaskService>();
d) 调用接口,具体测试哪个接口,就调用哪个。以创建任务为例,taskService.Create(template.Key,request);
5) 测试方法实现之验证结果
a)对于正常流,使用NUnit的断言进行验证。常用的断言有:
Assert.AreEqual()、Assert.AreNotEqual(),测试两个对象是否相等。方法支持相同类型,不同类型,多维数组,嵌套数组,集合类相互比较。
Assert.IsTrue()、Assert.IsFalse()、Assert.IsEmpty、 Assert.IsNotEmpty、Assert.IsNull、Assert.IsNotNull方法分别用于测试某个对象是否正确,错误、(字符串或集合)空、非空,引用为空、引用不为空。
b)对于异常流,因为调用接口执行之后会抛出异常,所以之后的语句不会被执行到,Assert断言就不起作用了。这种情况下,需要使用标记Exception,在具体的测试方法的Test标记后面加上预期的异常类型,例如:Test, ExpectedException(typeof(DataImperfectException))
(3)代码调试
在接口测试执行之前,主要先调通数据准备部分的代码,检验是否按照期望在数据库中准备好了数据。
调试方法:
1)在适当的地方设置断点,选中要调试的测试方法,右击TestWith->Debugger,调试过程中按F11跳到下一行代码,按F5直接跳到下一个断点。
2)使用数据库查询语句直接验证数据库中的内容。
验证结果部分的代码只要会用断言,细心一点基本上没有问题,唯一可能存在预期结果写错的情况,这些可以等接口可测时先执行一遍根据结果再去检查。
5.测试执行
代码调试通过、接口可测时就可以进行测试执行了,使用NUnit的IDE直接运行,执行阶段的产出包括:
产出一:Bug
和功能测试一样,执行失败的用例,需要记录bug反馈给开发。
接口测试bug描述要素:
摘要 — 简要说明主要的错误信息
测试用例 — 即运行失败的测试用例名
被测接口 — 运行失败的接口
错误描述 — 即测试执行失败时的错误信息。
产出二:测试报告和结果分析,包括:测试用例执行情况、代码覆盖率情况、缺陷分布情况等。
后续方向
1.使用CruiseControl.NET工具进行持续集成
2.借鉴iTest优化测试代码结构。优化方面包含几个目标:
目标一:降低耦合,包括测试项目与开发项目之间,测试各个项目之间的耦合
目标二:提取测试基类,提高代码重用性
目标三:测试数据统一管理
3.在内部平台进行接口测试的推广,扩大测试覆盖范围。
4.Mock技术的研究和应用 |
|