-
2021-07-03 09:30:49
前言
使用 yaml 文件写测试用例的时候,如何在 yaml 文件的测试用例里面实现参数关联? 这是很多做自动化测试的小伙伴经常思考的一个问题。
接着前面的pytest+yaml 文件实现接口自动化框架,本篇使用环境变量的方式,让测试用例参数关联。
实现场景:上个接口返回的接口提取变量,在写个接口中引用变量场景案例
我现在有一个登陆接口A,登陆成功后返回一个token值。有一个获取用户信息的接口B,但是接口B必须要先登录后传登录的token才能访问
A接口登录接口文档基本信息- 访问地址:http://127.0.0.1:8000/api/v1/login/
- 请求类型:POST
- 请求头部:application/json
- 请求参数:{“username”:“test”, “password”:“123456”}
B接口获取绑定卡号的接口文档基本信息
- 访问地址:http://127.0.0.1:8000/api/v1/userinfo/
- 请求类型:GET
- 请求头部:Content-Type: application/json
- 请求头部token参数: Authorization: Token xxxxx login token xxxxx
先不带token去访问接口B,使用命令行工具httpie测试接口
C:\Users\dell>http http://127.0.0.1:8000/api/v1/user/info/ HTTP/1.1 401 Unauthorized Allow: GET, POST, HEAD, OPTIONS Content-Length: 58 Content-Type: application/json Date: Sat, 21 Sep 2019 14:06:15 GMT Server: WSGIServer/0.2 CPython/3.6.0 Vary: Accept WWW-Authenticate: Token X-Frame-Options: SAMEORIGIN { "detail": "Authentication credentials were not provided." }
不带token会提示没权限访问:401 Unauthorized
接口测试
先使用接口测试工具测试下,用postman,或者fiddler都可以,我这里为了查看报文信息方便,用httpie命令行工具
先访问接口A获取token值
234af73571da46ade79ea6a74961b1d23d609b79
D:\>http http://127.0.0.1:8000/api/v1/login/ username=test password=123456 -v POST /api/v1/login/ HTTP/1.1 Accept: application/json, */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 42 Content-Type: application/json Host: 127.0.0.1:8000 User-Agent: HTTPie/1.0.3 { "password": "123456", "username": "test" } HTTP/1.1 200 OK Allow: POST, OPTIONS Content-Length: 109 Content-Type: application/json Date: Sat, 21 Sep 2019 15:37:06 GMT Server: WSGIServer/0.2 CPython/3.6.0 Vary: Accept, Cookie X-Frame-Options: SAMEORIGIN { "code": 0, "msg": "login success!", "token": "234af73571da46ade79ea6a74961b1d23d609b79", "username": "test" }
传给下个接口B
D:\>http http://127.0.0.1:8000/api/v1/user/info/ Authorization:"Token b7e02c959fbae4c2a0d9094f6f9b9a35fa8aaa1e" -v GET /api/v1/user/info/ HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Authorization: Token b7e02c959fbae4c2a0d9094f6f9b9a35fa8aaa1e Connection: keep-alive Host: 127.0.0.1:8000 User-Agent: HTTPie/1.0.3 HTTP/1.1 200 OK Allow: GET, POST, HEAD, OPTIONS Content-Length: 96 Content-Type: application/json Date: Sat, 21 Sep 2019 16:04:25 GMT Server: WSGIServer/0.2 CPython/3.6.0 Vary: Accept X-Frame-Options: SAMEORIGIN { "msg": "sucess!", "code": 0, "data": [{ "id": 15, "name": "test", "sex": "F", "age": 20, "mail": "1122@qq.com", "create_time": "2020-12-18" }] }
传头部参数用xx:xxxx格式,中间用冒号:,如:
User-Agent:demo-agent/1.0 'Cookie:a=b;b=c'
,由于Authorization参数中间有空格,用双引号包起来conftest.py 代码实现
在 conftest.py 使用环境变量保存测试的结果提取的变量,使用 template 替换 yaml 文件的变量
import pytest import requests import jsonpath import json import yaml from string import Template import os # 作者-上海悠悠 QQ交流群:717225969 # blog地址 https://www.cnblogs.com/yoyoketang/ def pytest_collect_file(parent, path): # 获取文件.yml 文件,匹配规则 if path.ext == ".yml" and path.basename.startswith("test"): print(path) print(parent) return YamlFile(path, parent) class YamlFile(pytest.File): '''收集测试用例''' def collect(self): yml_raw = self.fspath.open(encoding='utf-8').read() yml_var = Template(yml_raw).safe_substitute(os.environ) yaml_data = yaml.safe_load(yml_var) for yaml_case in yaml_data: name = yaml_case.get("test").get("name") values = yaml_case.get("test") yield YamlTest(name, self, values) class YamlTest(pytest.Item): def __init__(self, name, parent, values): super(YamlTest, self).__init__(name, parent) self.name = name self.values = values self.s = requests.session() def values_render_variable(self, values): # values 是Test用例部分 yaml_test = Template(json.dumps(values)).safe_substitute(os.environ) values = yaml.safe_load(yaml_test) return values def runtest(self): # 运行用例 values = self.values_render_variable(self.values) request_data = values.get("request") print("\n请求数据: ", request_data) print(request_data) response = self.s.request(**request_data) print("接口返回", response.text) # 判断是否有extract提取参数 if values.get("extract"): for key, value in values.get("extract").items(): os.environ[key] = jsonpath.jsonpath(response.json(), value)[0] self.assert_response(response, values.get("validate")) def assert_response(self, response, validate): '''设置断言''' if validate: for i in validate: if "eq" in i.keys(): yaml_result = i.get("eq")[0] actual_result = jsonpath.jsonpath(response.json(), yaml_result) expect_result = i.get("eq")[1] print("实际结果:%s" % actual_result[0]) print("期望结果:%s" % expect_result) assert actual_result[0] == expect_result
YAML 文件案例
使用 extract 关键字提取变量,提取变量方式执行jsonpath表达式, 引用变量使用template 模板的引用语法$变量名
# 作者-上海悠悠 QQ交流群:717225969 # blog地址 https://www.cnblogs.com/yoyoketang/ - test: name: login case1 request: url: http://49.235.X.X:7000/api/v1/login/ method: POST headers: Content-Type: application/json User-Agent: python-requests/2.18.4 json: username: test password: 123456 extract: token: $.token validate: - eq: [$.msg, login success!] - eq: [$.code, 0] - test: name: get user info case1 request: url: http://49.235.X.X:7000/api/v1/userinfo/ method: GET headers: Content-Type: application/json User-Agent: python-requests/2.18.4 Authorization: Token $token validate: - eq: [$.code, 0] - eq: ["$.data[0].name", test] - eq: ["$.data[0].mail", 1122@qq.com]
执行结果
执行方式使用命令行运行,支持pytest的命令行指令
pytest
运行结果
>pytest -s ============================= test session starts ============================== platform win32 -- Python 3.6.6, pytest-4.5.0, py-1.9.0, pluggy-0.13.1 rootdir: D:\soft\api_pytest_1208 collecting ... D:\soft\api_pytest_1208\data\test_info.yml <Package D:\soft\api_pytest_1208\data> collected 2 items data\test_info.yml 请求数据: {'url': 'http://49.235.X.X:7000/api/v1/login/', 'method': 'POST', 'headers': {'Content-Type': 'application/json', 'User-Agent': 'python-requests/2.18.4'}, 'json': {'username': 'test', 'password': 123456}} {'url': 'http://49.235.X.X:7000/api/v1/login/', 'method': 'POST', 'headers': {'Content-Type': 'application/json', 'User-Agent': 'python-requests/2.18.4'}, 'json': {'username': 'test', 'password': 123456}} 接口返回 {"code": 0, "msg": "login success!", "username": "test", "token": "09be4368534fa6320ed77a333e34c6661a36d40e"} 实际结果:login success! 期望结果:login success! 实际结果:0 期望结果:0 . 请求数据: {'url': 'http://49.235.X.X:7000/api/v1/userinfo/', 'method': 'GET', 'headers': {'Content-Type': 'application/json', 'User-Agent': 'python-requests/2.18.4', 'Authorization': 'Token 09be4368534fa6320ed77a333e34c6661a36d40e'}} {'url': 'http://49.235.X.X:7000/api/v1/userinfo/', 'method': 'GET', 'headers': {'Content-Type': 'application/json', 'User-Agent': 'python-requests/2.18.4', 'Authorization': 'Token 09be4368534fa6320ed77a333e34c6661a36d40e'}} 接口返回 {"msg":"sucess!","code":0,"data":[{"id":15,"name":"test","sex":"F","age":20,"mail":"1122@qq.com","create_time":"2020-12-18"}]} 实际结果:0 期望结果:0 实际结果:test 期望结果:test 实际结果:1122@qq.com 期望结果:1122@qq.com . =========================== 2 passed in 0.49 seconds ===========================
更多相关内容 -
python接口自动化(十六)--参数关联接口后传(详解)
2020-09-19 11:04:41主要介绍了python接口自动化参数关联接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
postman参数关联
2022-01-14 11:34:062.在要提取参数的接口中,Tests页,输入以下内容: var Jsondata = JSON.parse(responseBody); pm.environment.set("data",Jsondata.data); 第一行为提取response_json,第二行为将response中的data提取到第一步...一.目的
将第一个接口的返回值,给到第二个接口使用
二.步骤
1.在postman中设置变量
2.在要提取参数的接口中,Tests页,输入以下内容:
var Jsondata = JSON.parse(responseBody); pm.environment.set("data",Jsondata.data);
第一行为提取response_json,第二行为将response中的data提取到第一步设置的环境变量中
注意:1.代码中的“data”为要提取的字段,根据实际接口设置
2.如果返回的json包含多级,需要Jsondata.XX.XX使用这个格式
3.在提取参数的接口,用{{ }}此格式调用环境变量
-
Jmeter之参数关联
2018-12-15 11:26:51json提取器关联 ... 下一步的客服发消息... 这样就可以把参数关联起来啦。 正则表达式提取 同样呢也是在需要的请求后面添加正则表达式提取器。首先我们在查看结果树里可以先输入正则表达式看有没有提取到我们...json提取器关联
1、在需要提取参数的http请求后添加Json提取器,这里我用的获取access_token这个接口。
下一步的客服发消息这个接口需要用到上面接口返回的access_token参数。参数=${变量名称}
这样就可以把参数关联起来啦。
正则表达式提取
同样呢也是在需要的请求后面添加正则表达式提取器。首先我们在查看结果树里可以先输入正则表达式看有没有提取到我们想要的数据。
备注:
1、引用名称:下一个请求要引用的参数名称,如填写title,则可用${test}引用它。
2、模板:用$*$引用起来,如果在正则表达式中有多个正则表达式,则可以是$2$,$3$等等,表示解析到的第几个值给test。如:$1$表示解析到的第1个值,我们这里只有一个正则表达式,所以是$1$
3、匹配数字:0代表随机取值,1代表第一个,-1代表每一个。
4、缺省值:如果参数没有取得到值,那默认给一个值让它取。
然后运行我们的脚本,就发现ok啦
对返回的多个值均执行下一个请求
这里我需要提取每一个openid执行下一步的获取用户信息的请求。首先还是在查看结果树里输入正则表达式看一下有没有提取到我们想要的信息。
这里我们看到openid都是以"开始,"结束。所以我们的正则表达式是:"(.*?)"
上图中可以发现Match5-Match8是我们想要的数据
下面需要添加一个ForEach控制器,在ForEach控制器下面添加获取用户信息这个请求。这里一定要注意层级关系。
然后执行脚本,可以看到前面的三个请求都只执行了一次,最后的获取用户信息的请求执行了四次。点击查看每个请求的响应数据,成功啦~
-
python接口自动化-参数关联接口
2020-05-07 12:38:39对于有些操作,是需要上一个接口返回的数据来作为当前接口的请求数据,这时候需要参数关联。 比如博客园的随笔删除操作:随笔新建成功,会返回一个id,删除这篇随笔传输它的id就可以了。 大致操作步骤:登录-新建...对于有些操作,是需要上一个接口返回的数据来作为当前接口的请求数据,这时候需要参数关联。
比如博客园的随笔删除操作:随笔新建成功,会返回一个id,删除这篇随笔请求直接传输它的id参数就可以了。
大致操作步骤:登录-打开抓包工具-新建随笔(抓包)-删除随笔(抓包)-分析删除请求的数据-分析新建随笔抓取的包-提取参数-传输参数-代码实现模拟请求删除新建任务,进行抓包
使用Charles进行抓包,看请求头部,这个请求使用的是delete的方法,请求链接后面拼接了一串数字。看返回数据只返回状态码为204,(204的意思是请求被受理但没有资源可以返回。),
请求链接后面的数字是怎么来的那,分析新建随笔的包
可以看到,新建随笔请求成功后,返回数据中包含一个"id": 12842005,这串数字与删除请求的请求链接上的数字一致。所以只要把这个数据提取出来就可以了。提取参数
我们需要的参数,是在新建随笔请求的响应数据中
将响应数据的“id”提取出来request_dict = r2.json() id_str = request_dict["id"]
传参数
上面抓包数据可以看到,提取的参数需要拼接在删除请求的链接上
因为提取的“id”是int类型,拼接时将他转换成str类型:str(id_str)
代码:
import warnings import requests warnings.filterwarnings("ignore") """根据抓取包header值,进行赋值""" x_blog_id = "#######自己抓取的header值哈" content_type = "application/json" headers = { "x-blog-id": x_blog_id, "content-type": content_type } """刷新登录页面,获取部cookie""" url = "https://passport.cnblogs.com/user/signin" s = requests.session() r = s.get(url, headers=headers, verify=False) print("登录页面刷新部分cookies", r.cookies) """添加登录需要的两个cookie""" c = requests.cookies.RequestsCookieJar() c.set(".Cnblogs.AspNetCore.Cookies", "##########自己抓取的‘.Cnblogs.AspNetCore.Cookies’") c.set(".CNBlogsoCokie", "###########自己抓取的‘.CNBlogsoCokie’") s.cookies.update(c) print("更新cookies", s.cookies) """新随笔的填写和保存在草稿箱操作""" body = '{\"id\":null,\"postType\":1,\"title\":\"testeeeeehhhhhh1\",\"url\":null,\"postBody\":\"content3\",\"categoryIds\":null,\"inSiteCandidate\":false,\"inSiteHome\":false,\"siteCategoryId\":null,\"blogTeamIds\":null,\"isPublished\":false,\"displayOnHomePage\":true,\"isAllowComments\":true,\"includeInMainSyndication\":true,\"isPinned\":false,\"isOnlyForRegisterUser\":false,\"isUpdateDateAdded\":false,\"entryName\":null,\"description\":null,\"tags\":null,\"password\":null,\"datePublished\":\"2020-04-28T14:47:05.116Z\",\"isMarkdown\":false,\"isDraft\":true,\"autoDesc\":null,\"changePostType\":false,\"blogId\":0,\"author\":null,\"removeScript\":false,\"ip\":null,\"changeCreatedTime\":false,\"canChangeCreatedTime\":false}' url_save = "https://i-beta.cnblogs.com/api/posts" r2 = s.post(url_save, headers=headers, data=body, verify=False) # 获取随笔的id request_dict = r2.json() id_str = request_dict["id"] """删除链接拼接""" url_delete1 = "https://i-beta.cnblogs.com/api/posts/" url_delete2 = url_delete1 + str(id_str) """删除请求,注意使用的是delete方法""" r3 = s.delete(url_delete1, headers=headers) print(r3.text)
接口参数关联就到这里了
总结:
- 查看接口请求需要什么参数
- 查看他的上一个接口的抓包数据,看所需参数的位置,是请求数据还是响应数据
- 提取参数(可以直接提取key-value,也可以使用正则表达式)
- 传参并请求接口(请求方法,传参数的位置:可能是链接、header、body里面)
-
基于汉语单音节语料库的音质参数和F0参数关联性研究
2021-04-17 00:52:04基于汉语单音节语料库的音质参数和F0参数关联性研究 -
postman做参数关联
2019-01-15 14:24:54先设置环境变量: 然后在获取token的的接口的Tests里面输入脚本 var Jsondata = JSON.parse(responseBody);...获取响应的数据中 token 的值,然后赋值给字符“token” 如: 响... -
loadrunner11参数化、参数配置、参数关联
2018-03-13 17:27:221、打开Virtual User Generator录制好的脚本,点击“打开... 2.2 用记事本编辑,在记事本中输入参数的值,保存 注意: (1)loadrunner记事本编辑默认为100,可以修改 C:\Program Files\HP\LoadRunner\config\... -
Katalon---参数关联
2018-04-12 16:13:44一、什么是参数关联 简单的说:就是把脚本中某些写死(固定)的数据,转变成动态的数据,或者说将前面语句的结果数据保存下来,然后在后面的语句提交请求时使用这些数据。 【需要关联的前提条件】:客户端需要从... -
python接口自动化(十五)--参数关联接口(详解)
2019-04-12 08:30:00我们用自动化新建任务之后,要想接着对这个新建任务操作,那就需要用参数关联了,新建任务之后会有一个任务的Jenkins-Crumb,获取到这个Jenkins-Crumb,就可以通过传这个任务Jenkins-Crumb继续操作这个新建的任务... -
LoadRunner 设置脚本参数关联总结
2017-10-23 11:10:58LoadRunner11 脚本关联 关联:服务器返回给客户端一些动态变化的值,客户端使用这些值去访问服务器的时候,不能把这些值写死在脚本里面,而应该存放在一个变量里面。 在脚本回放过程中,客户端发出请求,通过... -
python接口自动化26-参数关联和JSESSIONID(上个接口返回数据作为下个接口请求参数)...
2018-09-18 22:54:00参数关联是接口测试和性能测试最为重要的一个步骤,很多接口的请求参数是动态的,并且需要从上一个接口的返回值里面取出来,一般只能用一次就失效了。 最常见的案例就是网站的登录案例,很多网站的登录并不仅仅只传... -
postman环境变量,参数关联
2021-12-13 16:20:57//提取出id参数数据 创建另一个接口,完成参数关联 将vapp作为变量,该值会随着创建vapp接口返回的id值而同步更新 总结: 环境变量:是选择哪个环境就可以用的变量,一个变量只能属于某个环境,在某一个环境中变量... -
Load runner11 参数化设置,参数关联。
2019-05-18 01:21:19Load runner11 参数化设置,参数配置与关联 一,进入参数列表 打开Virtual User Generator, a>快捷键ctrl+L进入参数列表 b>菜单栏——Vuser——参数列表 二,创建参数表 三,编辑参数表 1.少量数据可直接... -
Jmeter关联实现及参数化使用解析
2020-08-18 15:09:35主要介绍了Jmeter关联实现及参数化使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
接口测试之Postman-如何进行参数关联
2019-08-04 17:19:26 在做接口测试的时候经常会遇到这样的问题,要测试的接口参数依赖其他接口的返回数据,最典型的就是需要登录token验证的接口,需要先调用登录接口,获得token,在用token去请求其他API,那这个用Postman怎么做呢?... -
利用jmeter进行接口自动化测试(http请求、参数关联)
2019-11-12 10:48:07也称之为关联参数化 引用名称: 在HTTP等请求中,引用此数据,需要用到的名称 正则表达式: 用于将需要的数据提取出来 模板: 定义在匹配数字的取值结果中,使用提取到的第几个值 $0... -
revit二开之关联族参数的实现
2019-09-20 13:28:39小伙伴们在revit二次开发时,可能需要将子族的参数关联到其所在的嵌套族,那么如何实现呢? 二、思路 先明白三件事: 1.子族在嵌套族中是以FamilyInstance的状态存在的 2.关联这件事要发生在当前嵌套族文档中 3.... -
性能测试实战(五):参数化+关联
2022-01-09 18:59:40一、变量的定义与引用 1、怎么命名变量名称 建议使用 字母、数字或下划线...3、用户参数 局部变量,启动脚本时获取一次值,在运行过程中,还会动态获取值 4、引用 ${变量名称} 二、函数 三、关联 ... -
jenkins添加关联参数
2018-04-23 18:15:34将两个参数关联起来,当选定参数A内容时,自动填写参数B的内容在Jenkins官网找到了个Active Choices插件可用(https://plugins.jenkins.io/uno-choice)1.首先用管理员账户登录Jenkins,进入系统设置页面,选择插件... -
python+pytest+yaml框架接口关联参数存储&获取
2021-12-07 15:57:48导语:以下方法是用于python+pytest+yaml框架下,多个接口之间的参数关联。例如:登录接口返回的token用于下一个接口使用。 方法一:使用os.environ来存储及获取参数 yaml文件编写如下,动态获取的参数为$sms - ... -
mybatis关联查询及多参数传值
2020-05-07 10:06:30https://blog.csdn.net/qq_39778516/article/details/84191429 ... mybatis中的关联查询 (尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_39778516/article/details/... -
三参数区间数下非线性可拓关联度决策方法
2021-01-12 22:49:09针对属性值为三参数区间数和权重未知的多属性决策问题,提出一种新的基于非线性可拓简单关联度的多属性决策方法和框架.该方法基于可拓简单关联函数提出非线性可拓三参数区间关联度的计算方法,通过定义区间映射变换... -
基于灰关联的三维表征参数与耐磨性相关性分析
2020-07-09 17:16:50根据灰色关联理论分析方法,构建了评价零件表面耐磨性指标的灰关联分析模型.通过对5种不同三维表面表征参数对耐磨性影响程度的定量分析,得出三维表征参数与耐磨性的内在相关性,并计算出三维表面表征参数对耐磨性的... -
GPmethod.rar_关联维数 matlab_关联维数参数_关联维数计算_分形维数 matlab_混沌判断
2022-07-15 16:07:32可计算关联维数,设置分形的参数,判断混沌状态 -
使用Inventor进行零件间关联设计的研究
2020-03-14 13:28:16使用Inventor进行零件间关联设计的研究,姚叶明,,本文给出了三种在Autodesk Inventor平台上进行零部件设计时零件间关联设计表达的方法,探讨典型零部件在进行零件间参数化关联设计的技� -
基于参数化关联技术的冲裁模具设计研究 (2014年)
2021-05-13 04:16:09本文研究了参数关联的理论和方法,研究了参数的传递的方法,以冲裁模具的设计为例,介绍了冲裁模具参数化关联技术的具体实现,并应用CATIA二次开发方法进行基于参数化关联技术的冲裁模具设计。实现了冲裁模具的快速设计,... -
Python调用http请求(附带json小处理)(参数关联接口处理)
2019-03-11 09:50:56Get请求小示例 #导入请求包 import requests #导入json包 import json #设置要访问的地址(这里是get...直接传入json参数即可) #导入请求包 import requests #导入json包 import json #设置要访问的地址 url = 'htt -
登录获取token,token参数关联至所有请求的请求体内
2019-03-21 01:56:02问题描述: 有些系统接口判断用户...所有接口都依赖登录成功后的token,那么可将token进行关联。本案例实现请求登录接口,获取token,将token关联至另外的get请求或post请求 实现步骤: import json import reque... -
R为参数的数据关联性分析
2018-06-12 15:51:26电流模式 升压变换器的动力学分析,以R为参数的数据关联性分析