烧瓶 create_app 和 setUp 单元测试

Har*_*ith 5 database unit-testing flask

所以我以这种方式设置了我的烧瓶:

def create_app(config_name):
    app = Flask(__name__, static_folder='../designs/UI', template_folder='../designs/UI', instance_relative_config=True)

    app.config.from_object(app_config[config_name])
    app.config.from_pyfile('config.py')

    db.init_app(app)

    login_manager.init_app(app)
    login_manager.login_message = "You must be logged in to access this page."
    login_manager.login_view = "auth.login_page"

    migrate = Migrate(app, db)

    from app import models

    from .api import blueprint as api_blueprint
    app.register_blueprint(api_blueprint, url_prefix='/api/v1.0')

    @app.route('/')
    def homepage():
        return redirect('/api/v1.0')

    return app
Run Code Online (Sandbox Code Playgroud)

我的单元测试设置:

def setUp(self):
    """setup test variables"""
    self.app = create_app(config_name="testing")
    self.client = self.app.test_client

    # binds the app with the current context
    with self.app.app_context():
        #create all tables
        db.session.close()
        db.drop_all()
        db.create_all()
Run Code Online (Sandbox Code Playgroud)

当我将模型导入测试文件并尝试访问数据库中的任何内容时,出现以下错误:

运行时错误:应用程序未在数据库实例上注册并且没有应用程序绑定到当前上下文

有没有更好的方法来设置整个事情以便它可以工作?

Dan*_*har 7

我决定详细解释这个问题(和解决方案)。

1)为什么你的方式不起作用? 因为您尝试app context使用Context Manager进行推送。这是什么意思?current context将仅在with块内可用。您绑定context并且他仅在 中可用setUp,而在测试中不可用。app将不工作contextsetUp()完成。让我们看看这个例子:

app = Flask(__name__)

class TestCase(TestCase):

    def setUp(self):
        with app.app_context():
            # current_app is available(you will see <Flask 'app'> in terminal)
            print current_app
        # out of context manager - RuntimeError: Working outside of application context.
        print current_app

    def test_example(self):
        pass
Run Code Online (Sandbox Code Playgroud)

运行测试。你会看到 Flask 'app' + 异常。如果您删除最后一次打印(with块外),该错误将消失。

2)如何解决问题? 您可以在app context没有上下文管理器的情况下进行绑定。

class TestCase(TestCase):

    def setUp(self):
        ctx = app.app_context()
        ctx.push()
        # after this you can use current_app
        print current_app

    def test_example(self):
        # available because we pushed context in setUp()
        print current_app
Run Code Online (Sandbox Code Playgroud)

运行测试:

<Flask 'app'> # from setUp()
<Flask 'app'> # from test_example
Run Code Online (Sandbox Code Playgroud)

所以,让我们总结一下。current_app仅在“内部”上下文管理器中可用。但是您可以在没有上下文管理器的情况下绑定上下文。

我希望我已经解释了细节并回答了你的问题。