pytest合集6— Fixture夹具
一、关于夹具
1、夹具介绍
简单来说,pytest中的夹具就是用来实现测试前的环境准备,提供测试数据和测试后的环境清理动作。类似于unittest框架里的setup(前置处理),teardown(后置处理)。
常用在测试环境搭建和销毁,测试数据的共享,登录登出操作,数据库连接和关闭,浏览器打开关闭等操作。
2、夹具特点
- fixture固定装置,也叫夹具,下文都称呼为夹具。
- 使用 @pytest.fixture 可以将一个函数标记成夹具。
- 夹具本质上是函数,测试函数显示调用来使用夹具。
- 夹具的名称不要用test开头。
- 夹具可以定义在conftest.py文件中。
- 可以在测试函数,测试类,模块,甚至session会话级别使用夹具。
- 测试函数可以使用一个或者多个夹具,夹具也可以使用夹具,这才是fixture夹具功能真正强大的地方。
- pytest查找夹具的顺序:测试类>>测试模块>> conftest.py 文件>>内置插件和第三方插件。
3、夹具的简单使用
新建 test_fixture.py 文件如下:
import pytest
@pytest.fixture def myfixture(): print("this is myfixture") return True def test_one(myfixture): assert myfixture is True
运行命令:pytest test_fixture.py -vs
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>pytest test_fixture.py -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271', 'foo': 'bar'}rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testfixture
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 1 itemtest_fixture.py::test_one this is myfixture PASSED
=================================== 1 passed in 0.03s ===================================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>
说明:
测试函数test_one 使用myfixture作为参数,pytest 运行时候,会先查找并运行它参数的同名夹具myfixture,打印出了"this is my fixture",并且捕获到了夹具的返回值 True。
夹具执行过程(官网说明):
在基本层面上,测试函数通过将它们声明为参数来请求它们所需的夹具。
当 pytest 开始运行测试时,它会查看该测试函数签名中的参数,然后搜索与这些参数具有相同名称的夹具。一旦 pytest 找到它们,它就会运行这些固定装置,捕获它们返回的内容(如果有的话),并将这些对象作为参数传递给测试函数。
二、定义夹具
使用@pytest.fixture装饰器可以将测试函数标记成夹具,可以在测试用例文件中定义夹具,也可以在conftest.py文件中定义夹具,推荐使用conftest.py文件定义夹具。
1、fixture参数
fixture它有5个参数,分别是scope, params, autouse, ids, name。
@
fixture
(fixture_function=None, *, scope='function', params=None, autouse=False, ids=None, name=None)
scope:
作用域参数,他有4个级别分别是 function,class,module,session,默认function。
- function:函数级别,默认范围,夹具在测试结束时被销毁。
- class:类级别,夹具在类中最后一个测试结束时被销毁。
- module:模块级别,夹具在.py文件中最后一个测试结束时被销毁
- session:会话级别,夹具在测试会话结束时被销毁。
params:
一个可选的参数列表,默认值为None,可以用来实现 参数化,参数化的时候这里需要用到一个参数request,使用“request.param”来接受请求参数列表,进而实现参数化。
ids:
字符串列表,与params配合使用,如果没有提供 id,它们将从参数中自动生成。
autouse:
默认值False ,需要显式引用来激活夹具。如果为TRUE,则所有测试函数都可以使用该夹具(慎用)。
name:
夹具名称默认取的是被定义成夹具的函数名称,可以修改这个参数来修改夹具名称,需要注意的是,只能使用修改后的夹具名,不能使用原来的夹具函数名。
2、yield和return的区别
夹具中可以使用return,yield关键字为测试函数提供值,推荐使用yield关键字,他们的区别如下:
- yield返回值后,后面的代码还会继续运行
- return返回值后,后面的代码不会继续运行
三、使用夹具
1、function函数级别,将夹具名作为测试函数参数的入参(显示调用)
新建conftest.py配置文件如下,定义一个function级别的夹具。
-
import pytest
-
-
-
-
def myfixture_function():
-
print("开始加载function级别夹具")
-
yield 100
-
print("开始退出function级别夹具")
修改test_fixture.py文件如下:
-
def test_one(myfixture_function):
-
assert myfixture_function == 100
文件目录结构如下:
进入testfixture目录,运行命令:pytest -vs
Microsoft Windows [版本 10.0.19044.1889]
(c) Microsoft Corporation。保留所有权利。(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>pytest -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271', 'foo': 'bar'}rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testfixture
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 1 itemtest_fixture.py::test_one 开始加载function级别夹具
PASSED开始退出function级别夹具
=================================== 1 passed in 0.05s ===================================(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>
可知,function级别的夹具在显示调用该夹具的测试用例执行完后销毁。
2、class类级别,使用mark标记装饰器@pytest.mark.userfixtures
语法糖:
pytest.mark.usefixtures(*args)
*args – The names of the fixture to use, as strings.
看到装饰器的参数就能晓得,usefixtures可以和一个或者多个fixture配合使用。
修改conftest.py配置文件如下,新增一个class级别的夹具。
-
import pytest
-
-
-
-
def myfixture_function():
-
print("开始加载function级别夹具")
-
yield 100
-
print("开始退出function级别夹具")
-
-
-
-
def myfixture_class():
-
print("开始加载class级别夹具")
-
yield 200
-
print("开始退出class级别夹具")
修改test_fixture.py文件如下:
-
import pytest
-
-
-
def test_one(myfixture_function):
-
assert myfixture_function == 100
-
-
-
-
class TestFixture:
-
-
def test_two(self, myfixture_function):
-
assert myfixture_function == 100
-
-
def test_three(self):
-
pass
进入testfixture目录,运行命令:pytest -vs
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>pytest -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271', 'foo': 'bar'}rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testfixture
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 3 itemstest_fixture.py::test_one 开始加载function级别夹具
PASSED开始退出function级别夹具test_fixture.py::TestFixture::test_two 开始加载class级别夹具
开始加载function级别夹具
PASSED开始退出function级别夹具test_fixture.py::TestFixture::test_three PASSED开始退出class级别夹具
=================================== 3 passed in 0.07s ===================================(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>
可知,class级别的夹具在测试类中所有测试用例执行完后销毁。
3、module模块级别,使用pytestmark
修改conftest.py配置文件如下,新增一个module级别的夹具。
-
import pytest
-
-
-
-
def myfixture_function():
-
print("开始加载function级别夹具")
-
yield 100
-
print("开始退出function级别夹具")
-
-
-
-
def myfixture_class():
-
print("开始加载class级别夹具")
-
yield 200
-
print("开始退出class级别夹具")
-
-
-
-
def myfixture_module():
-
print("开始加载module级别夹具")
-
yield 300
-
print("开始退出module级别夹具")
修改test_fixture.py文件如下:
-
import pytest
-
-
pytestmark = pytest.mark.usefixtures('myfixture_module')
-
-
-
def test_one(myfixture_function):
-
assert myfixture_function == 100
-
-
-
-
class TestFixture:
-
-
def test_two(self, myfixture_function):
-
assert myfixture_function == 100
-
-
def test_three(self):
-
pass
进入testfixture目录,运行命令:pytest -vs
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>pytest -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271', 'foo': 'bar'}rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testfixture
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 3 itemstest_fixture.py::test_one 开始加载module级别夹具
开始加载function级别夹具
PASSED开始退出function级别夹具test_fixture.py::TestFixture::test_two 开始加载class级别夹具
开始加载function级别夹具
PASSED开始退出function级别夹具test_fixture.py::TestFixture::test_three PASSED开始退出class级别夹具
开始退出module级别夹具
=================================== 3 passed in 0.08s ===================================(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>
可知,module级别的夹具在测试文件中所有用例执行完成后销毁。
4、session会话级别,autouse=True
修改conftest.py配置文件如下,新增一个session级别的夹具。这里需要注意参数 autouse=True会话级别的夹具才能生效。
-
import pytest
-
-
-
-
def myfixture_function():
-
print("开始加载function级别夹具")
-
yield 100
-
print("开始退出function级别夹具")
-
-
-
-
def myfixture_class():
-
print("开始加载class级别夹具")
-
yield 200
-
print("开始退出class级别夹具")
-
-
-
-
def myfixture_module():
-
print("开始加载module级别夹具")
-
yield 300
-
print("开始退出module级别夹具")
-
-
-
-
def myfixture_session():
-
print("开始加载session级别夹具")
-
yield 400
-
print("开始退出session级别夹具")
在testfixture目录中新建test_sample.py文件如下:
-
def test_session(myfixture_function):
-
assert myfixture_function == 100
进入testfixture目录,运行命令:pytest -vs
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>pytest -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271', 'foo': 'bar'}rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testfixture
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 4 itemstest_fixture.py::test_one 开始加载session级别夹具
开始加载module级别夹具
开始加载function级别夹具
PASSED开始退出function级别夹具test_fixture.py::TestFixture::test_two 开始加载class级别夹具
开始加载function级别夹具
PASSED开始退出function级别夹具test_fixture.py::TestFixture::test_three PASSED开始退出class级别夹具
开始退出module级别夹具test_sample.py::test_session 开始加载function级别夹具
PASSED开始退出function级别夹具
开始退出session级别夹具
=================================== 4 passed in 0.09s ===================================(venv) C:\Users\057776\PycharmProjects\pytest-demo\testfixture>
可知,session级别的夹具在pytest运行完所有测试用例后销毁。
四、使用夹具(进阶)
1、夹具参数化
params:一个可选的参数列表,默认值为None,可以用来实现 参数化,参数化的时候这里需要用到一个参数request,使用“request.param”来接受请求参数列表,进而实现参数化。
2、夹具中使用其它夹具
pytest 的最大优势之一是其极其灵活的夹具系统。它允许我们将复杂的测试需求归结为更简单和有组织的功能,我们只需要让每个功能描述它们所依赖的东西。
例如下面的例子,新建test_append.py文件,在夹具order中使用了夹具first_entry。
import pytest # Arrange @pytest.fixture def first_entry(): return "a" # Arrange @pytest.fixture def order(first_entry): return [first_entry] def test_string(order): # Act order.append("b") # Assert assert order == ["a", "b"]
3、多个测试函数重复使用一个夹具
夹具可以重复使用,这是pytest功能强大的另外一个原因。不同的测试函数可以请求相同的夹具,并让 pytest 为每个测试提供来自该夹具的自己的结果,这样夹具就可以提供一致的、可重复的结果给不同的测试函数使用。
例如下面的例子,修改test_append.py文件,2个测试函数test_string,test_int都使用了夹具order。
import pytest # Arrange @pytest.fixture def first_entry(): return "a" # Arrange @pytest.fixture def order(first_entry): return [first_entry] def test_string(order): # Act order.append("b") # Assert assert order == ["a", "b"] def test_int(order): # Act order.append(2) # Assert assert order == ["a", 2]
4、测试函数使用多个夹具
测试函数或者夹具中也可以使用多个夹具,例如下面的例子,修改test_append.py文件如下:
import pytest # Arrange @pytest.fixture def first_entry(): return "a" # Arrange @pytest.fixture def second_entry(): return 2 # Arrange @pytest.fixture def order(first_entry, second_entry): return [first_entry, second_entry] # Arrange @pytest.fixture def expected_list(): return ["a", 2, 3.0] def test_string(order, expected_list): # Act order.append(3.0) # Assert assert order == expected_list
5、使用request内置夹具读取上下文信息
request是给请求测试函数提供信息的特殊夹具。请求夹具,来自测试函数或者夹具函数。请求对象允许访问请求测试函数上下文,并且在间接参数化夹具的情况下具有可选的“param”属性。
-
import pytest
-
-
data = [1, 2, 3]
-
-
-
-
def myfixture(request):
-
return request.param, request.config
-
-
-
def test_one(myfixture):
-
print(myfixture)
reference:
API Reference — pytest documentation
How to use fixtures — pytest documentation
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcgfce
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01