codecamp

Postman 测试脚本示例

使用您的请求、文件夹和集合中的“测试”选项卡编写测试,当 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", () => {
    //parse the response JSON and test three 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());
//output the html for testing
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 响应进行断言

您的测试可以检查请求响应的各个方面,包括bodystatus codesheaderscookiesresponse times等等。

测试响应体

检查响应正文中的特定值:

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"));
});
有关可用于在脚本中操纵变量的操作的概述,请参阅使用变量。

断言值类型

测试响应任何部分的类型:

/* response has this structure:
{
  "name": "Jane",
  "age": 29,
  "hobbies": [
    "skating",
    "painting"
  ],
  "email": null
}
*/
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;
});

断言数组属性

检查数组是否为空,以及它是否包含特定项:

/*
response has this structure:
{
  "errors": [],
  "areas": [ "goods", "services" ],
  "settings": [
    {
      "type": "notification",
      "detail": [ "email", "sms" ]
    },
    {
      "type": "visual",
      "detail": [ "light", "large" ]
    }
  ]
}
*/

const jsonData = pm.response.json();
pm.test("Test array properties", () => {
    //errors array is empty
  pm.expect(jsonData.errors).to.be.empty;
    //areas includes "goods"
  pm.expect(jsonData.areas).to.include("goods");
    //get the notification settings object
  const notificationSettings = jsonData.settings.find
      (m => m.type === "notification");
  pm.expect(notificationSettings)
    .to.be.an("object", "Could not find the setting");
    //detail array must include "sms"
  pm.expect(notificationSettings.detail).to.include("sms");
    //detail array must include all listed
  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或array。map如果在没有or.keys的情况下运行,则表达式默认为. 由于行为因目标而异,建议在使用with之前检查。.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"]);
});

断言包含一个对象

检查对象是否是父对象的一部分:

/*
response has the following structure:
{
  "id": "d8893057-3e91-4cdd-a36f-a0af460b6373",
  "created": true,
  "errors": []
}
*/

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()、console.info()和debug 语句与您的测试断言相结合,您可以检查 HTTP 请求和响应的内容console.warn(),console.error()以及变量等 Postman 数据项。您也可以使用该console.clear()方法清除控制台中的信息。从 Postman 页脚中选择 控制台图标 控制台以将其打开。

控制台信息

记录变量或响应属性的值:

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!");
  // do something
} else {
  console.log("no id ...");
  //do something else
}

断言深度相等错误

您可能会遇到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); // jsonData is not defined
});

确保所有测试代码都可以访问将响应数据设置为变量的任何代码,例如,在这种情况下,在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对象中定义。

测试不失败

在某些情况下,您可能希望测试失败,但实际上并没有。

//test function not properly defined - missing second parameter
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");

根据需要添加尽可能多的键,具体取决于您要测试的内容的数量。在“测试”选项卡下的响应查看器中查看您的测试结果。选项卡标题显示通过了多少测试,您在测试变量中设置的键也列在那里。如果该值评估为真,则测试通过。

//set an environment variable
postman.setEnvironmentVariable("key", "value");

//set a nested object as an environment variable
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));

//get an environment variable
postman.getEnvironmentVariable("key");

//get an environment variable whose value is a stringified object
//(wrap in a try-catch block if the data is coming from an unknown source)
const array = JSON.parse(postman.getEnvironmentVariable("array"));
const obj = JSON.parse(postman.getEnvironmentVariable("obj"));

//clear an environment variable
postman.clearEnvironmentVariable("key");

//set a global variable
postman.setGlobalVariable("key", "value");

//get a global variable
postman.getGlobalVariable("key");

//clear a global variable
postman.clearGlobalVariable("key");

//check if response body contains a string
tests["Body matches string"] = responseBody.has("string_you_want_to_search");

//check if response body is equal to a string
tests["Body is correct"] = responseBody === "response_body_string";

//check for a JSON value
const data = JSON.parse(responseBody);
tests["Your test name"] = data.value === 100;

//Content-Type is present (Case-insensitive checking)
tests["Content-Type is present"] = postman.getResponseHeader("Content-Type");
tests["Content-Type is present"] = postman.getResponseHeader("Content-Type");
//getResponseHeader() method returns the header value, if it exists

//Content-Type is present (Case-sensitive)
tests["Content-Type is present"] = responseHeaders.hasOwnProperty("Content-Type");

//response time is less than 200ms
tests["Response time is less than 200ms"] = responseTime < 200;

//response time is within a specific range
//(lower bound inclusive, upper bound exclusive)
tests["Response time is acceptable"] = _.inRange(responseTime, 100, 1001);

//status code is 200
tests["Status code is 200"] = responseCode.code === 200;

//code name contains a string
tests["Status code name has string"] = responseCode.name.has("Created");

//successful POST request status code
tests["Successful POST request"] = responseCode.code === 201 || responseCode.code === 202;

下一步

既然您已经看到了各种场景的测试脚本示例,您可能会对扩展自己的测试感兴趣:


Postman 使用监视器运行测试
Postman 动态变量
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }