我不知道如何在使用 with_app_context
装饰器进行单元测试(使用 pytest)flask cli 命令(使用单击)时正确使用测试应用程序版本。这个装饰器用“正常”的开发应用程序替换了 pytest fixture app。我使用应用工厂模式。
我在简化版本中的命令如下所示(注意 @with_appcontext
):
@click.command()
@click.option('--username', prompt='Username')
@click.option('--email', prompt='User E-Mail')
@click.option('--password', prompt='Password', confirmation_prompt=True, hide_input=True)
@with_appcontext # from flask.cli import with_appcontext
def createsuperuser(username, email, password):
user = User(
username=username,
email=email,
password=password,
active=True,
is_admin=True,
)
user.save()
没有 @with_appcontext
单元测试工作得很好(他们通过 pytest 注入(inject)应用程序),但命令本身没有,因为它需要一个应用程序上下文。
我提取的 pytest 代码:
# pytest fixtures
@pytest.yield_fixture(scope='function')
def app():
"""An application for the tests."""
_app = create_app(TestConfig)
ctx = _app.test_request_context()
ctx.push()
yield _app
ctx.pop()
@pytest.yield_fixture(scope='function')
def db(app):
"""A database for the tests."""
_db.app = app
with app.app_context():
_db.create_all()
yield _db
# Explicitly close DB connection
_db.session.close()
_db.drop_all()
@pytest.mark.usefixtures('db')
class TestCreateSuperUser:
# db fixture uses app fixture, works the same if app was injected here as well
def test_user_is_created(self, cli_runner, db):
result = cli_runner.invoke(
createsuperuser,
input='johnytheuser\nemail@email.com\nsecretpass\nsecretpass'
)
assert result.exit_code == 0
assert 'SUCCESS' in result.output
# etc.
我使用 app
和 db
fixtures 的所有测试除了这些修饰的之外都工作得很好。我不确定我应该如何解决这个设置应用程序本身的 with_appcontext
装饰器。
预先感谢您的任何提示。
最佳答案
灵感来自 https://github.com/pallets/flask/blob/master/tests/test_cli.py#L254 .
from flask.cli import ScriptInfo
@pytest.fixture
def script_info(app):
return ScriptInfo(create_app=lambda info: app)
在你的测试中:
def test_user_is_created(self, cli_runner, db, script_info):
result = cli_runner.invoke(
createsuperuser,
input='johnytheuser\nemail@email.com\nsecretpass\nsecretpass',
obj=obj,
)
关于python - Flask 单击命令单元测试 - 如何使用带有 "with_appcontext"装饰器的测试应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44428447/