首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用g的flask pytest函数

使用g的flask pytest函数
EN

Stack Overflow用户
提问于 2017-03-23 07:09:54
回答 1查看 963关注 0票数 4

我在Flask Cookiecutter上构建了我的测试,我的所有其他测试都工作得很好。只有在测试使用g元素的函数时才会出现问题,比如views.py文件中的g.user

我的conftest.py与Flask-cookiecutter的完全相同,再加上Flask-Testing中的the faking resources and context trick

代码语言:javascript
复制
### conftest.py ###
...
from contextlib import contextmanager
from flask import appcontext_pushed, g

@contextmanager
def user_set(app, user):
    def handler(sender, **kwargs):
        g.user = user

    with appcontext_pushed.connected_to(handler, app):
        yield
...

下面是我的测试文件:

代码语言:javascript
复制
### test_file.py ###
from .conftest import user_set
import pytest
from my_app.utils import presave_posted_settings # <-- fn I want to test

@pytest.fixture()
def form_data():
    return {...bunch of data..}

@pytest.mark.usefixtures("form_data")
class TestPresaveSettings:
    """Test cases for checking attributes before saving"""
    def test_presave_posted_settings(self, form_data, user, testapp):
        """User meals are selected in form"""
        with user_set(testapp, user):  #<-- testapp and user available from flask-cookiecutter conftest.py
            assert presave_posted_settings(form_data)

当我在test_file.py上运行测试时,我看到:

代码语言:javascript
复制
user = <User 'user0'>, testapp = <webtest.app.TestApp object at 0x1101ee160>

def test_presave_posted_settings(self, form_data, user, testapp):
    """User meals are selected in form"""
    with user_set(testapp, user):
>           assert presave_posted_settings(form_data)

test_utils.py:20: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  
../my_app/utils.py:26: in presave_posted_settings
g.user.breakfast = g.user.lunch = g.user.dinner = g.user.snack = g.user.dessert = False
 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  
 self = <flask.g of 'my_app'>, name = 'user'

 def __getattr__(self, name):
    if name == '__members__':
        return dir(self._get_current_object())
>       return getattr(self._get_current_object(), name)
E       AttributeError: '_AppCtxGlobals' object has no attribute 'user'

我已经用谷歌搜索过了,大多数示例都使用Unittest,或者将所有的pytest都放在一个文件中。我想坚持拥有多个测试文件的模式,每个测试文件都利用conftest.py,但是我终生无法弄清楚如何设置它,以便可以测试使用g元素的函数。谢谢!

EN

回答 1

Stack Overflow用户

发布于 2021-08-27 17:36:37

这个问题很老了,但它与我遇到的问题最相关,我有一个简单的解决方案。

给出一个测试客户端的夹具,就像这样(宽恕温和的伪代码):

代码语言:javascript
复制
@pytest.fixture()
def test_client():
    app = create_app()
    with app.test_client() as test_client:
        with app.app_context():
            yield test_client

我试着创建一个修改g的fixture,def modify_g(test_client)认为依赖于test_client提供的上下文将使它可用。由于一些我可能不完全理解的关于pytest如何评估fixture的事情,事实并非如此。您会得到相同的'_AppCtxGlobals' object has no attribute错误。但是,如果您创建一个中间函数,那么它的计算结果是正确的,并且修改后的g对象将出现在测试上下文中。

代码语言:javascript
复制
@pytest.fixture()
def pre_test_client():
    app = create_app()
    with app.test_client() as test_client:
        with app.app_context():
            yield test_client

@pytest.fixture()
def test_client(pre_test_client):
    yield pre_test_client

@pytest.fixture()
def modify_g(pre_test_client):
    g.user = 'test'

如果定义了g,那么使用g的测试将会起作用:

代码语言:javascript
复制
def test_g_data(test_client, modify_g):

这意味着它非常容易模拟数据中的许多不同状态,并将它们作为fixture放入测试函数中。

诚然,我并不确切地理解为什么这是必要的,所以我希望能就pytest如何评估这些fixture做出任何解释。

请注意,这忽略了Flask提供的appcontext_pushed解决方案,但这是使其工作的一种非常快速和简单的方法,尽管可能不是最佳解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42964347

复制
相关文章

相似问题

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