接口测试虽然作为版本的一环,但是也是有一套完整的体系,有接口的功能测试、性能测试、安全测试;同时,由于接口的特性,接口的自动化低成本高收益的,使用一些开源工具或一些轻量级的方法,在测试用例开发的成本不高的情况下能去的比较好的测试效果。
开源测试工具Jmeter可以承担接口请求、结果解析和断言的工作,可以作为轻量级接口自动化的实现手段,对于开发能力不强或规模不大的团队也能接受。Jmeter可以在协议层实现基本的功能,包括接口访问、参数化构造、返回值断言和数据库访问,基本足够满足一个轻量级的接口自动化框架的功能。
我们定义一个如下的接口:
入参:
SearchKeys: 我亲爱的你, //用户输入的查询数据,不能为空 PageSize: 10,//分页的Page大小,默认入参为10,前端传入 PageIndex: 1,//分页的PageIndex,第几页,前端传入 OrderBy: 0,//排序条件:0-销量,1-价格,由前端传入,前端的通过单选控件实现 Method: ASC//排序方式:ASC-升序,DESC-降序,前端通过单选控件实现
返回值:
{
"data":
[
{
"CommodityID":"03445f1e-ba55-421d-80fa-1777741bb57e",
"CategoryID":2,
"CommodityName":"双人床solo抽泣",
"Thumb":"http://img4.imgtn.bdimg.com/it/u=1924829949,2185178641&fm=27&gp=0.jpg",
"SalePrice":16.0,
"SaleAmount":13
}
],
"records":1,
"status":true,
"message":""
}
代码处理逻辑:按照分页的页面和大小,从Commodity表一张表中直接查询到对应数据,查询结果进行实例化为Json处理后返回,对应字段均存在Commodity表中,对应数据如下:
测试的思路为,按照实现的业务逻辑,取除了Thumb的字段作为断言字段,并构造SQL进行查询,如果查询到对应数据,则证明接口返回通过。具体构造的SQL如下:
SELECT * FROM Commodity WHERE CommodityID = '03445f1e-ba55-421d-80fa-1777741bb57d' AND CategoryID = 2 AND CommodityName = '我亲爱的你大事不妙' AND SalePrice = 13.0 AND SaleAmount = 130
那么我们需要进行的工作,按照顺序即为访问接口-获取返回值-解析回参-构造SQL-查询-判断结果。整个过程,都能通过Jmeter进行实现,上手起来也比较容易。具体操作过程如下:
一.Http请求:
在测试计划下新增一个线程组,并在线程组下新增一个http请求:
添加Http请求以后,按照下图所示可以设置请求,需要注意的是如果要输入协议,就不要在服务器名称或IP前加http或https了,否则会直接访问到http://http://上去 :
一般来说,接口在访问的时候都需要在验证Header中的身份信息,Jmeter中提供了头信息管理的功能:添加-配置元件-Http请求头管理器:
使用结果树查看接口返回值:添加-监听器-查看结果树,可以明确看到接口的返回报文:、
入参:
PS:Jmeter记录的入参会进行自动URL编码处理,有需要的可以自己做URL解码即可
回参:
这样,我们就完成了一个基本的Http请求的访问。
二.实现参数化
想必大家注意到了,我们之前在通过Http请求构造入参时,对SearchKey这个入参并没有填入之前构造的参入,而是使用了${Key},在Jmeter中,参数的传入就是通过${参数名}的方式进行的。
一般来说,我们测试过程中不一定能保证数据的稳定或需要构造多个不同的参数进行处理 ,很多时候需要考虑做参数化的处理,一定程度上实现动态构造。Jmeter中提供了通过读取本地文件进行参数化的功能:
读取配置文件中的参数:在添加的http请求下添加配置元件-CSV DATA SET CONFIG:
添加CSV 数据配置器后,按照如下设置即可设置参数:
需要调用的时候, 直接使用 ${参数名} 进行调用即可。
三.使用JSON Extractor处理返回值中的Json
通常来说,现在大部分的接口返回值都序列化处理成为Json格式进行返回。虽然使用正则获取返回值也可以,但是Jmeter提供了一个更加方便的插件:JSON Extractor处理Json。
下载插件https://jmeter-plugins.org/wiki/JSONPathExtractor/,下载解压后,把lib里的两个jar拷贝到jmeter的lib目录,lib/ext里面的两个jar拷贝到jmeter的lib/ext目录,重启jmeter即可。
我们以处理以下Json中的CommodityID为例,来获得对应的值:
{ "data": [ { "CommodityID":"03445f1e-ba55-421d-80fa-1777741bb57e", "CategoryID":2, "CommodityName":"双人床solo抽泣", "Thumb":"http://img4.imgtn.bdimg.com/it/u=1924829949,2185178641&fm=27&gp=0.jpg", "SalePrice":16.0, "SaleAmount":13 } ], "records":1, "status":true, "message":"" }
注意到CommodityID在Json数组中,所以Json路径为data[0]["CommodityID"],需要添加Json数组中的索引值 。我们在Json Path Expreeions填入 $.data[0].[CommodityID],这样我们就取出了CommodityID的值;在后续之后,我们就可以通过${CommodityID}的方式调用取出的值。
如法炮制,我们可以取出所有的断言字段。
按照之前的分析,我们可以构造使用断言字段构造一条SQL访问数据库,如果所有的字段都返回正确,那么查询结果应该是不为空的;按照如下的格式,我们就可以构造出我们所需要的断言SQL了:
SELECT * FROM Commodity WHERE CommodityID = '${CommodityID}' AND CategoryID = ${CategoryID} AND CommodityName = '${ CommodityName }' AND SalePrice = ${SalePrice} AND SaleAmount = ${SaleAmount}
接下来,我们只需要使用Jmeter执行该SQL,并对返回结果进行验证,即可实现这个轻量级的接口自动化。
四.使用JDBC访问MySql:
Jmeter提供了JDBC的插件进行数据库访问,但是在此之前,我们需要下载MySql的JDBC驱动包。一般来说,JDBC驱动包版本需要和数据库版本匹配,否则可能因为驱动的关系导致出错。
1.在测试计划下添加,导入对应的JDBC驱动包:
2.添加-配置元件,JDBC Connection Configuration
具体设置如下所示,蓝色框线内的部分一般可以直接使用默认设置,红色框线内需要我们手动填写:
底部的数据库连接字符串填写如下:
DataBaseURL: 数据库连接字符串,使用MySql的同学按照以下格式填写即可:
jdbc:mysql://localhost:2000/AutoTest?useUnicode=true&characterEncoding=utf8 jdbc:mysql://数据库服务器地址:端口号/数据库名,在测试过程中遇到过因为编码问题,查询条件中的中文字符串不生效导致断言结果错误,所以需要添加编码方式,设置的与数据库本身的编码方式相同即可,我使用的是UTF-8 JDBC Driver Class:直接填写com.mysql.jdbc.Driver即可 UserName/Password:连接数据库的账号和密码
3.使用JDBC Request进行数据库操作:添加-Sampler-JDBC Request
JDBC的操作比较简单,我们只需要通过参数名调用设置的JDBC Connection Configuration,然后输入要执行的SQL即可:
添加一个查看结果树,我们就能看到SQL的执行结果了:
构造的SQL:
查询的结果:
五.使用断言验证返回结果:
Jmeter提供了丰富的断言功能,可以用于检查响应数据与预期是否一致,可以用作接口自动化测试的结果校验。对于一次请求,如果通过的话,断言结果中只会打印一行请求的名称;如果失败,则除了请求的名称外,还会有一行失败的原因(不同类型的断言,结果不同),也可以帮助我们定位返回值错误的内容。此外,一个Sampler可以添加多个断言,根据你的检查需求来添加相应的断言,当Sampler下所有的断言都通过了,那么才算request成功。
那么针对这个用例,我们可以把问题简单化:既然数据库返回的查询结果查询到数据就算测试通过,那么JDBC Request的返回值中是一定有我们的传入的参数的,那么我们就可以直接使用基本的文本工具来进行断言的验证,返回结果包含一个或几个断言字段,那么就能断言测试通过了:
添加-断言-响应断言,响应文本中包括关键的参数即可:
那么如果返回结果正确,断言测试通过,结果树中只有一条返回的数据:
如果返回结果错误,那么断言测试失败,结果树中会新增一行失败的原因:
我们构造一个错误的场景,将返回字段中的SaleAmount(销量)返回为SalePrice(价格),那么我们的查询结果为空,返回的断言结果就会是失败的,因为返回值中没有包括传入的CommodityID:
断言失败,因为没有匹配到对应的CommodityID数据。
至此,我们就使用Jmeter完成了一个轻量级的接口自动化测试的用例构造,构造好的用例可以用于后续版本的回归测试。