2017-10-19 1 views
0

Flask + SQLAlchemyアプリケーションをテストするのにPytestを使用しています。これは、私はあなたがpop()への呼び出しとして、あなたのティアダウン機能でctx.pop()を呼び出すことになっているとは思わない、私はpytestを実行すると、私はこのエラーメッセージRecursionError:最大再帰深度がFlask Pytestを超えました

___________________ ERROR at teardown of test_create_project ___________________ 

exception = None 

    @_app.teardown_appcontext 
    def teardown(exception=None): 
>  ctx.pop() 

tests/conftest.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../.virtualenvs/quest-backend/lib/python3.6/site-packages/flask/ctx.py:189: in pop 
    self.app.do_teardown_appcontext(exc) 
../../.virtualenvs/quest-backend/lib/python3.6/site-packages/flask/app.py:1892: in do_teardown_appcontext 
    func(exc) 
tests/conftest.py:31: in teardown 
    ctx.pop() 
E RecursionError: maximum recursion depth exceeded 
!!! Recursion detected (same locals & position) 

答えて

1

は、ここで私はあなたのappフィクスチャを書き換える方法は以下のようになります

@pytest.fixture(scope='session') 
def app(): 
    _app = create_app() 
    _app.debug = False 

    _app.engine = create_engine(_app.config['SQLALCHEMY_DATABASE_URI'], connect_args={"options": "-c timezone=utc"}) 
    # session should probably not be global?.. 
    DbSession = scoped_session(
     sessionmaker(), 
     scopefunc=_app_ctx_stack.__ident_func__ 
    ) 
    DbSession.configure(bind=_app.engine, query_cls=BaseQuery) 

    # Establish an application context before running the tests. 
    ctx = _app.app_context() 
    ctx.push() 

    # this function is specifically for app's teardown, don't call it again for fixture teardown 
    @_app.teardown_appcontext 
    def teardown(exception=None): 
     if DbSession: 
      DbSession.remove() 

    # here is where tests will be executed 
    yield _app 

    # now tear-down our fixture (as apposed to flask app's teardown) 
    ctx.pop() 

あなたが内側のスコープ内からグローバル変数に値を代入する場合を除き、globalキーワードを使用する必要はありません。

3

を取得tests/contftest.py

import pytest 
from sqlalchemy import create_engine 
from sqlalchemy.orm import scoped_session, sessionmaker 
from flask import _app_ctx_stack 
from flask.ext.sqlalchemy import SQLAlchemy, BaseQuery 
from package.myapp import create_app 
from package.config import DefaultConfig 

DbSession = scoped_session(
     sessionmaker(), 
     scopefunc=_app_ctx_stack.__ident_func__ 
    ) 
@pytest.fixture(scope='session') 
def app(request): 
    _app = create_app() 
    _app.debug = False 

    _app.engine = create_engine(_app.config['SQLALCHEMY_DATABASE_URI'], connect_args={"options": "-c timezone=utc"}) 
    global DbSession 
    DbSession.configure(bind=_app.engine, query_cls=BaseQuery) 

    # Establish an application context before running the tests. 
    ctx = _app.app_context() 
    ctx.push() 

    @_app.teardown_appcontext 
    def teardown(exception=None): 
     ctx.pop() 
     global DbSession 
     if DbSession: 
      DbSession.remove() 


    request.addfinalizer(teardown) 
    return _app 

の内容です登録されたティアダウンコールバックが呼び出されます(したがって、AppContextは、Flask.do_teardown_appcontext()を呼び出します。

for func in reversed(self.teardown_appcontext_funcs): 
    func(exc) 

器具を破壊するときは、ctx.pop()に電話する必要があります。ローマKutlakの答えを拡大

関連する問題