flask create_app和setUp unittest

时间:2018-01-20 08:03:44

标签: 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

我的单位测试设置:

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()

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

  

RuntimeError:应用程序未在数据库实例上注册,并且没有应用程序绑定到当前上下文

有没有更好的方法来设置整个东西,以便它可以工作?

1 个答案:

答案 0 :(得分:3)

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

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

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

运行测试。你会看到Flask&#39; app&#39; +例外。如果删除最后一个打印件(with块之外),错误将消失。

2)如何解决问题? 您可以在没有Context Manager的情况下绑定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

运行测试:

<Flask 'app'> # from setUp()
<Flask 'app'> # from test_example

所以,让我们总结一下。 current_app仅适用于&#39;内部&#39;} Context Manager。但是你可以在没有Context Manager的情况下绑定上下文。

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