首页 > 其他分享 >接口测试工具Apifox 基础篇:数据传递与处理

接口测试工具Apifox 基础篇:数据传递与处理

时间:2022-10-18 17:34:45浏览次数:119  
标签:body 接口 sign 参数 测试工具 Apifox 环境变量 pm


一、接口之间如何传递数据

1、使用场景

接口B请求参数依赖于接口A返回的数据

2、实现思路

2.1 接口A使用后置操作->提取变量功能将请求完成后返回的数据提取作为变量

2.2 接口B对应的参数值直接引用前面设置的变量

3、使用示例

3.1 接口A使用后置操作->提取变量

将接口返回 Response JSON 数据里的 token 值提取到名为 token 的临时变量(或环境变量、全局变量)

接口测试工具Apifox 基础篇:数据传递与处理_字符串

3.2  接口B参数引用变量

对应的参数值里写入 {{token}},即引用可名为token的变量。

二、登录态的接口如何处理

1、Session/Cookie 方式

Apifox 会自动保持 Session/Cookie 方式的登录态。

使用方式:

  • 先执行登录接口,执行完成后全局 Cookie 会自动保存返回的 Session/Cookie 信息。
  • 然后运行其他接口,会自动带上 Session/Cookie 信息。

2、Token 方式

Token 方式是将登录凭证放在接口请求参数里(通常会放在 Header)。常见的有Basic Auth、Bearer Token、API Key等方式。

使用方法:

方法一、通过全局(项目概览页)、分组(分组设置)、接口(文档编辑页)的 Auth 设置授权信息,支持如下多种授权类型

接口测试工具Apifox 基础篇:数据传递与处理_字符串_02

方法二、手动将 token 写入 Header 或其他对应参数里(推荐使用 环境变量 存放 token)。

示例:

Bearer Token:设置一个名为Authorization的 Header,设置值为Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9yJpZCI6(或者使用环境变量,设置值为Bearer {{AUTH_TOKEN}})

方法三、在 环境 里的全局参数统一设置,所有接口运行时会自动加上全局参数,无需每个接口手动设置。

3、全自动登录方式

自动调用登录接口完成登录,无需手动登录

3.1、实现思路

3.1.1、使用 环境变量(如:ACCESS_TOKEN)保存登录需要的凭证。

3.1.2、如凭证有过期时间,使用环境变量(如:ACCESS_TOKEN_EXPIRES)保存登录凭证的过期时间。

3.1.3、创建一个 公共脚本 :

A、判断环境变量ACCESS_TOKEN是否有值,以及ACCESS_TOKEN_EXPIRES是否过期,如果存在且未过期,跳出执行,否则下一步。

B、使用 pm.sendRequest 调用登录接口,将登录接口返回的登录凭证写入环境变量,过期时间也写入环境变量。

3.1.4、设置需要登录态的接口用例:

A、将用来验证登录态的参数值设置为 {{ACCESS_TOKEN}} 。

  • 将 header 里的Authorization的设置为{{ACCESS_TOKEN}}。注意:这里也可以使用 Cookie 或其他位置的参数,请根据实际情况确定。
  • 此处也可以在 环境 里的 额外参数 统一设置,所有接口运行时会自动加上 额外参数,无需每个接口手动设置。

B、在 前置脚本 里引用前面创建公共脚本。

3.2、示例:

  • 示例脚本里的登录用户名和密码,是从环境变变量 LOGIN_USERNAME 和 LOGIN_PASSWORD 获取,如果你直接拷贝代码的话,记得要手动设置这两个环境变量。
  • 如果你们的 token 没有过期时间,可以将 ACCESS_TOKEN_EXPIRES相关的代码去除。
// 定义发送登录接口请求方法
function sendLoginRequest() {
// 获取环境变量里的前置URL
const baseUrl = pm.environment.get('BASE_URL');
// 登录用户名,从环境变量LOGIN_USENAME获取,也可以写死(但不建议)
const username = pm.environment.get('LOGIN_USERNAME');
// 登录密码,从环境变量LOGIN_PASSWORD获取,也可以写死(但不建议)
const password = pm.environment.get('LOGIN_PASSWORD');

// 构造一个POST x-www-form-urlencoded 格式请求。这里需要改成你们实际登录接口的请求参数
const loginRequest = {
url: baseUrl + '/api/v1/login',
method: 'POST',
// 若 body 为 x-www-form-urlencoded 格式,mode 为 'urlencoded'
body: {
mode: 'urlencoded',
urlencoded: [
{ key: 'account', value: username },
{ key: 'password', value: password }

]
}
/*
// 若 body 为 form-data 格式,mode 为 'formdata'
body: {
mode: 'formdata',
formdata: [
{ key: 'account', value: username },
{ key: 'password', value: password }
]
}
// 若 body 为 raw 或 json 格式,mode 为 'raw'
body: {
mode: 'raw',
raw: JSON.stringify({ username: username, password: password }),
}
*/
};
// 发送请求
pm.sendLoginRequest(loginRequest, function (err, res) {
if (err) {
console.log(err);
} else {
// 读取接口返回的json数据
// 如果token信息存放在cookies的,可以使用res.cookies.get('token')方式获取
const jsonData = res.json();
// 将accessToken写入环境变量ACCESS_TOKEN
pm.environment.set('ACCESS_TOKEN', jsonData.data.accessToken);
// 将accessTokenExpires 过期时间写入环境变量 ACCESS_TOKEN_EXPIRES
pm.environment.set('ACCESS_TOKEN_EXPIRES', jsonData.data.accessTokenExpires);
}
});
}

// 获取环境变量的ACCESS_TOKEN
const accessToken = pm.environment.get('ACCESS_TOKEN');
// 获取环境变量里的 ACCESS_TOKEN_EXPIRES
const accessTokenExpires = pm.environment.get('ACCESS_TOKEN_EXPIRES');
// 如 ACCESS_TOKEN 没有值,或 ACCESS_TOKEN_EXPIRES 已过期,则执行发送登录接口请求
if (!accessToken || (accessTokenExpires && new Date(accessTokenExpires) <= new Date())) {
sendLoginRequest();
}

 

三、接口签名如何处理

注:统一处理,无需每个接口都处理

1、实现思路

1.1、创建一个 ​​公共脚本​​​ 实现签名逻辑,​​读取接口请求参数​​​,然后使用 ​​内置类库​​​,如(​​crypto-js​​),生成签名。

1.2、将生成的签名 sign 作为参数加入请求,可使用以下两种方案:

  • 方案一:​​脚本直接修改请求信息​​,注入一个签名参数,无需使用环境变量。(注:脚本只能修改 header 和 query 参数,不能修改 body 参数。如需将签名放在 body 里,只能使用方案二)。
  • 方案二:将生成的签名写入环境变量,接口设置参数时引用环境变量。

1.3、在接口的 ​​前置脚本​​ 里引用前面创建公共脚本。

1.4、如果签名算法是其他语言编写的,可使用fox.execute方法 ​​调用其他语言编写的程序​

2、接口签名示例之微信支付签名算法

第一步:假设所有发送参数集合M,将集合M内非空参数值的参数按照参数名 ASCII 码从小到大排序(字典序),使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

2.1、参数名ASCII码从小到大排序(字典序);

2.2、如果参数的值为空不参与签名;

2.3、参数名区分大小写;

2.4、传送的sign参数不参与签名;

第二步:在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

3、公共脚本实现之微信支付签名算法

// 获取预先设置为环境变量的 APPKEY
let key = pm.environment.get("APPKEY");

// 存放所有需要用来签名的参数
let param = {};

// 加入 query 参数
let queryParams = pm.request.url.query;
queryParams.each(item => {
if (item.value !== '') { // 非空参数值的参数才参与签名
param[item.key] = item.value;
}
});

// 加入 body 参数
if (pm.request.body) {
let formData;
switch (pm.request.body.mode) {
case 'formdata':
formData = pm.request.body.formdata;
break;
case 'urlencoded':
formData = pm.request.body.urlencoded;
break;
case 'raw':
// 如果没有 JSON 格式的请求 body,或 JSON 格式 body 不参与签名,可以删除这一段
let contentType = pm.request.headers.get('content-type');
if (
contentType
&& pm.request.body.raw
&& contentType.toLowerCase().indexOf('application/json') !== -1
) {
try {
let jsonData = JSON.parse(pm.request.body.raw);
/*
* 注意:通过脚本取出来的接口参数,如果参数包含变量,变量是不会替换成对应的值。如想要获取替换后的值,可使用`pm.variables.replaceIn`方法处理:
* let body = pm.variables.replaceIn(pm.request.body.raw);
* let jsonData = JSON.parse(body);
*/
for (let key in jsonData) {
let value = `${jsonData[key]}`; // 此处要注意如果值的实际类型不是 string 需要根据实际情况处理。
if (value !== '') { // 非空参数值的参数才参与签名
param[key] = value;
}
}
} catch (e) {
console.log('请求 body 不是 JSON 格式')
}
}
break;
default:
break;
}
if (formData) {
formData.each(item => {
if (item.value !== '') { // 非空参数值的参数才参与签名
param[item.key] = item.value;
}
});
}
}


// 取 key
let keys = [];
for (let key in param) {
// 注意这里,要剔除掉 sign 参数本身
if (key !== 'sign') {
keys.push(key);
}
}

// 参数名 ASCII 码从小到大排序(字典序)
keys.sort();

// 转成键值对
let paramPair = [];
for (let i = 0, len = keys.length; i < len; i++) {
let k = keys[i];
paramPair.push(k + '=' + encodeURIComponent(param[k])) // urlencode 编码
}

// 最后加上 key
paramPair.push("key=" + key);

// 拼接
let stringSignTemp = paramPair.join('&');
// console.log(stringSignTemp);

let sign = CryptoJS.MD5(stringSignTemp).toString().toUpperCase();
console.log(sign);

// 方案一:直接修改接口请求的 query 参数,注入 sign,无需使用环境变量。
// queryParams.upsert({
// key: 'sign',
// value: sign,
// });

// 方案二:写入环境变量,此方案需要在接口里设置参数引用环境变量
pm.environment.set("SIGN", sign);

 

4、接口签名示例之微信支付签名算法

百度翻译接口:​​百度翻译接口参考文档​​。

4.1、签名生成规则

第一步:将请求参数中的 APPID(appid), 翻译query(q, 注意为UTF-8编码), 随机数(salt), 以及平台分配的密钥(可在​​管理控制台​​查看) 按照 appid+q+salt+密钥 的顺序拼接得到字符串1。

第二步:对字符串1做md5,得到32位小写的sign。

注:

  1. 待翻译文本(q)需为UTF-8编码
  2. 在生成签名拼接 appid+q+salt+密钥 字符串时,q不需要做URL encode,在生成签名之后,发送HTTP请求之前才需要对要发送的待翻译文本字段q做URL encode

4.2、官方举例

官方举例:将apple从英文翻译成中文:

请求参数:
q=apple
from=en
to=zh
appid=2015063000000001
salt=1435660288
平台分配的密钥: 12345678
生成sign:
>拼接字符串1
拼接appid=2015063000000001+q=apple+salt=1435660288+密钥=12345678
得到字符串1 =2015063000000001apple143566028812345678
>计算签名sign(对字符串1做md5加密,注意计算md5之前,串1必须为UTF-8编码)
sign=md5(2015063000000001apple143566028812345678)
sign=f89f9594663708c1605f3d736d01d2d4
完整请求为:
http://api.fanyi.baidu.com/api/trans/vip/translate?q=apple&from=en&to=zh&appid=2015063000000001&salt=1435660288&sign=f89f9594663708c1605f3d736d01d2d4

4.3、公共脚本实现

// 获取 Query 参数对象
var queryParams = pm.request.url.query;

// 获取 query 参数 q 的值
var q = queryParams.get('q');

// 获取预先设置为环境变量的 APPID 和 SECRET_KEY
var appid = pm.environment.get("APPID");
var secretKey = pm.environment.get("SECRET_KEY");

// 定义一个随机数(32768, 65536)之间
var salt = parseInt(Math.random() * (32769) + 32768, 10);

// 将随机数转换为字符串
salt = salt.toString();
console.log(salt);

// 定义一个由appid、要翻译的字符串、随机数、密钥组合成一个字符串
var str = appid + q + salt + secretKey;
console.log(str);

// 将 str 进行 md5 加密生成 sign
var sign = CryptoJS.MD5(str).toString();

// 方案一:直接修改接口请求的 query 参数,注入 salt 和 sign,无需使用环境变量。
queryParams.upsert({
key: 'salt',
value: salt,
});
queryParams.upsert({
key: 'sign',
value: sign,
});

// 方案二:将 salt 和 sign 写入环境变量,此方案需要在接口里设置参数引用环境变量
// pm.environment.set("SALT", salt);
// pm.environment.set("SIGN", strmd5);

标签:body,接口,sign,参数,测试工具,Apifox,环境变量,pm
From: https://blog.51cto.com/u_15834920/5767853

相关文章

  • 利用jmeter Ant Jenkins搭建 接口 性能测试 持续集成平台
    0.环境准备安装如下工具:1、Jmeter:编写测试脚本,相关的安装、配置、编写可以参考:​​​快速掌握jmeter的基本操作和使⽤​​2、ant:执行测试脚本,并生成测试报告,相关的安装......
  • smart-doc生成接口文档
      maven引入插件<plugin><groupId>com.github.shalousun</groupId><artifactId>smart-doc-maven-plugin</artifactId>......
  • 中通快递 | 轨迹查询接口
    如何利用快递鸟提供的接口来查询中通快递的物流轨迹。​我们来看一下,接口完成以后的实际效果以下是调用快递鸟接口获得的中通物流轨迹信息,显示的界面效果需要自己开发:现在我......
  • .NetCore WebApi接口 DELETE 请求错误405.0 - Method Not Allowed 跨域问题
    问题描述:.NetCore接口在发布到IIS上后,使用Delete请求时报错:405.0-MethodNotAllowed  解决方式:1:在启用或关闭Windows功能–>InternetInformationServices关......
  • Java通过经纬度、IP、城市调用天气接口(YY天气)
    调用接口,首先得去注册一个账号,(它只能获取当天的数据,没有百度API的功能强大)官网参考:http://www.yytianqi.com/api.htmlpackagecom.common.filo;importjava.io.Buffere......
  • 接口测试—1
    可以对比以下图,知道接口是怎么分类的http常用请求方式,可以参考,如下接口测试的工具用多种,例:postman,jmeter等,不知道接口可以通过控制台或者抓包软件提取1GET请求指定的......
  • getUserMedia报错:新版本Chrome中getUserMedia接口在http下不再支持
    新版本Chrome中getUserMedia接口在http下不再支持,请使用https来访问比较兼容的就是需要判断一下varmedia=(navigator.getUserMedia||navigator.webk......
  • 图片、接口封装 文字可生成的奇特图像
    脑洞大开!这个简易命令行工具,输入文字可生成的奇特图像 https://copyfuture.com/blogs-details/20210418130919282a图片、接口封装  https://blog.csdn.net/weix......
  • python接口自动化13-流量回放
    @目录FastTester:快速生成测试用例进行测试简介流程图(设计思路)快速开始一、接口用例集合获取方式一:Fiddler方式二:mitmproxy结合以上两种方式二、执行测试方式1:流量回放,......
  • 8.函数式接口
    函数式接口概念:一个接口中的抽象方法只有一个,那么这个接口就是一个函数式接口。1、通过注解检测一个接口是否是一个函数式接口:@FunctionalInterface在接口上直接加上注......