使用您的请求、文件夹和集合中的“测试”选项卡来编写测试,这些测试将在 Postman 收到来自您发送请求的
API 的响应时执行。为每个请求添加您需要的许多测试。当您将测试添加到文件夹或集合时,它们将在其中的每个请求之后执行。
开始测试
要编写您的第一个测试脚本,请在 Postman 应用程序中打开一个请求并打开“测试”选项卡。输入以下
JavaScript 代码:
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
|
此代码使用pm库来运行该test方法。文本字符串将出现在测试输出中。测试中的函数代表一个断言。Postman
测试可以使用Chai Assertion Library BDD语法,它提供了优化测试对您和您的合作者的可读性的选项。在这种情况下,代码使用
BDD 链to.have来表达断言。
此测试检查 API 返回的响应代码。如果响应码为200,则测试通过,否则失败。选择发送并转到响应区域中的测试结果选项卡。
尝试更改断言代码中的状态代码并再次发送请求,以查看测试结果在通过或失败时的显示方式有何不同。
以各种方式构建您的测试断言,以适应您希望结果输出方式的逻辑和偏好。以下代码是使用expect语法实现与上述相同测试的另一种方法:
pm.test("Status code is 200", () => {
pm.expect(pm.response.code).to.eql(200);
});
|
有关断言语法选项的完整概述,请参阅Chai 断言库文档。
使用多个断言
您的测试可以包含多个断言作为单个测试的一部分。使用它来组合相关的断言:
pm.test("The response has all properties", () => {
const responseJson = pm.response.json();
pm.expect(responseJson.type).to.eql('vip');
pm.expect(responseJson.name).to.be.a('string');
pm.expect(responseJson.id).to.have.lengthOf(1);
});
|
如果任何包含的断言失败,则整个测试将失败。所有断言必须成功才能通过测试。
解析响应正文数据
要对您的响应执行断言,您首先需要将数据解析为您的断言可以使用的 JavaScript 对象。
要解析 JSON 数据,请使用以下语法:
const responseJson = pm.response.json();
|
要解析 XML,请使用以下命令:
const responseJson = xml2Json(pm.response.text());
|
如果您正在处理复杂的 XML 响应,您可能会发现控制台日志记录很有用。
要解析 CSV,请使用CSV 解析实用程序:
const parse = require('csv-parse/lib/sync');
const responseJson = parse(pm.response.text());
|
要解析 HTML,请使用cheerio:
const $ = cheerio.load(pm.response.text());
console.log($.html());
|
处理不解析的响应
如果您无法将响应正文解析为 JavaScript,因为它没有格式化为 JSON、XML、HTML、CSV
或任何其他可解析的数据格式,您仍然可以对数据进行断言。
测试响应正文是否包含字符串:
pm.test("Body contains string",() => {
pm.expect(pm.response.text()) .to.include("customer_id");
});
|
这不会告诉您在哪里遇到字符串,因为它对整个响应正文执行测试。测试响应是否与字符串匹配(通常仅对短响应有效):
pm.test("Body is string", function () {
pm.response.to.have.body("whole-body-text");
});
|
对 HTTP 响应进行断言
您的测试可以检查请求响应的各个方面,包括正文、状态代码、标头、cookie、响应时间等。
测试响应体
检查响应正文中的特定值:
pm.test("Person is Jane", () => {
const responseJson = pm.response.json();
pm.expect(responseJson.name).to.eql("Jane");
pm.expect(responseJson.age).to.eql(23);
});
|
测试状态码
测试响应状态码:
pm.test("Status code is 201", () => {
pm.response.to.have.status(201);
});
|
如果您想测试状态代码是否是一组中的一个,请将它们全部包含在一个数组中并使用oneOf:
pm.test("Successful POST request", () => {
pm.expect(pm.response.code).to. be.oneOf([201,202]);
});
|
检查状态码文本:
pm.test("Status code name has string", () => {
pm.response.to.have.status("Created");
});
|
测试标头
检查是否存在响应标头:
pm.test("Content-Type header is present", () => {
pm.response.to.have.header("Content-Type");
});
|
测试具有特定值的响应标头:
pm.test("Content-Type header is application/json", () => {
pm.expect(pm.response.headers. get('Content-Type')).to.eql('application/json');
});
|
测试 cookie
测试响应中是否存在 cookie:
pm.test("Cookie JSESSIONID is present", () => {
pm.expect(pm.cookies.has( 'JSESSIONID')).to.be.true;
});
|
测试特定的 cookie 值:
pm.test("Cookie isLoggedIn has value 1", () => {
pm.expect(pm.cookies.get ('isLoggedIn')).to.eql('1');
});
|
测试响应时间
测试响应时间是否在指定范围内:
pm.test("Response time is less than 200ms", () => {
pm.expect(pm.response.responseTime) .to.be.below(200);
});
|
常见的断言示例
继续阅读一些常见断言示例,您可能会发现在您的脚本中有用,如下所述或通过编辑细节以满足您自己的需要。
有关可以在断言中包含的内容的更全面的概述,请参阅Chai 断言库文档。
针对变量断言响应值
检查响应属性是否与变量(在本例中为环境变量)具有相同的值:
pm.test("Response property matches environment variable", function () {
pm.expect(pm.response.json(). name).to.eql(pm.environment.get("name"));
});
|
有关可用于在脚本中操作变量的操作的概述,请参阅使用变量。
断言值类型
测试响应的任何部分的类型:
const jsonData = pm.response.json();
pm.test("Test data type of the response", ()
pm.expect(jsonData).to.be.an("object");
pm.expect(jsonData.name).to.be.a("string");
pm.expect(jsonData.age).to.be.a("number");
pm.expect(jsonData.hobbies).to.be.an("array");
pm.expect(jsonData.website).to.be.undefined;
pm.expect(jsonData.email).to.be.null;
});
|
断言数组属性
检查数组是否为空,以及它是否包含特定项:
const jsonData = pm.response.json();
pm.test("Test array properties", () => {
pm.expect(jsonData.errors).to.be.empty;
pm.expect(jsonData.areas).to.include("goods");
const notificationSettings = jsonData.settings.find
(m => m.type === "notification");
pm.expect(notificationSettings)
.to.be.an("object", "Could not find the setting");
pm.expect( notificationSettings.detail).to.include("sms");
pm.expect(notificationSettings.detail)
.to.have.members(["email", "sms"]);
});
|
中的顺序.members不影响测试。
断言对象属性
断言一个对象包含键或属性:
pm.expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.not.have.any. keys('c', 'd');
pm.expect({a: 1}).to.have.property('a');
pm.expect({a: 1, b: 2}).to.be.an('object')
.that.has.all.keys('a', 'b');
|
目标可以是object、set或。如果在没有or的情况下运行,则表达式默认为。由于行为因目标而异,建议在使用前检查with
。arraymap.keys.all.any.all.keystypetype.keys.a
断言一个值在一个集合中
根据有效选项列表检查响应值:
pm.test("Value is in valid list", () => {
pm.expect(pm.response.json().type)
.to.be.oneOf(["Subscriber" , "Customer", "User"]);
});
|
断言包含一个对象
检查对象是否是父对象的一部分:
pm.test("Object is contained", () => {
const expectedObject = {
"created": true,
"errors": []
};
pm.expect(pm.response.json() ).to.deep.include(expectedObject);
});
|
Using.deep导致链中所有.equal, .include, .members, .keys,
和.property断言使用深度相等(松散相等)而不是严格 ( ===) 相等。虽然.eql也比较松散,但.deep.equal导致深度相等比较也可用于链中的任何其他断言,而.eql不会。
断言当前环境
检查 Postman 中的活动(当前选择的)环境:
pm.test("Check the active environment", () => {
pm.expect(pm.environment. name).to.eql("Production");
});
|
排除常见测试错误
当您在测试脚本中遇到错误或意外行为时,Postman控制台可以帮助您识别来源。通过将console.log()、和debug
语句与您的测试断言相结合console.info(),您可以检查 HTTP 请求和响应的内容,以及诸如变量之类的
Postman 数据项。选择Postman 左下角的Console打开它。console.warn()console.error()
控制台信息
记录变量或响应属性的值:
console.log(pm.collectionVariables.get("name"));
console.log(pm.response.json().name);
|
记录变量或响应属性的类型:
console.log(typeof pm.response.json().id);
|
使用控制台日志来标记代码执行,有时称为“跟踪语句”:
if (pm.response.json().id) {
console.log("id was found!");
} else {
console.log("no id ...");
}
|
断言深度相等错误
你可能会遇到AssertionError: expected <value> to
deeply equal '<value>'. 例如,这将出现在以下代码中:
pm.expect(1).to.eql("1");
|
发生这种情况是因为测试将数字与字符串值进行比较。只有当类型和值都相等时,测试才会返回 true。
JSON 未定义错误
你可能会遇到这个ReferenceError: jsonData is not defined问题。当您尝试引用尚未声明或超出测试代码范围的
JSON 对象时,通常会发生这种情况。
pm.test("Test 1", () => {
const jsonData = pm.response.json();
pm.expect(jsonData.name).to.eql("John");
});
pm.test("Test 2", () => {
pm.expect(jsonData.age).to.eql( 29);
});
|
确保所有测试代码都可以访问将响应数据设置为变量的任何代码,例如在这种情况下const jsonData
= pm.response.json();,在第一个代码之前移动pm.test会使它对两个测试函数都可用。
断言未定义的错误
你可能会遇到这个AssertionError: expected undefined to
deeply equal..问题。当您引用不存在或超出范围的属性时,通常会发生这种情况。
pm.expect(jsonData.name).to.eql("John");
|
在上面的示例中,如果您看到AssertionError: expected undefined
to deeply equal 'John',这表明该name属性未在jsonData对象中定义。
测试没有失败
在某些情况下,您可能希望测试失败,但事实并非如此。
pm.test("Not failing", function () {
pm.expect(true).to.eql(false);
});
|
确保您的测试代码在语法上是正确的,然后再次尝试发送您的请求。
验证响应结构
使用 Tiny Validator V4 (tv4) 执行 JSON 模式验证:
const schema = {
"items": {
"type": "boolean"
}
};
const data1 = [true, false];
const data2 = [true, 123];
pm.test('Schema is valid', function() {
pm.expect(tv4.validate(data1, schema)).to.be.true;
pm.expect(tv4.validate(data2, schema)).to.be.true;
});
|
使用 Ajv JSON 模式验证器验证 JSON 模式:
const schema = {
"properties": {
"alpha": {
"type": "boolean"
}
}
};
pm.test('Schema is valid', function() {
pm.response.to.have.jsonSchema(schema);
});
|
发送异步请求
从您的测试代码发送请求并记录响应。
pm.sendRequest("https://postman -echo.com/get", function (err, response) {
console.log(response.json());
});
|
以前的 Postman 测试写作风格(已弃用)
本节指的是 Postman 以前版本中使用的不推荐使用的脚本语法。如果您现在正在编写脚本,请使用上述当前语法。
以前编写 Postman 测试的方式依赖于为tests对象设置值。为对象中的元素设置一个描述性键,然后断言它是真还是假。例如,以下将检查响应正文是否包含user_id字符串:
tests["Body contains user_id"] = responsebody.has("user_id");
|
根据需要添加尽可能多的键,具体取决于您要测试的内容数量。在“测试”选项卡下的响应查看器中查看您的测试结果。选项卡标题显示通过了多少测试,并且您在测试变量中设置的键在此处列出。如果该值评估为真,则测试通过。
postman.setEnvironmentVariable("key", "value");
const array = [1, 2, 3, 4];
postman.setEnvironmentVariable("array" , JSON.stringify(array, null, 2));
const obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
postman.setEnvironmentVariable("obj" , JSON.stringify(obj));
postman.getEnvironmentVariable("key");
const array = JSON.parse(postman. getEnvironmentVariable("array"));
const obj = JSON.parse(postman. getEnvironmentVariable("obj"));
postman.clearEnvironmentVariable("key");
postman.setGlobalVariable("key", "value");
postman.getGlobalVariable("key");
postman.clearGlobalVariable("key");
tests["Body matches string"] = responseBody.has("string_you_want_to_search");
tests["Body is correct"] = responseBody === "response_body_string";
const data = JSON.parse(responseBody);
tests["Your test name"] = data.value === 100;
tests["Content-Type is present"] = postman.getResponseHeader("Content-Type");
tests["Content-Type is present"] = postman.getResponseHeader("Content-Type");
tests["Content-Type is present"] = responseHeaders.hasOwnProperty("Content-Type");
tests["Response time is less than 200ms"] = responseTime < 200;
tests["Response time is acceptable"] = _.inRange(responseTime, 100, 1001);
tests["Status code is 200"] = responseCode.code === 200;
tests["Status code name has string"] = responseCode.name.has("Created");
tests["Successful POST request"] = responseCode.code === 201 || responseCode.code === 202;
|
下一步
使用collection runner自动化您的测试运行。
|