参数化方式有三种,以下面的登录接口为例
from httprunner import HttpRunner, Config, Step, RunRequest
class TestCaseLogin(HttpRunner):
config = Config('hrun3_demo').base_url('http://xxx:9090').export(*['vars_name'])
teststeps = [
Step(
RunRequest('login')
.post('/xxx/login.html')
.with_headers(**{'X-Requested-With': 'XMLHttpRequest'})
.with_data({'accounts':'ss','pwd':'123456'})
.extract()
.with_jmespath('body.msg','value_msg')
.validate()
.assert_equal('body.msg','登录成功')
.assert_equal('body.code',0)
)
]
if __name__ == '__main__':
TestCaseLogin().test_start()
1.装饰器
- 声明:
在使用参数化之前,首先要导入pytest包,和httprunner的Parameters这个类
使用httprunner改造过的pytest参数化,通过parameters这个字段去引用
注意:需结合 test_start()方法使用
如果声明多个参数值,那么用例数会是笛卡尔积后的数量,我这里只声明一个参数值
@pytest.mark.parametrize(
'param',
Parameters(
{
'base_url':['http://xxx:9090'],
'url':['/xxx/login.html'],
'accounts':['ss'],
'pwd':['123456']
}),
)
def test_start(self, param):
super().test_start(param)
- 引用
使用$base_url,$url,$accounts,$pwd 方式引用参数,下面是完整代码
from httprunner import HttpRunner, Config, Step, RunRequest
import pytest
from httprunner import Parameters
class TestCaseLogin(HttpRunner):
@pytest.mark.parametrize(
'param',
Parameters(
{
'base_url':['http://xxx:9090'],
'url':['/xxx/login.html'],
'accounts':['ss'],
'pwd':['123456']
}),
)
def test_start(self, param):
super().test_start(param)
config = Config('hrun3_demo').base_url('$base_url').export(*['vars_name'])
teststeps = [
Step(
RunRequest('login')
.post('$url')
.with_headers(**{'X-Requested-With': 'XMLHttpRequest'})
.with_data({'accounts':'$accounts','pwd':'$pwd'})
.extract()
.with_jmespath('body.msg','value_msg')
.validate()
.assert_equal('body.msg','登录成功')
.assert_equal('body.code',0)
)
可以看到 headers没有参数化,因为 目前headers像url 那样参数化调不通
.with_headers(**'$headers')时会报错,当然按道理来讲应该可以调用的
这个就放在第三种参数化方式里实现吧
2.csv文件
通过外部csv文件进行参数化,将 csv 文件放到项目的根目录(也可以在该目录下指定相对路径,比如data/*.csv)
这部分url 我先不参数化,只参数化用户名和密码
- 一对一参数化
data.csv 文件如下:
data里是两组测试用例[bull,123456] [ss,123456]
注意 csv里不同字段用“,”分隔
声明的时候把参数用 “- ”关联
'accounts-pwd': '${parameterize(data.csv)}'
@pytest.mark.parametrize(
'param',
Parameters(
{
'accounts-pwd': '${parameterize(data.csv)}'
}),
)
def test_start(self, param):
super().test_start(param)
引用还是使用$accounts,$pwd,完整代码如下:
from httprunner import HttpRunner, Config, Step, RunRequest
import pytest
from httprunner import Parameters
class TestCaseLogin(HttpRunner):
@pytest.mark.parametrize(
'param',
Parameters(
{
'accounts-pwd': '${parameterize(data.csv)}'
}),
)
def test_start(self, param):
super().test_start(param)
config = Config('hrun3_demo').base_url('http://xxx:9090').export(*['vars_name'])
teststeps = [
Step(
RunRequest('login')
.post('/xxx/login.html')
.with_headers(**{'X-Requested-With': 'XMLHttpRequest'})
.with_data({'accounts':'$accounts','pwd':'$pwd'})
.extract()
.with_jmespath('body.msg','value_msg')
.validate()
.assert_equal('body.msg','登录成功')
.assert_equal('body.code',0)
)
]
if __name__ == '__main__':
TestCaseLogin().test_start()
运行如下,因为有一个用户名不存在,所以一个成功一个失败:
3.debugtalk.py
- 定义
在debugtalk.py中定义get_user()函数,返回列表,两组测试用例,一组成功一组失败
再将 header 进行参数化,定义 get_headers()函数
# @File: debugtalk.py
def get_user():
return [
{'accounts': 'ss', 'pwd': '123456'},
{'accounts': 'bull', 'pwd': ''}
]
def get_headers():
headers={
'X-Requested-With': 'XMLHttpRequest'
}
return headers
- 调用
debugtalk.py的回调
get_user()调用,${gen_user()}
@pytest.mark.parametrize(
'param',
Parameters(
{
'accounts-pwd': '${get_user()}'
}),
)
def test_start(self, param):
super().test_start(param)
headers 调用,直接导入get_headers 方法
from hrun_demo.mtx_demo.debugtalk import get_headers
然后.with_headers(**get_headers())
完整代码如下:
from httprunner import HttpRunner, Config, Step, RunRequest
import pytest
from httprunner import Parameters
from hrun_demo.mtx_demo.debugtalk import get_headers
class TestCaseLogin(HttpRunner):
@pytest.mark.parametrize(
'param',
Parameters(
{
'accounts-pwd': '${get_user()}'
}),
)
def test_start(self, param):
super().test_start(param)
config = Config('hrun3_demo').base_url('http://xxx:9090').export(*['vars_name'])
teststeps = [
Step(
RunRequest('login')
.post('/xxx/login.html')
.with_headers(**get_headers())
.with_data({'accounts':'$accounts','pwd':'$pwd'})
.extract()
.with_jmespath('body.msg','value_msg')
.validate()
.assert_equal('body.msg','登录成功')
.assert_equal('body.code',0)
)
]
if __name__ == '__main__':
TestCaseLogin().test_start()
三种方式实现原理
@pytest.mark.parametrize()会先将param作为一个动态参数,传递给param,然后由httprunner再进行参数化,httprunner在pytest的parametrize上封装了一层,增加了csv和debugtalk.py参数化的支持