pytest实现⽤例间参数传递的两种⽅式
我们在做接⼝⾃动化测试的时候,会经常遇到这种场景:接⼝A的返回结果中的某个字段,是接⼝B的某个字段的⼊参。如果是使⽤postman,那我们可以通过设置后置变量,然后在需要使⽤的地⽅通过{{}}的⽅式来进⾏调⽤。但是如果是使⽤⾃⼰写的测试框架中要如何实现呢?我想到的是如下三种⽅法。
⾸先说明⼀下,以下三种⽅式均是通过python + pytest来实现的
⼀、通过conftest创建全局变量
conftest.py⽂件是pytest框架中很有⽤的⼀个东西,⾸先看下官⽅⽂档中的解释:
⼤概意思就是说,conftest.py⽂件供整个⽤例⽬录(conftest.py⽂件可以有多个,并且只在当前package下⽣效)使⽤⽽⽆需导⼊,也就是说在⽤例⽬录是conftest中的信息是公⽤的,例如:
a/conftest.py:
def pytest_runtest_setup(item):
# called for running each test in 'a' directory
print("setting up", item)
a/test_sub.py:
def test_sub():
pass
test_flat.py:
def test_flat():
pass
运⾏后的结果:
pytest test_flat.py --capture=no  # will not show "setting up"
pytest a/test_sub.py --capture=no  # will show "setting up"
⽽我们就可以通过conftest + fixture函数来实现我们想要的效果了,具体代码如下:
# conftest.py
# 定义⼀个全局变量,⽤于存储内容
global_data = {}
@pytest.fixture
def set_global_data():
"""
设置全局变量,⽤于关联参数
:return:
"""
def _set_global_data(key, value):
global_data[key] = value
return _set_global_data
python怎么读取py文件
@pytest.fixture
def get_global_data():
"""
从全局变量global_data中取值
:return:
"""
def _get_global_data(key):
return (key)
return _get_global_data
简单说⼀下实现逻辑:
1. ⾸先定义⼀个变量global_data⽤于接收存储⽤例返回的结果
2. set_global_data和get_global_data两个fixture⽅法顾名思义,set⽅法是往global_data中存数据,get⽅法是从global_data中取数据⽅法实现了,具体应该怎么使⽤呢?如下:
# test_get_set.py
import requests
import pytest
def test_set(set_global_data):
res = ("www.baidu")
status_code = res.status_code
logger.info(f"请求返回状态码:{status_code}")
set_global_data("status_code", status_code)
def test_get(get_global_data):
data = get_global_data("status_code")
logger.info(f'通过get_global_data⽅法获取的值:{data}')
if __name__ == '__main__':
pytest.main(['-sv', 'test_get_set.py'])
返回结果:
test_get_set.py::test_set PASSED
2021-12-24 17:58:37.642 | INFO    | st_get_set:test_set:19 - 请求返回状态码:200
2021-12-24 17:58:37.643 | INFO    | st_get_set:test_get:25 - 通过get_global_data⽅法获取的值:200
test_get_set.py::test_get PASSED
============================== 2 passed in 0.06s ===============================
通过这种⽅式,便实现了⽤例间的参数传递问题。
在实际⼯作中,因为涉及到的接⼝、⽤例会很多,所以可以根据需要使⽤不同的conftest进⾏管理。并且存储的数据结构也需要进⾏规范区分,如使⽤⽅法名作为字典的key。
⼆、使⽤tmpdir_factory⽅法
第⼆种⽅法,是使⽤pytest的tmpdir和tmpdir_factory两个夹具函数,同样是通过conftest⽂件来实现。仍然是先来看下官⽅⽂档针对这两个⽅法的说明:
简单来说,这两个⽅法的作⽤就是为每个测试⽅法创建⼀个临时⽬录⽤于存储⾃定义的⽂件,这个临时⽬录会默认保存3个sessions,之后就会按照创建的顺序删除旧的⽬录。看下官⽅的例⼦:
# content of test_tmpdir.py
def test_create_file(tmpdir):
p = tmpdir.mkdir("sub").join("")
p.write("content")
ad() == "content"
assert len(tmpdir.listdir()) == 1
assert 0
# contents of conftest.py
import pytest
@pytest.fixture(scope="session")
def image_file(tmpdir_factory):
img = compute_expensive_image()
fn = tmpdir_factory.mktemp("data").join("img.png")
img.save(str(fn))
return fn
# contents of test_image.py
def test_histogram(image_file):
img = load_image(image_file)
# compute and test histogram
我在实际项⽬中的使⽤:
1. 仍是在conftest.py⽂件中⾃定义⼀个夹具函数,返回结果是⼀个元组,p是tmpdir_factory⽅法返回的对象,转为字符串之后就是⽂
件存储的路径。
⾃定义⼀个名为“apitest-tmp-dir”的⽂件夹⽤于存储⽂件
# conftest.py
@pytest.fixture
def tmp_factory(tmpdir_factory):
"""
⽣成临时⽬录
"""
p = tmpdir_factory.mktemp('apitest-tmp-dir')
logger.info("当前临时⽂件的⽬录为:" + str(p))
return p, str(p)
1. 在测试⽅法中的使⽤
# test_get_set.py
import requests
import pytest
import json
def test_set(tmp_factory):
res = ("www.baidu")
status_code = res.status_code
logger.info(f"返回状态码:{status_code}")
logger.debug(tmp_factory)
# 创建⽂件
a = tmp_factory[0].join("")
# 将需要的内容写⼊到⽂件中
a.write({"status_code": status_code})
# 使⽤read()⽅法获取⽂件中的内容
logger.ad())
if __name__ == '__main__':
pytest.main(['-sv', 'test_get_set.py'])
返回结果:
test_get_set.py::test_set 2021-12-24 18:24:39.292 | INFO    | ftest:tmp_factory:150 - 当前临时⽂件的⽬录为:/private/var/folders/_f/1d0lt83x1599bf6mc 2021-12-24 18:24:39.347 | INFO    | st_get_set:test_set:32 - 返回状态码:200
2021-12-24 18:24:39.347 | DEBUG    | st_get_set:test_set:34 - (local('/private/var/folders/_f/1d0lt83x1599bf6mcfppbwp40000gn/T/pytest-of-j/pytest-19/ap 2021-12-24 18:24:39.348 | DEBUG    | st_get_set:test_set:38 - {'status_code': 200}
PASSED
============================== 1 passed in 0.07s ===============================
创建的⽂件:
可以看到,tmpdir_factory会⾃动为我们创建⼀个⽬录,名字是`tmp_factory`⽅法中⾃定义的名称后⾯加0,同时它的上级⽬录会⾃动从
pytest-0递增
1. 说下这个办法的优缺点:
1. 先说优点,这种数据存储是直接写⼊到⽂件,因此即使运⾏结束后也可以访问,⽽不像第⼀种⽅法存储的内容会随着⽤例运⾏的
结束⽽消失
2. 再说缺点,因为这个临时⽬录最多只能保存3个,因此如果⽤例很多时,那么就可能存在⽂件被⾃动
删除的风险。不过这个貌似
可以通过修改默认配置来解决,可以继续研究下。
3. 缺点⼆,上⾯的例⼦中,直接通过a.read()就访问到了⽂件中的内容,这是因为内容的存储与读取全是在⼀个⽅法内,因此可以
直接调⽤。如果是A⽅法存结果,在B中需要读取,那么便不能直接使⽤read()⽅法了(因为每个⽅法都会创建⼀个⽬录,并且
默认的读取地址都是这个⽅法⾃⼰创建的⽬录)。就需要我们⾃⼰去单独封装⼀个读取⽂件的⽅法了,实现起来也不难⽽且
tmpdir本⾝的这些⽅法也是对os.path⼀些⽅法的⼆次封装。
2. 话说回来,都需要我⾃⼰去封装⼀个读取⽂件的⽅法了,为啥不⼲脆把读、写都⾃⼰来做呢?这样是否删除⽂件、删除⼏个、什么时

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。