Apifox 测试步骤之间怎么传递数据?搞懂上下游参数传递这一篇就够了!

在使用 Apifox 编排自动化测试流程时,我们会接触到各种类型的测试步骤:接口请求、数据库查询、For 循环、ForEach 遍历、脚本处理等等。

这些测试步骤执行后产生的数据往往需要被下游步骤引用,作为下游步骤的输入条件 形成一个"数据驱动 + 流程联动"的自动化逻辑。

举个例子:你可能需要在前置步骤中获取用户 token,或查询数据库中的某条记录,然后将这些结果用于下一个测试步骤的调用。

那么问题来了,这些上游步骤产生的数据,该如何在下游步骤中正确引用?

数据传递的两种机制

在 Apifox 的自动化测试中,不同测试步骤之间的数据流转,通常有两种方式:

1. 通过「动态值」引用(即用即取)

通过"动态值"功能,在下游测试步骤中直接读取上游步骤的数据。

2. 通过「变量」中转(先存后用)

在上游步骤中通过"提取变量"将关键数据提取为变量,再供下游步骤使用。

理解这两种传递方式,是掌握 Apifox 自动化测试的基础。

本文将从"如何提取数据"与"如何使用数据"两个角度出发,逐一拆解不同类型步骤的数据处理方法,帮助你灵活构建联动性更强的测试流程。

你可以根据自己的实际需求,滑动至感兴趣的部分进行阅读!

接口响应数据的提取与使用

接口数据的特征

在自动化测试中,接口请求执行后通常会返回结构化的 JSON 数据,这些响应数据是后续步骤的关键输入源,例如:

相比其他类型的步骤,接口数据的结构往往比较复杂,可能包含多层嵌套的对象和数组。

数据提取方式

针对接口响应数据,我们通常采用两种方式来提取所需的数据,让其在测试步骤之间流转:

方式一:动态值引用

你可以在下游步骤中,通过"动态值"语法直接引用前置接口的响应。在任意输入框中点击"魔棒"图标,选择「读取前置步骤的运行结果」,Apifox 会自动生成表达式,无需手动拼写。

方式二:提取为变量

你也可以在接口步骤中通过"提取变量"功能,将响应中的特定字段提取为变量。例如设置变量名称为 products_id,JSONPath 为 $.products[0].id,那么在后续步骤中就可以直接使用 {{products_id}} 来引用这个值。

数据使用场景

接口响应数据通过上述"动态值"以及"提取变量"的方式来流转,在下游步骤中的常见用法如下:

在接口请求中使用:

  • 动态值方式:跟上述"方式一"介绍的一样,只需在输入框中点击"魔棒"图标,选择「读取前置步骤的运行结果」来填写输入参数即可。
  • 提取变量方式:假设提取的变量为 products_id,则在参数中直接填入{{products_id}}即可

在数据库操作中使用:

如果你需要将接口返回的某个值作为查询条件,传入数据库步骤中拼接 SQL 语句,也可以通过两种方式。

  • 动态值方式:
SQL 复制代码
SELECT * FROM products WHERE id = '{{$.1.response.body.products[0].id}}'

这里面的表达式可以在动态值中读取:

  • 提取变量方式:假设提取的变量名为 products_id,则在 SQL 语句中直接插入{{products_id}}即可
SQL 复制代码
SELECT * FROM products WHERE id = '{{products_id}}'

在 For 循环中使用:

若需根据接口返回数组的长度执行多轮循环,可以通过动态值读取数组的 .length 值作为循环次数,例如{{$.1.response.body.products.length}}

在 ForEach 中使用: 若需将接口返回的数组对象,作为 ForEach 循环的输入源,也可以通过两种方式。

  • 动态值方式:直接把整个数组提取出来即可,例如{{$.1.response.body.products}}
  • 提取变量方式:假设已提取整个数组为products变量,则在循环中直接插入{{products}}即可

在脚本中使用:

在脚本中引用前置步骤的数据,需要通过 pm.variables.get() 方法。

  • 动态值方式:可以直接读取前置步骤的运行结果
JavaScript 复制代码
const products = pm.variables.get("$.1.response.body.products")
  • 提取变量方式:假设已将products提取为变量(环境/临时/全局变量) ,则在pm.variables.get()方法内填入products即可。

获取临时变量的值:

JavaScript 复制代码
const products = pm.variables.get("products")

获取环境变量的值:

JavaScript 复制代码
const products = pm.environment.get("products")

获取全局变量的值:

JavaScript 复制代码
const products = pm.globals.get("products")

注意:在脚本中不能直接使用 {{products}} 这样的插值语法,必须通过方法获取变量值。

数据库查询结果的提取与使用

数据库数据的特征

数据库查询步骤执行后会返回查询结果的结构化数据,格式是一个数组对象,即使只查询到一条记录也会被包装在数组中,例如:

与接口数据不同的是,数据库步骤产生的数据不能直接通过「动态值」访问,必须先通过「提取变量」的方式保存下来。

数据提取方式

在数据库步骤中执行完 SQL 后,Apifox 会自动解析出结构化响应,格式大致如下:

JSON 复制代码
[
  {
    "id": "1000",
    "title": "标题1",
    "description": "标题1的描述"
  }
]

你可以通过 JSONPath 提取其中的字段并保存为变量,例如:

  • 变量名:products_id
  • JSONPath:$[0].id,如果要保存整个结果集,则设置为 $
  • 下游步骤通过{{ }}引用变量,例如:{{products_id}}

数据使用场景

在接口请求中使用:

如果你在数据库中查询出了某个 id,将其提取为products_id的变量后,下游接口的请求参数中可以直接通过{{products_id}}引入该变量:

在 ForEach 中使用:

如果你查询出了一组记录,想要逐条处理,就可以将整个数组作为 ForEach 循环的遍历源,例如{{products}}

前提是你在数据库操作中提取变量时保存了整个数组,例如:

  • 变量名:products
  • JSONPath:$

在脚本中使用:

脚本中访问数据库提取出来的变量方式与其他变量一致,例如:

获取临时变量的值:

JavaScript 复制代码
const products = pm.variables.get("products")

获取环境变量的值:

JavaScript 复制代码
const products = pm.environment.get("products")

获取全局变量的值:

JavaScript 复制代码
const products = pm.globals.get("products")

For 循环中数据的提取与使用

For 循环的工作机制

For 循环是一种重复执行特定逻辑的控制结构,它通过指定的次数来循环执行内部的步骤。

你可以固定一个常量来控制循环次数,也可以通过动态值读取前置步骤返回的数组,将数组的长度 .length 作为循环次数,例如{{$.1.response.body.products.length}}

与其他输出数据的步骤不同,For 循环本身并不直接产出数据,它只提供一个从 0 开始的索引值(index),表示当前是第几次循环执行。

循环索引的获取

在执行流程中,你可以通过「动态值」语法访问循环的当前索引值,例如 {{$.7.index}}

其中的数字 7 代表该 For 循环步骤的 ID,每个步骤都有唯一的 ID 标识。这个索引值从 0 开始计数,在第一次循环时值为 0,第二次为 1,依此类推。

循环数据的应用场景

在脚本中使用循环索

当你需要在测试脚本中访问循环相关信息时,可以通过pm.variables.get()方法获取当前循环的索引值,然后进行相应的逻辑处理:

JavaScript 复制代码
// 获取当前循环的索引值
const index = pm.variables.get("$.7.index");
console.log("当前是第 " + (parseInt(index) + 1) + " 次循环");

结合其他数据源使用

For 循环的一个常见使用场景是结合上游步骤获取的数据,在每次循环中处理不同的元素。例如,你可以先获取一个数组,然后在 For 循环中通过索引访问数组的不同元素,实现批量处理的效果。

JavaScript 复制代码
// 获取 For 循环的数据源
const products = pm.variables.get("$.1.response.body.products")

// 获取 For 循环中的索引
const index =  pm.variables.get("$.7.index")

// 使用索引从数组中获取当前元素
console.log(products[index])

ForEach 循环中数据的提取与使用

ForEach 循环的工作原理

ForEach 循环专为数组数据设计,它会自动遍历数组中的每一个元素并执行相同的操作。与 For 循环的关键区别是,ForEach 会在每轮迭代中自动提取当前元素的完整数据,使其在子步骤中可用。

ForEach 循环中的数据访问

在 ForEach 循环中,系统会自动创建两个特殊变量:

当前元素

包含当前正在处理的数组元素的完整数据,例如{{$.4.element}}。对于对象数组,你可以直接访问其属性,如{{$.4.element.id}}{{$.4.element.title}}等。

当前索引

表示当前是第几轮循环(从 0 开始计数),如{{$.4.index}}

注意:数字4是 ForEach 步骤的 ID,在实际使用时需要替换为你自己流程中 ForEach 步骤的 ID。

ForEach 数据的应用场景

在接口请求中使用

ForEach 循环非常适合批量处理数据,例如对数组中的每个元素发起一个请求。在不同轮次中,相同的请求模板会自动使用不同的数据,例如{{$.4.element.id}}

在数据库操作中使用

你可以使用循环里的元素字段进行数据库查询,或者将当前元素的多个字段插入到数据库表中,实现批量的数据库操作。例如:用当前项中的某个字段去查询数据库:

SQL 复制代码
SELECT * FROM products WHERE id = '{{$.4.element.id}}'

这里的表达式{{$.4.element.id}}可以通过动态值来获取:

将当前项的多个字段插入到某张表中:

SQL 复制代码
INSERT INTO products (id, title) VALUES ('{{$.4.element.id}}', '{{$.4.element.title}}')

在脚本中使用

如果你需要在自定义脚本中获取循环中的数据后进一步处理,也可以使用pm.variables.get()方法来获取当前循环元素的实际值,例如:

JavaScript 复制代码
// 获取当前元素
const item = pm.variables.get("$.4.element")

// 获取当前索引
const item = pm.variables.get("$.4.index")

脚本中数据的设置与传递

脚本数据的特殊性

与其他测试步骤不同,脚本不会自动产出可供下游测试步骤直接读取的数据。如果你希望将脚本中的处理结果用于后续步骤,必须显式地将数据保存为变量。

数据设置方式

你可以在脚本中通过如下方法,将结果写入变量,例如:

JavaScript 复制代码
// 获取 JSON 格式的请求返回数据
// 1. 从而当前接口中获取
// const currentData = pm.response.json();

// 2. 通过动态值从前置步骤中获取
const preData = pm.variables.get("$.1.response.body")

// 将值写入环境变量
pm.environment.set('products', preData.products);
pm.environment.set('products_id', preData.products[0].id);

// 将值写入全局变量
pm.globals.set('products', preData.products);

// 将值写入临时变量(仅本次运行有效)
pm.variables.set('products', preData.products);

变量设置完成后,就可以在后续步骤中通过 {{ }}语法进行引用。

脚本数据的应用场景

在接口请求中使用

脚本中设置的变量可以直接在下游接口请求的参数中使用,实现动态参数的生成和传递。例如你在脚本中写入了变量 products_id,则可以在下游接口请求的参数中用{{products_id}}作为入参。

在数据库操作中使用

与其他测试步骤设置的变量一样,脚本中设置的变量也可以参与 SQL 语句的拼接,为数据库操作提供动态的查询条件或插入值。例如:

SQL 复制代码
SELECT * FROM products WHERE id = '{{products_id}}'

在 For 循环中使用

你可以用脚本生成循环次数或中间值并保存在"临时变量"中,再传入 For 步骤:

JavaScript 复制代码
pm.variables.set("loopCount", 5);

然后在 For 的循环次数中填写 {{loopCount}}

在 ForEach 中使用

你可以在脚本里将整个数组写入到变量中,然后在 ForEach 循环中使用,例如:

JavaScript 复制代码
// 通过动态值从前置步骤中获取
// const preData = pm.variables.get("$.1.response.body.products")

const preData = [{id: 1}, {id: 2}, {id: 3}];

// 将值写入环境变量
pm.environment.set('products', preData);

接着将 {{products}} 作为 ForEach 的遍历数据源:

总结

掌握不同类型步骤的数据提取与使用方法,是构建高效自动化测试流程的关键。接口和数据库步骤主要产出业务数据,循环步骤提供控制逻辑,脚本步骤则负责数据的加工处理。通过合理组合动态值引用和变量提取两种机制,你可以构建出灵活且强大的数据驱动测试流程。

在实际使用中,建议根据数据的使用频率和复杂程度来选择合适的传递方式:简单且偶尔使用的数据可以直接通过动态值引用,而需要多次使用或在脚本中处理的数据则建议提取为变量。

欢迎大家继续对 Apifox 提出使用反馈和优化意见,有任何问题可以在 Apifox 用户群与我们交流沟通。

相关推荐
涡能增压发动积1 天前
同样的代码循环 10次正常 循环 100次就抛异常?自定义 Comparator 的 bug 让我丢尽颜面
后端
Wenweno0o1 天前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
于慨1 天前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz1 天前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
swg3213211 天前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
从前慢丶1 天前
前端交互规范(Web 端)
前端
tyung1 天前
一个 main.go 搞定协作白板:你画一笔,全世界都看见
后端·go
gelald1 天前
SpringBoot - 自动配置原理
java·spring boot·后端
CHU7290351 天前
便捷约玩,沉浸推理:线上剧本杀APP功能版块设计详解
前端·小程序
GISer_Jing1 天前
Page-agent MCP结构
前端·人工智能