常用断言示例
通过后执行脚本执行断言
在Apipost中打开一个接口调试界面,选择后执行脚本,输入以下 JavaScript 代码:
//检查 API 返回的响应代码。如果响应代码为200,则通过,否则失败
apt.test("Status code is 200", function () {
apt.response.to.have.status(200);
});
此代码使用该apt库来运行该test方法,代码里的函数代表一个断言,断言结果可以在响应区——断言与校验中查看。
Apipost可以使用 Chai 断言库 BDD语法
,使用 BDD 链式语法.to.have来表达断言,方便开发者更好的理解断言
点击“发送”后,在响应区一侧的断言与校验
中查看断言结果
想要了解接口的通过和失败时的情况,可以更改断言代码中的状态码code后再次点击发送,如下:
//检查 API 返回的响应代码。如果响应代码为201,则通过,否则失败
apt.test("Status code is 201", function () {
apt.response.to.have.status(201);
});
支持多种方式构建断言,以下代码是实现相同断言的另一种方法expect
:
apt.test("Status code is 200", () => {
apt.expect(apt.response.code).to.eql(200);
});
有关断言语法选项的完整概述,请参阅Chai 断言库文档。
使用多个断言
在后执行脚本中,可以添加多个断言组合起来,对接口进行验证校验
apt.test("The response has all properties", () => {
// 解析响应的 JSON 并校验三个属性
const responseJson = apt.response.json();
apt.expect(responseJson.type).to.eql('vip');
apt.expect(responseJson.name).to.be.a('string');
apt.expect(responseJson.id).to.have.lengthOf(1);
});
有任意一个断言失败,则会返回校验失败,必须全部成功才会返回断言成功
解析响应主体数据
如果想要对响应结果进行断言校验,可以首先将数据解析为断言可以使用的JavaScript对象
解析Json数据,使用以下代码:
const responseJson = apt.response.json();
要解析 XML,请使用以下代码:
const responseJson = xml2Json(apt.response.text());
要解析 CSV,请使用 CSV 解析 实用程序:
const parse = require('csv-parse/lib/sync');
const responseJson = parse(apt.response.text());
要解析 HTML,请使用Cheerio:
const $ = cheerio.load(apt.response.text());
//打印测试的 HTML
console.log($.html());
处理无法解析的响应
如果无法将响应结果解析为 JavaScript,且它的格式不是 JSON、XML、HTML、CSV 或任何其他可解析的数据格式,也可以对其进行断言校验
校验响应正文是否包含字符串:
apt.test("Body contains string",() => {
apt.expect(apt.response.text()).to.include("customer_id");
});
这个断言校验这不会告诉你字符串在响应的哪里,因为它是对整个响应正文进行校验。校验响应是否与字符串匹配(通常仅对短响应有效):
apt.test("Body is string", function () {
apt.response.to.have.body("whole-body-text");
});
对 HTTP 响应进行断言
校验请求响应的各项内容,包括正文、状态码、header、cookie、响应时间等。
测试响应体
检查响应正文中的特定值:
apt.test("Person is Jane", () => {
const responseJson = apt.response.json();
apt.expect(responseJson.name).to.eql("Jane");
apt.expect(responseJson.age).to.eql(23);
});
测试状态代码
测试响应状态码:
apt.test("Status code is 201", () => {
apt.response.to.have.status(201);
});
如果想校验状态码是否为一组状态代码,可以将它们全部包含在一个数组中并使用oneOf
:
apt.test("Successful POST request", () => {
apt.expect(apt.response.code).to.be.oneOf([201,202]);
});
检查状态码文本:
apt.test("Status code name has string", () => {
apt.response.to.have.status("Created");
});
测试header
检查响应标头是否存在:
apt.test("Content-Type header is present", () => {
apt.response.to.have.header("Content-Type");
});
测试具有特定值的响应标头:
apt.test("Content-Type header is application/json", () => {
apt.expect(apt.response.headers.get('Content-Type')).to.eql('application/json');
});
测试 cookie
测试响应中是否存在 cookie:
apt.test("Cookie JSESSIONID is present", () => {
apt.expect(apt.cookies.has('JSESSIONID')).to.be.true;
});
测试特定 cookie 值:
apt.test("Cookie isLoggedIn has value 1", () => {
apt.expect(apt.cookies.get('isLoggedIn')).to.eql('1');
});
测试响应时间
测试响应时间是否在指定范围内:
apt.test("Response time is less than 200ms", () => {
apt.expect(apt.response.responseTime).to.be.below(200);
});
常见断言示例
以下为一些常见断言示例,可能会发现在脚本中很有用,可以按照下方的代码执行,也可以编辑修改以满足自己的需求。
有关可以在断言中包含的内容的更全面概述,请参阅Chai 断言库文档。
针对变量断言响应值
检查响应属性是否与变量(在本例中为环境变量)具有相同的值:
apt.test("Response property matches environment variable", function () {
apt.expect(apt.response.json().name).to.eql(apt.environment.get("name"));
});
校验值类型
校验响应任何部分的类型:
/* 响应内容为以下结构:
{
"name": "Jane",
"age": 29,
"hobbies": [
"skating",
"painting"
],
"email": null
}
*/
const jsonData = apt.response.json();
apt.test("Test data type of the response", () => {
apt.expect(jsonData).to.be.an("object");
apt.expect(jsonData.name).to.be.a("string");
apt.expect(jsonData.age).to.be.a("number");
apt.expect(jsonData.hobbies).to.be.an("array");
apt.expect(jsonData.website).to.be.undefined;
apt.expect(jsonData.email).to.be.null;
});
校验数组属性
检查数组是否为空,以及是否包含特定项目:
/*
响应内容为以下结构:
{
"errors": [],
"areas": [ "goods", "services" ],
"settings": [
{
"type": "notification",
"detail": [ "email", "sms" ]
},
{
"type": "visual",
"detail": [ "light", "large" ]
}
]
}
*/
const jsonData = apt.response.json();
apt.test("Test array properties", () => {
//错误数据为空
apt.expect(jsonData.errors).to.be.empty;
//areas包含了“goods”
apt.expect(jsonData.areas).to.include("goods");
//获取通知设置对象
const notificationSettings = jsonData.settings.find
(m => m.type === "notification");
apt.expect(notificationSettings)
.to.be.an("object", "Could not find the setting");
//detail 数组必须包含 "sms"
apt.expect(notificationSettings.detail).to.include("sms");
//detail 数组必须包含所有列出的元素
apt.expect(notificationSettings.detail)
.to.have.members(["email", "sms"]);
});
顺序.members不影响测试。
校验对象属性
断言对象包含键或属性:
apt.expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
apt.expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
apt.expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
apt.expect({a: 1}).to.have.property('a');
apt.expect({a: 1, b: 2}).to.be.an('object')
.that.has.all.keys('a', 'b');
目标可以是object、set、array或map。如果在没有or.keys的情况下运行,则表达式默认为。由于行为因目标而异,建议在使用with之前检查。.all.any.all.keystypetype.keys.a
校验某个值是否在集合中
根据有效选项列表检查响应值:
apt.test("Value is in valid list", () => {
apt.expect(apt.response.json().type)
.to.be.oneOf(["Subscriber", "Customer", "User"]);
});
校验包含一个对象
检查对象是否是父对象的一部分:
/*
response has the following structure:
{
"id": "d8893057-3e91-4cdd-a36f-a0af460b6373",
"created": true,
"errors": []
}
*/
apt.test("Object is contained", () => {
const expectedObject = {
"created": true,
"errors": []
};
apt.expect(apt.response.json()).to.deep.include(expectedObject);
});
使用.deep会导致链式调用中的.equal
、.include
、.members
、.keys
和.property
断言使用深度相等性(宽松相等)而不是严格相等性(===)。而.eql
也会使用宽松相等性进行比较,但.deep
.equal
会导致任何后续的断言也使用深度相等性进行比较,而.eql
则不会。
校验当前环境
检查当前选定的环境:
apt.test("Check the active environment", () => {
apt.expect(apt.environment.name).to.eql("Production");
});
常见测试错误故障排除
当在使用脚本中遇到错误或意外行为时,控制台可以帮助你快速定位。通过将console.log()
、console.info()
和debug
语句与断言相结合,可以校验 HTTP 请求和响应的内容,以及Apipost数据项(例如变量)console.warn()
、console.error()
。还可以使用console.clear()
方法清除控制台中的信息。
打印变量或响应属性的值:
console.log(apt.collectionVariables.get("name"));
console.log(apt.response.json().name);
打印变量或响应属性的类型:
console.log(typeof apt.response.json().id);
使用控制台日志来标记代码执行,有时称为“跟踪语句”:
if (apt.response.json().id) {
console.log("id was found!");
//执行某个操作
} else {
console.log("no id ...");
//执行另一个操作
}
校验深度相等错误
你可能会遇到AssertionError: expected <value> to deeply equal '<value>'.
例如,以下代码会出现这种情况:
apt.expect(1).to.eql("1");
发生这种情况是因为断言校验正在将数字与字符串值进行比较。仅当类型和值相等时校验结果才会返回 true
。
JSON 未定义错误
可能会遇到ReferenceError: jsonData is not defined
问题。当你尝试引用尚未声明或超出断言校验代码范围的 JSON 对象时,通常会发生这种情况。
apt.test("Test 1", () => {
const jsonData = apt.response.json();
apt.expect(jsonData.name).to.eql("John");
});
apt.test("Test 2", () => {
apt.expect(jsonData.age).to.eql(29); //jsonData没有被定义
});
确保将设置响应数据的代码赋值给变量的部分对所有断言代码都可访问。例如,在这种情况下,将const jsonData = apt.response.json();
移到第一个apt.test
之前会使其在两个断言函数中都可用。
校验未定义错误
可能会遇到AssertionError: expected undefined to deeply equal..
问题。通常,当引用不存在或超出范围的属性时,就会发生这种情况。
apt.expect(jsonData.name).to.eql("John");
在这个例子中,如果你收到错误消息 AssertionError: expected undefined to deeply equal 'John'
,这表示在jsonData
对象中没有定义name
属性。
校验没有失败
有时可能期望校验会失败,但事实并非如此
//断言函数未正确定义 - 缺少第二个参数。
apt.test("Not failing", function () {
apt.expect(true).to.eql(false);
});
请确保你的测试代码在语法上是正确的,然后再发送请求。
校验响应结构
使用 Tiny Validator V4 (tv4) 执行 JSON 模式验证:
const schema = {
"items": {
"type": "boolean"
}
};
const data1 = [true, false];
const data2 = [true, 123];
apt.test('Schema is valid', function() {
apt.expect(tv4.validate(data1, schema)).to.be.true;
apt.expect(tv4.validate(data2, schema)).to.be.true;
});
使用 Ajv JSON 模式验证器验证 JSON 模式:
const schema = {
"properties": {
"alpha": {
"type": "boolean"
}
}
};
apt.test('Schema is valid', function() {
apt.response.to.have.jsonSchema(schema);
});
发送异步请求
在后执行脚本中发送请求并记录响应
apt.sendRequest("https://echo.apipost.cn/get.php", function (err, response) {
console.log(response.json());
});