pytest - 带有参数化会话夹具的 Pytest 集合
问题描述
我在理解 pytest 收集夹具和测试以及执行所有操作的顺序时遇到了一些麻烦,特别是传入了 `params=[]` 的 pytest 夹具。
我想分享这个例子,以及我的逻辑。
假设我有 3 个应用程序,App1
,App2
,app3
,并且对于每个应用程序,我执行 SampleSuite。SampleSuite 有 1 个类作用域夹具,可以让一些随机用户登录。在测试套件中的每个测试之前,有一个函数作用域夹具,它将执行一些导航。
这是通过这个示例test_sample.py
和一个基本pytest.ini
文件(用于记录)在下面实现的
import logging
import pytest
logger = logging.getLogger(__name__)
@pytest.fixture(scope="session", params=["App1", "App2", "App3"])
def apps_fixture(request):
""" Sets up some generic app """
logger.info(f"Setting up for app {request.param}")
yield
logger.info(f"Tearing down for app {request.param}")
@pytest.mark.usefixtures("apps_fixture", "testsuite_user_fixture", "testcase_navigation_fixture")
class TestSampleSuite:
""" Sample Suite """
@classmethod
@pytest.fixture(scope="class")
def testsuite_user_fixture(cls):
""" fixture executed once for the test suite """
logger.info("Setting up testsuite_user_fixture to sign a random user in")
yield
logger.info("Tearing down testsuite_user_fixture to sign the user out")
@classmethod
@pytest.fixture(scope="function")
def testcase_navigation_fixture(cls):
""" fixture executed before each test case """
logger.info("Setting up testcase_navigation_fixture for navigation")
yield
logger.info("Tearing down testcase_navigation_fixture")
def test_sample_1(self):
"""
A test case
"""
logger.info("Test3")
现在,当我在上面运行这个测试时,输出的顺序如下......
test_apps.py::TestSampleSuite::test_sample_1[App1]
--------------------------------- live log setup ----------------------------------
2020-09-01 15:48:59 INFO Setting up for app App1
2020-09-01 15:48:59 INFO Setting up testsuite_user_fixture to sign a random user in
2020-09-01 15:48:59 INFO Setting up testcase_navigation_fixture for navigation
---------------------------------- live log call ----------------------------------
2020-09-01 15:48:59 INFO Test3
PASSED [ 33%]
-------------------------------- live log teardown --------------------------------
2020-09-01 15:48:59 INFO Tearing down testcase_navigation_fixture
test_apps.py::TestSampleSuite::test_sample_1[App2]
--------------------------------- live log setup ----------------------------------
2020-09-01 15:48:59 INFO Tearing down for app App1
2020-09-01 15:48:59 INFO Setting up for app App2
2020-09-01 15:48:59 INFO Setting up testcase_navigation_fixture for navigation
---------------------------------- live log call ----------------------------------
2020-09-01 15:48:59 INFO Test3
PASSED [ 66%]
-------------------------------- live log teardown --------------------------------
2020-09-01 15:48:59 INFO Tearing down testcase_navigation_fixture
test_apps.py::TestSampleSuite::test_sample_1[App3]
--------------------------------- live log setup ----------------------------------
2020-09-01 15:48:59 INFO Tearing down for app App2
2020-09-01 15:48:59 INFO Setting up for app App3
2020-09-01 15:48:59 INFO Setting up testcase_navigation_fixture for navigation
---------------------------------- live log call ----------------------------------
2020-09-01 15:48:59 INFO Test3
PASSED [100%]
-------------------------------- live log teardown --------------------------------
2020-09-01 15:48:59 INFO Tearing down testcase_navigation_fixture
2020-09-01 15:48:59 INFO Tearing down testsuite_user_fixture to sign the user out
2020-09-01 15:48:59 INFO Tearing down for app App3
从我在此输出中看到的内容来看,会话范围固定装置apps_fixture
会为每个传递的参数(如预期的那样)设置和拆除,但类范围固定装置testsuite_user_fixture
仅在整个运行过程中设置和拆除一次。(这对我来说是令人困惑的部分)
我所期待的是,testsuite_user_fixture
将为每个传递的参数设置和拆除,因为类的范围比会话小。
至于我的调查,我在 pytest 文档或谷歌周围没有找到太多帮助。我确实发现使用 pytests 会--collect-only
分享一些有趣的细节。运行后pytest test_apps.py --collect-only
收集的结构看起来像这样......
<Module test_apps.py>
<Class TestSampleSuite>
<Function test_sample_1[App1]>
<Function test_sample_1[App2]>
<Function test_sample_1[App3]>
这让我对为什么每个参数只设置和拆除一次班级固定装置有一些了解,但我不明白为什么。我试图调试它并了解 pytest 如何收集所有这些,但我迷失在了一堆钩子中。
注意:testsuite_user_fixture
如果我在测试运行期间有 2 个或更多类,则工作正常,因为每个类都会在从apps_fixture
. 因此,仅在运行 1 个测试类时才会出现问题。
对于传入参数的夹具,我找不到关于 pytest 的优秀文档,所以我希望在这里能找到一些帮助。所以我的问题是......
是否可以根据为会话范围夹具传递的参数运行类范围夹具?
解决方案
推荐阅读
- javascript - 为移动和桌面加载不同的 JS 文件
- java - JSON 列表中的变量名称后跟对象详细信息
- android - 关闭android应用程序时如何播放视频
- sql - pgSQL 在 SELECT 查询之前在其函数中显示错误
- php - Symfony 4 形式 - 变量形式不存在
- c# - 是否可以在启动时显示 DisplayAlert (Xamarin.Forms)
- npm - NPM `EACCES` 错误,不能通过更改默认目录来修复
- php - SocialEngine:使用 Zend_Db_Table_Row_Abstract::save() 更新密码
- javascript - 当用户在 React 中单击窗口上的后退按钮时,将道具传递给您来自的组件
- c# - OpenID Connect AAD 用户模拟