接口测试分为人工介入的“手工接口测试”和无人值守的“自动化接口测试 (批量执行)”。无论哪种形式都可以做断言,不过一般我们只会在需要做无人值守的“自动化接口测试”时在接口请求中编写断言Tests脚本。
打开“管理员登录”请求,进入到Tests标签页。
展开“代码生成器”,选择"Status code: Code is 200",自动生成代码
发送请求后,在下半区Response的Test Results查看断言结果
如果你设计了一个反例,比如请求“登录”接口时使用错误的账号或密码进行入参,那么预期结果应该是服务器返回响应码401或者500(视不同的项目,我们这个项目是500),这个时候你需要断言“服务器返回响应码是500”。同样的,还是选择"Status code: Code is 200"自动生成代码(这样做比较快),然后再改一些内容即可:
"Response body: JSON value check"代码生成器生成的是“响应body内容的JSON字符串检查”的预置代码,我们检查“响应headers内容”是要经过进行一些代码修改的,但仍然推荐使用这个代码生成器,因为可以帮我们生成“测试函数”的基础结构体。
打开“管理员登录”请求,进入到Tests标签页。
展开“代码生成器”,选择"Response body: JSON value check",自动生成代码:
// pm是Postman工具的一个对象,提供了测试相关功能。
// pm.test测试函数用来生成一个测试,可以输入测试标题(默认是Your test name),并在function函数内加入各种断言;
// 一个接口请求可以添加多个test测试函数。
// pm.expect断言函数,用来生成各种断言,一个test测试函数里可以只有一个expect断言函数,也可以是多个;
// 如果是多个情况,所有断言函数全部通过才算测试成功,只要某一个断言函数失败,接口测试最终就失败。
// 代码比较长,所以建议自动生成,然后小修小改即可,主要是修改test函数里的内容
// 以下就是一个“测试函数”的基础结构体,里面至少包含“断言函数”
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});
pm.test("检查Headers:Authorization参数的值有内容", function(){
// 下面这句话如果是整个脚本共用的,可以放到函数外
var adminUserToken = postman.getResponseHeader("Authorization")
// 断言adminUserToken包含值(包含值的写法就是一对双引号里什么都别写,包括空格)
pm.expect(adminUserToken).to.include("")
});
接口往往响应报文里的内容很多,不可能去验证所有参数的值(响应报文的参数还有个别名叫做“出参”),所以我们要学会挑选“出参”,根据所测接口背后的功能的业务意义,挑选出1~3个最合适的参数做断言。
选择"Response body: JSON value check"自动生成代码,然后修改后如下:
// JSON断言方式(检查JSON格式的响应报文中的参数名和参数值符合预期结果)
pm.test("Response Body断言:success=true/lastName=超管/roleId=1", function () {
// 获取响应报文的内容并以JSON格式解析,传给变量jsonData
// 前提是,服务器响应报文内容的格式必须支持application/json (可以在响应Headers里查看Content-Type)
// 放心,只要是做接口测试,95%以上的响应报文都是application/json格式 (我为我说过的话负责)
var jsonData = pm.response.json();
// 要检查哪个参数,就直接把下面注释掉的代码的括号里的value替换掉就可以了,填写参数名
// pm.expect(jsonData.value).to.eql(100);
// 然后改eql(100),把预期结果值替换掉括号内的100,
// 比如我要检查success参数的值是true,改动后的代码如下:
pm.expect(jsonData.success).to.eql(true);
// 注:success是参数名不需要加一对引号,
// 而eql()里填写的是断言的参数值,值是需要根据参数的数据类型来决定的
pm.expect(jsonData.lastName).to.eql("超管");
pm.expect(jsonData.roleId).to.eql(1);
});
除了“JSON断言方式”以外,还有多种断言方式,但在实际工作中都不实用,比如介绍一个“文本内容包含的断言方式”感受下:
// 文本断言方式之“包含”:选择"Response body: Contains string",自动生成代码后修改:
pm.test("不推荐的断言方式", function () {
// 断言:整个响应报文内容中包含:"lastName":"超管"
// 真的超级麻烦,需要使用转义符号(\),\"就是转义后的双引号,意思是:我这个双引号是内容里真的含有的双引号
pm.expect(pm.response.text()).to.include("\"lastName\":\"超管\"");
});
// 提取响应头信息中的Authorization
var adminUserToken = postman.getResponseHeader("Authorization")
// 把Authorization值存放到公共环境的变量中
pm.globals.set("adminUserToken", adminUserToken);
// 以JSON格式解析整个响应体报文
var jsonData = pm.response.json();
// 断言HTTP响应码是200
pm.test("HTTP响应码:200 OK", function () {
pm.response.to.have.status(200);
});
// 断言响应头信息:Authorization参数有值
pm.test("检查Headers:Authorization参数的值有内容", function(){
pm.expect(adminUserToken).to.include("")
});
// 断言响应体内容:
// (1) success=true
// (2) lastName=超管
// (3) roleId=1
pm.test("Response Body断言:success=true/lastName=超管/roleId=1", function () {
pm.expect(jsonData.success).to.eql(true);
pm.expect(jsonData.lastName).to.eql("超管");
pm.expect(jsonData.roleId).to.eql(1);
});
接口测试执行速度很快,所以一般情况下我们就一整个项目的接口一起执行掉,即使你仅仅只是想对很少的模块功能进行回归。
RUN ORDER区域是调整运行顺序的,通过接口请求的名称来上下拖动,另外还有三个快捷按钮:
右侧是批量执行策略设置的区域:
当接口请求的入参需要覆盖不同测试数据的时候,比如使用不同的账户名登录,虽然参数值会不同,但是参数名一直是username。一般情况下我们不使用数据驱动技术,因为使用成本较高,如果需要测试三种不同的登录,其实写三个登录接口更快更简单。入参的测试数据需要准备很多不同的数据时,数据驱动测试模式更高效以及接口在以后的可维护性更高
数据驱动测试模式是一种思想,永远先考虑为什么要使用数据驱动技术,如果真的有必要用,必须先设计数据驱动文件
数据文件:
[
{
"caseId": "帐号登录_TC01",
"caseName": "管理员帐号登录",
"username": "admin",
"password": "123",
"httpStatusCode": 200,
"success": true,
"msg": null,
"lastName": "超管"
},
{
"caseId": "帐号登录_TC02",
"caseName": "一般帐号登录",
"username": "test1",
"password": "123456",
"httpStatusCode": 200,
"success": true,
"msg": null,
"lastName": "测试账号"
},
{
"caseId": "帐号登录_TC03",
"caseName": "密码输入错误",
"username": "admin",
"password": "666",
"httpStatusCode": 200,
"success": false,
"msg": "密码错误",
"lastName": null
}
]
进入到Tests标签页,设计和编写数据传递或者断言等代码:
// 从JSON数据驱动文件中根据键名称(key)读取值(value)
var caseId = pm.variables.get("caseId");
var caseName = pm.variables.get("caseName");
var httpStatusCode = pm.variables.get("httpStatusCode");
var success = pm.variables.get("success");
var msg = pm.variables.get("msg");
var lastName = pm.variables.get("lastName");
// 测试函数,把caseId和caseName拼接,做为测试报告标题
pm.test(caseId+":"+caseName, function () {
// 判断HTTP状态码等于JSON数据驱动文件中的对应值(预期结果)
pm.response.to.have.status(httpStatusCode);
// 解析JSON格式的服务器响应体内容
var jsonData = pm.response.json();
// 判断实际报文中的success等于JSON数据驱动文件中的对应值(预期结果)
pm.expect(jsonData.success).to.eql(success);
// 判断实际报文中的msg等于JSON数据驱动文件中的对应值(预期结果)
pm.expect(jsonData.msg).to.eql(msg);
// 判断实际报文中的lastName等于JSON数据驱动文件中的对应值(预期结果)
pm.expect(jsonData.lastName).to.eql(lastName);
});
在批量执行策略设置的区域根据实际情况改变Iterations的值,比如:数据驱动文件中设计了三组测试用例数据,那么Iterations填3;如果数据驱动文件中有三组数据,而Iterations迭代次数填写2,那么数据驱动文件中的第三组数据是使用不到的。如果批量执行器设置的迭代数大于数据驱动文件中的数据组数量,后续的迭代执行全部使用的是数据驱动文件中的最后一组数据:
Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful API风格的Web服务,为接口文档也搭建了一套服务器。