python - Flask 单击命令单元测试 - 如何使用带有 "with_appcontext"装饰器的测试应用程序?

标签 python unit-testing flask command-line-interface pytest

我不知道如何在使用 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.

我使用 appdb 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/

相关文章:

python - 使用python将每个字符串列表的最后一个字符加倍

javascript - 测试 HTML5 网站的最佳方法是什么?

python - 作用域 session 上的事件监听器

unit-testing - React/TypeScript 的 Jest 配置问题

javascript - 为 JavaScript 应用程序创建测试数据的最佳方式是什么?

Python QuerySelectField 和 request.form 返回字典键,而不是字典值

dns - 创建本地自定义主机名而不是 localhost?

python - 如果 AppEngine 应用程序使用 GCS,那么该应用程序的用户如何上传大文件?

python - Django中邮箱验证的实现

python - 如何阻止 asyncio 中的进程