一、前言

  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 - 实现参数化驱动的更多相关文章

  1. pytest_参数化3

    import pytesttest_user_data=[ {'user':'linda','password':'8888'}, {'user':'servenruby','password':'1 ...

  2. HttpRunner_参数化进阶

    一.获取返回包数据   在提取参数时,当 HTTP 的请求响应结果为 JSON 格式,则可以采用.运算符的方式,逐级往下获取到参数值:响应结果的整体内容引用方式为 content 或者 body,如上 ...

  3. TestNG进行接口测试,脚本及可维护性框架

    注: 以下内容引自http://blog.csdn.net/u010321474/article/details/49977969 TestNG进行接口测试,脚本及可维护性框架 原创 2015年11月 ...

  4. Selenium自动化测试Python三:WebDriver进阶

    WebDriver 进阶 欢迎阅读WebDriver进阶讲义.本篇讲义将会重点介绍Selenium WebDriver API的重点使用方法,以及使用模块化和参数化进行自动化测试的设计. WebDri ...

  5. jdbc大略

    一.概述JDBC JDBC从物理结构上说就是Java语言访问数据库的一套接口集合. 从本质上来说就是调用者(程序员)和实现者(数据库厂商)之间的协议. JDBC API: 使得开发人员可以使用纯Jav ...

  6. 行为驱动:Cucumber + Selenium + Java(四) - 实现测试用例的参数化

    在上一篇中,我们介绍了Selenium + Cucumber + Java框架下的使用Tags对测试用例分组的实现方法,这一篇我们用数据表格来实现测试用例参数化. 4.1 什么是用例参数化 实际测试中 ...

  7. 行为驱动:Cucumber + Java - 实现数据的参数化

    1.什么是参数化 实际设计测试用例过程中,我们经常会用等价类.边界值这样的方法,针对一个功能进行测试数据上的测试,比如一个输入框,正向数据.逆向数据,非法输入等等 2.Cucumber的数据驱动 同上 ...

  8. httprunner3.x全网最详细教程

    一.所需环境 wiindows10以上 python3.6以上 httprunner3.1.6(最新版本) pycharm社区版 二.安装httprunner 1.卸载旧版本 卸载之前版本的命令为:p ...

  9. [转]DDD领域驱动设计基本理论知识总结

    领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...

随机推荐

  1. [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎

    [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎 目录 [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎 0x00 摘要 0x01 前言 1.1 ...

  2. JS011. 身份证号码校验(仅34行)

    身份证格式 六位数字地址码 + 八位数字出生日期码 + 三位数字顺序码 + 一位数字校验码 checkIdCard.js checkIdCard: function (idCard){ //15位和1 ...

  3. centos7关于防火墙的一些操作

    防火墙相关 # 检查防火墙状态 systemctl status firewalld # 开启防火墙 systemctl start firewalld # 关闭防火墙 systemctl stop ...

  4. python基础--网站推荐

    Python教程 - 廖雪峰的官方网站 Python 基础教程 | 菜鸟教程 随笔分类 - 机器学习

  5. Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用

    原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...

  6. 机器学习——EM算法

    1 数学基础 在实际中,最小化的函数有几个极值,所以最优化算法得出的极值不确实是否为全局的极值,对于一些特殊的函数,凸函数与凹函数,任何局部极值也是全局极致,因此如果目标函数是凸的或凹的,那么优化算法 ...

  7. PHP的zip压缩工具扩展包学习

    总算到了 PHP 的拿手好戏上场了,前面我们学习过 Bzip2 . LZF . Phar 和 rar 这些压缩相关扩展在 PHP 中的使用,不过它们要么是太冷门,要么就是很多功能不支持.而 Zip 则 ...

  8. PHP的引用计数是什么意思?

    什么是引用计数 在PHP的数据结构中,引用计数就是指每一个变量,除了保存了它们的类型和值之外,还额外保存了两个内容,一个是当前这个变量是否被引用,另一个是引用的次数.为什么要多保存这样两个内容呢?当然 ...

  9. Docker系列(27)- 容器互联--link

    思考 思考一个场景,我们编写了一个微服务,database url=IP:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以使用名字来进行访问容器吗 实践 [root@localhost ...

  10. SourceTree使用详解-摘录收藏

    前言: 非原创,好文收录,原创作者:追逐时光者 俗话说的好工欲善其事必先利其器,Git分布式版本控制系统是我们日常开发中不可或缺的.目前市面上比较流行的Git可视化管理工具有SourceTree.Gi ...