掌握 Apifox 中 pm 脚本的基本使用

当你开始使用 Apifox 进行接口测试时,很快就会遇到需要编写脚本的场景。Apifox 完全兼容 Postman 的脚本 API,这意味着你可以在前置脚本和后置脚本中使用这些强大的功能来处理请求数据、响应结果,以及进行各种自动化操作。

这些脚本的核心就是 pm
对象。可以说,掌握了 pm
对象的使用,你就掌握了 Apifox 脚本编写的精髓。
pm 对象:脚本的核心
pm
是一个包含了接口运行相关信息的核心对象。通过它,你可以访问即将发送的请求信息,获取返回的响应数据,还能读写各种类型的变量。可以把它理解为你在脚本中操作一切的入口点,接下来我们就来逐一了解它的各个组成部分。
获取运行时信息:pm.info
有时候你需要知道当前脚本运行在什么环境下,比如这是前置脚本还是后置脚本,当前是第几轮循环测试。pm.info
就是专门提供这些上下文信息的。
通过 pm.info.eventName
可以判断当前执行的脚本类型。它会返回 "prerequest"(前置脚本)或 "test"(后置脚本)。这在编写通用脚本时特别有用,你可以根据脚本类型执行不同的逻辑。
另外,pm.info.requestName
和 pm.info.requestId
可以帮你获取当前正在运行的接口用例名称和唯一ID。
console.log(pm.info.eventName);
console.log(pm.info.iteration);
console.log(pm.info.iterationCount);
console.log(pm.info.requestName);
console.log(pm.info.requestId);
在脚本中发送请求:pm.sendRequest
有时候你需要在主请求之外再发送一些辅助请求,比如在前置脚本中获取 token,或者在后置脚本中发送通知。pm.sendRequest
就是为这种场景设计的。
这个方法可以异步发送 HTTP/HTTPS 请求,它接受两个参数:一个是请求配置,另一个是回调函数。回调函数有两个参数,第一个是错误信息,第二个是响应结果。
最简单的用法是直接传入一个URL:
pm.sendRequest("https://postman-echo.com/get", function(err, res) {
if (err) {
console.log(err);
} else {
pm.environment.set("variable_key", "new_value");
}
});
当然,你也可以传入完整的请求配置,包括请求方法、请求头、请求体等:
const echoPostRequest = {
url: "https://postman-echo.com/post",
method: "POST",
header: {
headername1: "value1",
headername2: "value2",
},
body: {
mode: "urlencoded",
urlencoded: [
{ key: "account", value: "apifox" },
{ key: "password", value: "123456" },
],
},
};
pm.sendRequest(echoPostRequest, function(err, res) {
console.log(err ? err : res.json());
});
对于不同的请求体格式,你需要设置不同的 body.mode
。如果是 JSON 格式,记得在 header 中添加 Content-Type: application/json
,并将数据序列化为字符串。
操作临时变量:pm.variables
在脚本运行过程中,你经常需要存储一些临时数据,比如从响应中提取的某个值,或者计算得出的中间结果。pm.variables
就是用来操作这些临时变量的,这些变量只在当前请求运行期间有效。
临时变量的操作很直观。用 set
方法设置变量,用 get
方法获取变量,用 has
方法检查变量是否存在:
pm.variables.set("foo", "bar");
console.log(pm.variables.has("foo")); // true
console.log(pm.variables.get("foo")); // bar
特别有用的是 replaceIn
方法,它可以将字符串中的变量占位符替换为真实值:
console.log(pm.variables.replaceIn("Hello {{foo}}")); // Hello bar
如果你需要处理动态值表达式(比如 {{$person.fullName}}
),可以使用 replaceInAsync
方法,记得在前面加上 await
。
处理测试数据:pm.iterationData
当你在进行自动化测试时,可能需要使用测试数据文件中的数据。pm.iterationData
专门用来访问这些测试数据变量,不过它是只读的,你不能修改这些数据。
使用方法和临时变量类似,但只能读取不能设置:
console.log(pm.iterationData.has("userId"));
console.log(pm.iterationData.get("userId"));
console.log(pm.iterationData.replaceIn("Hello {{userId}}"));
console.log(pm.iterationData.toObject());
管理环境变量:pm.environment
环境变量是 API 测试中最重要的概念之一。不同的环境(开发、测试、生产)通常有不同的配置,比如不同的域名、数据库连接等。pm.environment
让你可以在脚本中读写当前环境的变量。
首先,你可以通过 pm.environment.name
获取当前环境的名称。然后就可以像操作其他变量一样操作环境变量了:
pm.environment.set("env1", "value1");
console.log(pm.environment.has("env1")); // true
console.log(pm.environment.get("env1")); // value1
console.log(pm.environment.replaceIn("Hello {{env1}}")); // Hello value1
如果需要删除某个环境变量,用 unset
方法。如果要清空当前环境的所有变量,用 clear
方法。需要注意的是,这些操作都是针对本地值,不会影响到远程保存的值。
操作模块变量:pm.moduleVariables
模块变量在整个模块(或集合)范围内有效。操作方法和环境变量完全一样:
pm.moduleVariables.set("token", "abc123");
console.log(pm.moduleVariables.has("token")); // true
console.log(pm.moduleVariables.get("token")); // abc123
console.log(pm.moduleVariables.replaceIn("Token is {{token}}")); // Token is abc123
值得一提的是,pm.collectionVariables
和 pm.moduleVariables
是等效的,你可以根据个人习惯选择使用哪一个。
管理全局变量:pm.globals
全局变量的作用域是最大的,在整个项目甚至团队范围内都有效。Apifox 支持项目全局变量和团队全局变量两种类型。
在设置全局变量时,你可以指定变量的作用范围:
pm.globals.set("g1", "val1", "PROJECT"); // 项目全局变量
console.log(pm.globals.get("g1")); // val1
如果不指定作用范围,默认是项目全局变量。当你使用 'TEAM' 作为作用范围时,只会更改已有同名团队变量的本地值,不会创建新的团队变量。
访问请求信息:pm.request
pm.request
让你可以访问当前的请求对象。在前置脚本中,它表示即将发送的请求;在后置脚本中,它表示已经发送的请求。
通过这个对象,你可以获取和修改请求的各个部分:
console.log(pm.request.url.toString()); // 请求URL
console.log(pm.request.method); // 请求方法
console.log(pm.request.getBaseUrl()); // 前置URL
你还可以动态操作请求头。比如添加一个新的请求头:
pm.request.headers.add({ key:"X-Test", value:"123" });
console.log(pm.request.headers.get("X-Test"));
如果要更新已存在的请求头,可以使用 upsert
方法,它会自动判断是新增还是更新。
处理响应数据:pm.response
响应对象只在后置脚本中可用,它包含了服务器返回的所有信息:状态码、响应头、响应体、响应时间等。
最常用的操作是获取响应的基本信息:
console.log(pm.response.code); // 状态码
console.log(pm.response.status); // 状态描述
console.log(pm.response.responseTime); // 响应时间
获取响应内容有两种主要方式:
console.log(pm.response.text()); // 获取文本内容
console.log(pm.response.json()); // 获取JSON对象
如果响应包含特定的请求头,你也可以轻松获取:
console.log(pm.response.headers.get("Date"));
操作 Cookies:pm.cookies
网站认证经常使用 cookies,pm.cookies
让你可以访问当前请求对应域名下的 cookies:
console.log(pm.cookies.has("session"));
console.log(pm.cookies.get("session"));
console.log(pm.cookies.toObject());
如果需要清空所有 cookies,可以这样做:
pm.cookies.jar().clear(pm.request.getBaseUrl());
需要注意的是,pm.cookies
获取的是接口请求后返回的 cookie,不是请求发出时的 cookie。
编写测试断言:pm.test
测试断言是验证接口是否正常工作的关键。pm.test
让你可以编写各种测试用例来检查响应是否符合预期:
pm.test("response should be okay to process", function() {
pm.response.to.not.be.error;
pm.response.to.have.jsonBody("");
pm.response.to.not.have.jsonBody("error");
});
对于异步测试,你可以使用 callback 参数中的 done
函数:
pm.test("async test", function(done) {
setTimeout(() => {
pm.expect(pm.response.code).to.equal(200);
done();
}, 1500);
});
使用断言库:pm.expect
pm.expect
提供了强大的断言功能,它基于 ChaiJS 的 expect 断言库。你可以用它来验证各种数据:
pm.expect(pm.response.code).to.equal(200);
pm.expect(pm.response.json().data).to.be.an('array');
pm.expect(pm.response.json().data.length).to.be.above(0);
响应断言的便捷方法
Apifox 还提供了许多针对响应的便捷断言方法,让你可以快速检查常见的响应特征:
pm.response.to.have.status(200); // 检查状态码
pm.response.to.have.header("Content-Type"); // 检查是否有特定请求头
pm.response.to.have.jsonBody(); // 检查是否有JSON响应体
pm.response.to.be.ok; // 检查状态码是否为200
pm.response.to.be.success; // 检查状态码是否为2XX
这些方法涵盖了从状态码验证到响应体结构检查的各种常见场景,让你可以快速编写出可靠的测试脚本。
通过这些 pm 脚本的功能,你可以实现复杂的接口测试自动化流程。从简单的变量传递到复杂的业务逻辑验证,pm 对象都能为你提供强大的支持。掌握了这些基础用法,你就可以开始构建属于自己的自动化测试体系了。