Pytest.参数化
参数化在自动化测试里算是一个耳熟能详的概念了,那么pytest框架是怎么应用它的呢?之前在pytest.fixture脚手架一文中有说过fixture的构造有params,这个也可以起到参数化的作用。本文讲的是ParametrizeMarkDecorator装饰器。
举个最简单的例子,格式如下:
参数化的一个好处是,每条用例都是独立的,单独运行的,第一条报错,不会影响第二条的运行。
import pytest
@pytest.mark.parametrize("test_input", ["1 2", "2-1"])
def test_eval(test_input):
assert eval(test_input) == 3
参数化的另外一个好处是,可以一个参数,也可以多个参数。
import pytest
@pytest.mark.parametrize("test_input,expected", [
["1 2", 3],
["2-1", 2],
])
def test_eval(test_input, expected):
assert eval(test_input) == expected
如果入参很多,是一个多参数的json,dict等等,会导致测试代码不整洁。比如:
import pytest
@pytest.mark.parametrize("test_input, expected", [
[{"username": "test1", "password": "123"}, {"resCode": 200, "message": "login success"}],
[{"username": "test1", "password": ""}, {"resCode": 200, "message": "用户名或密码错误!"}],
[{"username": "", "password": "123"}, {"resCode": 200, "message": "用户名或密码错误!"}],
[{"username": "", "password": ""}, {"resCode": 200, "message": "用户名或密码错误!"}],
[{"username": "test1", "password": "321"}, {"resCode": 200, "message": "用户名或密码错误!"}],
])
def test_login(test_input, expected):
... # 断言
如果这个py文件的用例很多,想去修改其中某个场景的入参或预期结果,这么找下去会很麻烦,如果改错用例还得去找。
那么我们是不是可以把这些输入输出隔离出来?
有人说只要在外部定一个变量即可。
import pytest
data = [
[{"username": "test1", "password": "123"}, {"resCode": 200, "message": "login success"}],
[{"username": "test1", "password": ""}, {"resCode": 200, "message": "用户名或密码错误!"}],
[{"username": "", "password": "123"}, {"resCode": 200, "message": "用户名或密码错误!"}],
[{"username": "", "password": ""}, {"resCode": 200, "message": "用户名或密码错误!"}],
[{"username": "test1", "password": "321"}, {"resCode": 200, "message": "用户名或密码错误!"}],
]
@pytest.mark.parametrize("test_input, expected", data)
def test_login(test_input, expected):
... # 断言
这么写也没问题,但还是在一个py文件里,并没有达到数据隔离的真正目的。
这里我们可以重写一个文件,看数据是什么格式的,我们可以在用例同级目录下新建一个json文件,把data按list格式直接复制过去就好。但是json文件规范,比如必须是双引号,如果你的测试data里是单引号,还需要转换一下。
json文件写好后,我们需要写一个方法取驱动用例来读取测试数据。这个公共方法就是读取所在路径下的把json类型转换成适配用例的dict或者list等等。
新建一个py文件,写一个公共方法:
import json
def read_json_data(file_path="data.json"):
with open(file_path, "rb") as f:
r = json.load(f)
return r
if __name__ == '__main__':
obj = read_json_data("data.json")
print(obj)
测试用例里再引用这个公共方法即可读取json文件作为测试data了
import pytest
from apitest_dev.read_data import read_json_data
data = read_json_data("data.json")
# print(data)
# print(type(data))
@pytest.mark.parametrize("input_test, expected", data)
def test_login(input_test, expected):
...
这么看是不是更简洁明了,层次清晰?
如果测试数据格式用yaml,那么可以在这个公共方法py文件里再增加上读取yaml文件的方法即可。
代码如下:
def read_yaml_data(file_path="test_data.yml"):
if not os.path.isfile(file_path):
raise FileNotFoundError(f"文件{file_path}不存在,请检查文件名或路径是否正确")
with open(file_path, "rb") as f:
r = yaml.safe_load(f)
return r
再说下mark标签的,如何选择性的执行case,发一串伪代码:
@pytest.mark.login
def test_login_1():
...
def test_login_2():
...
@pytest.mark.register
def test_register_1():
...
@pytest.mark.register
def test_register_2():
...
这里给每条用例做了标签,register的用例我都想执行,而login的用例只想执行login_1,mark标签按上面这么写。同时需要配置pytest.ini,不配ini会有warning提示:
pytest.ini配置这么写:
[pytest]
markers =
login: login case
register: register case
[pytest]表示这里都是pytest的配置,冒号后面的可以不写,相当于注释。但是login和register必须是换行的,否则无效。
最后执行用例py文件pytest -m “login"或者文件内部main执行pytest.main([”-s", “-m login”, “xx.py”]),也支持多个mark,这里不再赘述了。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhiebbhf
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
excel图片置于文字下方的方法
PHP中文网 06-27 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
excel下划线不显示怎么办
PHP中文网 06-23 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22 -
微信提示登录环境异常是什么意思原因
PHP中文网 04-09