gpt4 book ai didi

python - pytest:以 DRY 方式参数化设备

转载 作者:行者123 更新时间:2023-12-04 16:45:25 27 4
gpt4 key购买 nike

使用 Pytest 固定装置,我正在寻找一种将设置覆盖传递给我的应用程序固定装置的方法,这样我就可以测试不同的设置而无需定义不同的固定装置。

在为 Flask 创建测试时,我使用的一种常见模式是初始化应用程序和数据库,如下所示。请注意 db fixture 硬编码 app固定装置作为参数。

from myapp import create_app

@pytest.fixture
def app():
settings_override = {} # By setting values here, I can pass in different Flask config variables
app = create_app(settings_override)
return app

@pytest.fixture
def db(app):
do_something_to_create_the_database(app) # app needed for context
yield db


然后,许多测试可能会使用上面定义的 fixture ,例如。
def test_my_application_1(db, app):
...

def test_my_application_2(db, app):
...

假设我想用不同的设置初始化应用程序装置,并且假设我可以将这些设置传递到上面定义的 create_app() 函数中。在每次测试的基础上,如何附加 appdb固定装置,以便我可以将设置覆盖传递给 app fixture ?有没有办法可以在测试用例级别参数化 fixture ,以便我可以将不同的设置传递给 fixture ?

IE。
# for this test, I want to pass the BAZ=True setting to the app fixture. 
def test_my_application_1(db, app):
...

# for this test, I want to pass FOO=BAR setting to the app fixture
def test_my_application_2(db, app):
...

我感谢您提供的任何建议。

更新:来自@mrbean-bremen 的解决方案

感谢@MrBean Bremen 提供了优雅的解决方案。通过使用 hasattr 稍作修改,我能够扩展解决方案以接受参数覆盖或接受默认值。
@pytest.fixture(scope='function')
def app(request):
settings_override = {
'SQLALCHEMY_DATABASE_URI': "sqlite:///:memory:",
}
params = request.param if hasattr(request, 'param') else {}
return create_app({**settings_override, **params})


@pytest.fixture(scope='function')
def db(app):
with app.app_context():
....


def test_without_params(db, app):
...


@pytest.mark.parametrize("app", [{'DEBUG': True}], indirect=True)
def test_with_overrides(db, app):
...


最佳答案

您可以尝试将设置作为字典参数传递给 fixture ,如下所示:

import pytest
from myapp import create_app

@pytest.fixture
def app(request):
settings_override = {
'SQLALCHEMY_DATABASE_URI': "sqlite:///:memory:",
}
params = request.param if hasattr(request, 'param') else {}
return create_app({**settings_override, **params})

@pytest.fixture
def db(app):
do_something_to_create_the_database(app)
yield db

def test_my_application_no_override_params(db, app):
...

@pytest.mark.parametrize("app", [{'BAZ': True}], indirect=True)
def test_my_application_1(db, app):
...

@pytest.mark.parametrize("app", [{'FOO': 'BAR'}], indirect=True)
def test_my_application_2(db, app):
...
request object 使 fixture 可以访问请求的测试上下文,并且可以用作任何 fixture 中的参数。 indirect=True pytest.mark.parametrize 中的参数装饰器将参数传递给可选的 param request 的属性对象,因此这实质上是对 fixture 本身进行参数化。

更新:
我添加了@JoeJ 提出的有用的添加(使用 hasattr ),这使得可以在没有附加参数的情况下使用测试。

关于python - pytest:以 DRY 方式参数化设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61330200/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com