HttpRunner3.X - 实现参数化驱动
一、前言
HttpRunner3.X支持三种方式的参数化,参数名称的定义分为两种情况:
- 独立参数单独进行定义;
- 多个参数具有关联性的参数需要将其定义在一起,采用短横线(-)进行连接。
数据源指定支持三种方式:
- 列表:["张三", "李四", "王五"] —— 这种属于直接指定参数列表,该种方式最为简单易用,适合参数列表比较小的情况
- debugtalk.py的回调,${get_styleCode()} —— 调用 debugtalk.py 中自定义的函数生成参数列表:该种方式最为灵活,可通过自定义 Python 函数实现任意场景的数据驱动机制,当需要动态生成参数列表时也需要选择该种方式
- Parameterize类的回调,例如csv:${parameterize(account.csv)} ——注:这种适合数据量比较大的情况,后面会换一种方式实现
假如测试用例中定义了多个参数,那么测试用例在运行时会对参数进行笛卡尔积组合,覆盖所有参数组合情况。
如果使用过pytest的参数化的小伙伴一定不会陌生,@pytest.mark.parametrize()会先将param作为一个动态参数,传递给param,然后由httprunner在进行参数化,httprunner在pytest的parametrize上封装了一层,增加了csv及debugtalk.py参数化的支持。
二、源码介绍Parameters 中的使用方法
- def parse_parameters(parameters: Dict,) -> List[Dict]:
- """ parse parameters and generate cartesian product.
- Args:
- parameters (Dict) parameters: parameter name and value mapping
- parameter value may be in three types:
- (1) data list, e.g. ["iOS/10.1", "iOS/10.2", "iOS/10.3"]
- (2) call built-in parameterize function, "${parameterize(account.csv)}"
- (3) call custom function in debugtalk.py, "${gen_app_version()}"
- Returns:
- list: cartesian product list
- Examples:
- >>> parameters = {
- "user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"],
- "username-password": "${parameterize(account.csv)}",
- "app_version": "${gen_app_version()}",
- }
- >>> parse_parameters(parameters)
- """
- parsed_parameters_list: List[List[Dict]] = []
三、实例讲解
1、前置工作
1)httprunner3.x中的参数化需要引入pytest和处理参数化的函数
- import pytest
- from httprunner import Parameters
2)选取某个查询接口作为例子
POST https://xxx.mand/contract/page
- {
- "styleCode": "",
- "purchaserNameLike": "",
- "status": "",
- "pageNum": 1,
- "pageSize": 20,
- }
2、第一种列表:笛卡尔积组合
2个入参进行了参数化,以下示例,运行后得到的用例执行次数是2*3,如图1所示,
- # NOTE: Generated By HttpRunner v3.1.5
- # FROM: har\search.har
- # 参数化驱动
- import self as self
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase,Parameters
- import pytest
- from config.ExcelUtiltest import ParseExcel
- class TestCaseSearch(HttpRunner):
- @pytest.mark.parametrize("param", Parameters({"styleCode": ['S21001061', 'S21000597'],"purchaserNameLike":['测试','南京公司','测试2']}))
- def test_start(self, param):
- super().test_start(param)
- config = Config("参数化搜索").verify(False)
- teststeps = [
- Step(
- RunRequest("搜索接口")
- .post("https://xxx.mand/web/v1/contract/page")
- .with_headers(
- **{
- "Connection": "keep-alive",
- "Content-Length": "249",
- }
- )
- .with_json(
- {
- "styleCode": "$styleCode",
- "purchaserNameLike": "$purchaserNameLike",
- "status": "",
- "pageNum": 1,
- "pageSize": 20,
- }
- )
- .validate()
- .assert_equal("status_code", 200)
- .assert_equal('headers."Content-Type"', "application/json")
- .assert_equal("body.successful", True)
- .assert_equal("body.code", "200")
- .assert_equal("body.message", "请求成功")
- ),
- ]
- if __name__ == "__main__":
- TestCaseSearch().test_start()
图1:笛卡尔积组合 即n*m
3、第二种debugtalk.py的回调函数
在debugtalk.py中定义一个函数,返回列表
- def get_styleCode():
- return [
- {'styleCode':'S21001217'},
- {'styleCode': 'S21001211'},
- ]
在searchdriver_test.py文件调用,运行后的结果如图2所示,
- # NOTE: Generated By HttpRunner v3.1.5
- # FROM: har\search.har
- # 参数化驱动
- import self as self
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase,Parameters
- import pytest
- from config.ExcelUtiltest import ParseExcel
- class TestCaseSearch(HttpRunner):
- @pytest.mark.parametrize("param",Parameters({'styleCode':'${get_styleCode()}'}))
- def test_start(self, param):
- super().test_start(param)
- config = Config("参数化搜索").verify(False)
- teststeps = [
- Step(
- RunRequest("搜索接口")
- .post("https://xxx.mand/web/v1/contract/page")
- .with_headers(
- **{
- "Connection": "keep-alive",
- "Content-Length": "249",
- }
- )
- .with_json(
- {
- "styleCode": "$styleCode",
- "purchaserNameLike": "",
- "status": "",
- "pageNum": 1,
- "pageSize": 20,
- }
- )
- .validate()
- .assert_equal("status_code", 200)
- .assert_equal('headers."Content-Type"', "application/json")
- .assert_equal("body.successful", True)
- .assert_equal("body.code", "200")
- .assert_equal("body.message", "请求成功")
- ),
- ]
- if __name__ == "__main__":
- TestCaseSearch().test_start()
图2:调用debugtalk
4、第三种excel文件作为参数化输入
1)根据网上查的资料,httprunner3.x可以用.csv作为数据源,写法如下,.csv如图3所示,
- csv的路径要使用相对路径,不支持绝对路径不支持\\符号的路径,csv映射的时候,参数名要以“-”分割,name和pwd使用的-进行分割
疑问点:我在用这种方式时,会提示参数类型不正确,想不明白为什么别人可以运行成功呢,哈哈哈
- @pytest.mark.parametrize("param",Parameters({"styleCode-purchaserNameLike": "${parameterize(testdata\styleCode.csv)}"}))
- def test_start(self, param):
- super().test_start(param)
图3:.csv文件
2)踩了坑后,经过别人的指点下(这个装饰器只接收list类型的),所以决定写个读取excel的方法,并转换成list,然后用例直接调用即可
在config文件下新建ExcelUtiltest.py(excel封装参考https://www.cnblogs.com/du-hong/p/10892379.html)
- #封装解析excel的方法
- from openpyxl import load_workbook
- class ParseExcel:
- def __init__(self,excelPath,sheetName):
- # 将要读取excel加载到内存
- self.wb=load_workbook(excelPath)
- # 通过工作表名获取一个工作表对象
- #self.sheet=self.wb.get_sheet_by_name(sheetName)
- self.sheet = self.wb[sheetName]
- # 获取工作表中存在数据的区域最大行号
- self.maxRowNum=self.sheet.max_row
- def getDatasFromSheet(self):
- # 存放从表中取出的数据
- datalist=[]
- for line in list(self.sheet.rows)[1:]:
- # 遍历工作表中数据区域每一行
- tmplist=[]
- tmplist.append(line[1].value)
- tmplist.append(line[2].value)
- datalist.append(tmplist)
- print(datalist)
- return datalist
- '''if __name__ == '__main__':
- #excelPath = 'E:\\03UI test\\UnittestProject\\TestData\\search_data_list.xlsx'
- excelPath = 'E:\\05\\api_test\\testdata\\styleCode.xlsx'
- sheetName=u'Sheet1'
- pe = ParseExcel(excelPath, sheetName)
- for i in pe.getDatasFromSheet():
- print(i[0],i[1])'''
在用例文件searchdriver_test.py进行调用(这里直接用Parameters,如有多个参数,用横杠-),excel文件如图4所示,运行结果如图5所示
- # NOTE: Generated By HttpRunner v3.1.5
- # FROM: har\search.har
- # 参数化驱动
- import self as self
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase,Parameters
- import pytest
- from config.ExcelUtiltest import ParseExcel
- class TestCaseSearch(HttpRunner):
- data = ParseExcel('E:\\05\\api_test\\testdata\\styleCode.xlsx','Sheet1')
- datalist = data.getDatasFromSheet()
- #下面是为了方便理解,直接指定的list数据
- #@pytest.mark.parametrize('param',Parameters({'styleCode-purchaserNameLike':[['S21001170','南京公司'],['S21001213','南京公司']]}),)
- @pytest.mark.parametrize('param', Parameters({'styleCode-purchaserNameLike': datalist}), )
- def test_start(self, param):
- super().test_start(param)
- config = Config("参数化搜索").verify(False)
- teststeps = [
- Step(
- RunRequest("查询接口")
- .post("https://xxx.mand/web/v1/contract/page")
- .with_headers(
- **{
- "Connection": "keep-alive",
- }
- )
- .with_json(
- {
- "styleCode": "$styleCode",
- "purchaserNameLike": "$purchaserNameLike",
- "status": "",
- "pageNum": 1,
- "pageSize": 20,
- }
- )
- .validate()
- .assert_equal("status_code", 200)
- .assert_equal('headers."Content-Type"', "application/json")
- .assert_equal("body.successful", True)
- .assert_equal("body.code", "200")
- .assert_equal("body.message", "请求成功")
- ),
- ]
- if __name__ == "__main__":
- TestCaseSearch().test_start()
图4:excel文件数据
图5:excel参数化运行结果
HttpRunner3.X - 实现参数化驱动的更多相关文章
- pytest_参数化3
import pytesttest_user_data=[ {'user':'linda','password':'8888'}, {'user':'servenruby','password':'1 ...
- HttpRunner_参数化进阶
一.获取返回包数据 在提取参数时,当 HTTP 的请求响应结果为 JSON 格式,则可以采用.运算符的方式,逐级往下获取到参数值:响应结果的整体内容引用方式为 content 或者 body,如上 ...
- TestNG进行接口测试,脚本及可维护性框架
注: 以下内容引自http://blog.csdn.net/u010321474/article/details/49977969 TestNG进行接口测试,脚本及可维护性框架 原创 2015年11月 ...
- Selenium自动化测试Python三:WebDriver进阶
WebDriver 进阶 欢迎阅读WebDriver进阶讲义.本篇讲义将会重点介绍Selenium WebDriver API的重点使用方法,以及使用模块化和参数化进行自动化测试的设计. WebDri ...
- jdbc大略
一.概述JDBC JDBC从物理结构上说就是Java语言访问数据库的一套接口集合. 从本质上来说就是调用者(程序员)和实现者(数据库厂商)之间的协议. JDBC API: 使得开发人员可以使用纯Jav ...
- 行为驱动:Cucumber + Selenium + Java(四) - 实现测试用例的参数化
在上一篇中,我们介绍了Selenium + Cucumber + Java框架下的使用Tags对测试用例分组的实现方法,这一篇我们用数据表格来实现测试用例参数化. 4.1 什么是用例参数化 实际测试中 ...
- 行为驱动:Cucumber + Java - 实现数据的参数化
1.什么是参数化 实际设计测试用例过程中,我们经常会用等价类.边界值这样的方法,针对一个功能进行测试数据上的测试,比如一个输入框,正向数据.逆向数据,非法输入等等 2.Cucumber的数据驱动 同上 ...
- httprunner3.x全网最详细教程
一.所需环境 wiindows10以上 python3.6以上 httprunner3.1.6(最新版本) pycharm社区版 二.安装httprunner 1.卸载旧版本 卸载之前版本的命令为:p ...
- [转]DDD领域驱动设计基本理论知识总结
领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...
随机推荐
- (五)羽夏看C语言——结构体与类
写在前面 由于此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇 ...
- Install Docker Engine on CentOS 在CentOS 7 上安装Docker
Install Docker Engine on CentOS OS Requirements 系统要求 To install Docker Engine,you need a maintained ...
- Redis消息的发布与订阅
- DPDK应用示例指南简介(汇总)
DPDK应用示例指南简介 <DPDK示例>系列文章主要是学习.记录.翻译DPDK官方示例文档.为了更好地理解和学习DPDK, 特通过对源码中的经典示例进行整理,供大家学习.交流和讨论. A ...
- vue+element+echarts饼状图+可折叠列表
html: <div id="echartsDiv" style="width: 48%; height: 430px; float: left;"> ...
- Typora + PicGo做个人知识库
最近在做个人知识库,考察了一圈各种平台和工具,发现还是直接用文件系统管理Markdown文件更符合我当前的需求.以Markdown文件作为文字载体,以文件目录作为分类结构,承载以计算机知识为主的学习笔 ...
- window server 2008 系统加固
1.更改管理员账号: 开始->运行->compmgmt.msc(计算机管理)->本地用户和组->用户,右击Administrator账户并选择"重命名",并 ...
- 将rgb表示方式转换为hex表示方式-------------将hex表示方式转换为rgb表示方式(这里返回rgb数组组合)
/** * kevin 2021.1.4 * 将rgb表示方式转换为hex表示方式 * @param {string} rgbColor 传过来的hex格式的颜色 * @returns { ...
- Java反序列化漏洞Apache CommonsCollections分析
Java反序列化漏洞Apache CommonsCollections分析 cc链,既为Commons-Collections利用链.此篇文章为cc链的第一条链CC1.而CC1目前用的比较多的有两条链 ...
- 在PHP中使用SPL库中的对象方法进行XML与数组的转换
虽说现在很多的服务提供商都会提供 JSON 接口供我们使用,但是,还是有不少的服务依然必须使用 XML 作为接口格式,这就需要我们来对 XML 格式的数据进行解析转换.而 PHP 中并没有像 json ...