首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用url_for函数为瓶测试客户端生成URL

用url_for函数为瓶测试客户端生成URL
EN

Stack Overflow用户
提问于 2017-10-09 12:34:49
回答 2查看 6.1K关注 0票数 9

我试着用pytest为一个烧瓶应用程序编写单元测试。我有一个应用程序工厂:

代码语言:javascript
复制
def create_app():
    from flask import Flask
    app = Flask(__name__)
    app.config.from_object('config')
    import os
    app.secret_key = os.urandom(24)
    from models import db
    db.init_app(app)
    return app

还有一堂测试课:

代码语言:javascript
复制
class TestViews(object):

    @classmethod
    def setup_class(cls):
        cls.app = create_app()
        cls.app.testing = True
        cls.client = cls.app.test_client()

    @classmethod
    def teardown_class(cls):
        cls.app_context.pop()

    def test_create_user(self):
        """
        Tests the creation of a new user.
        """
        view = TestViews.client.get(url_for('create_users')).status_code == 200

但是,当我运行测试时,我会得到以下错误:

代码语言:javascript
复制
RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available.

谷歌这告诉我(我认为)使用测试客户端应该创建一个自动的应用程序上下文。我遗漏了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-09 12:51:57

使用测试客户端发出请求确实会(间接地)推送应用程序上下文。但是,您混淆了这样一个事实,即url_for在测试请求调用中是视觉上的,而它实际上是在内部调用的。首先计算url_for调用,然后将结果传递给client.get

url_for通常用于在应用程序中生成URL,单元测试是外部的。通常,您只需在请求中准确地编写要测试的URL,而不是生成它。

代码语言:javascript
复制
self.client.get('/users/create')

如果您真的想在这里使用url_for,您必须在应用程序上下文中这样做。注意,当您在应用程序上下文中而不是请求上下文中时,您必须设置SERVER_NAME配置并传递_external=False。但是,您可能应该写出您想要测试的URL。

代码语言:javascript
复制
app.config['SERVER_NAME'] = 'localhost'

with self.app.app_context():
    url = url_for(..., _external=False)

self.client.get(url, ...)
票数 12
EN

Stack Overflow用户

发布于 2021-02-22 10:40:33

您可以在用url_for()方法创建的测试请求上下文中调用app.test_request_context()。实现这一目标的方法有三种。

用设置和拆卸

由于您已经创建了安装和拆卸方法,就像我通常对unittest所做的一样,您可以在安装方法中推送一个测试请求上下文,然后在teardown方法中弹出它:

代码语言:javascript
复制
class TestViews(object):

    @classmethod
    def setup_class(cls):
        cls.app = create_app()
        cls.app.testing = True
        cls.client = cls.app.test_client()
        cls.context = cls.app.test_request_context()  # create the context object
        cls.context.push()  # push the context

    @classmethod
    def teardown_class(cls):
        cls.context.pop()  # pop the context

    def test_create_user(self):
        """
        Tests the creation of a new user.
        """
        view = TestViews.client.get(url_for('create_users')).status_code == 200

用热瓶

此外,您也可以使用热瓶。使用pytest-flask,您可以访问上下文绑定对象(url_for、request、session),而无需上下文管理器:

代码语言:javascript
复制
def test_app(client):
    assert client.get(url_for('myview')).status_code == 200

自置夹具

如果您不想安装这个插件,您可以使用下面的固定装置来做类似的事情(从pytest-烧瓶的源头偷来的):

代码语言:javascript
复制
@pytest.fixture
def app():
    app = create_app('testing')
    return app


@pytest.fixture(autouse=True)
def _push_request_context(request, app):
    ctx = app.test_request_context()  # create context
    ctx.push()  # push

    def teardown():
        ctx.pop()  # pop

    request.addfinalizer(teardown)  # set teardown
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46646603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档