Flask-Script在运行unittests之前加载应用程序

时间:2016-02-08 18:04:18

标签: python flask python-unittest flask-script

我使用Flask-Script在我的应用程序上运行测试,manage.py文件的重要部分如下所示:

import unittest

from flask.ext.script import Manager
from project import app

manager = Manager(app)

@manager.command
def test():
    """Run unit tests."""
    app.config.from_object('config.Test')
    tests = unittest.TestLoader().discover('tests', pattern='*.py')
    unittest.TextTestRunner(verbosity=1).run(tests)

但是当我运行python manage.py test时,它会尝试初始化整个应用程序,因此,例如,如果我没有设置我的环境变量,它会从我的项目中抛出KeyError __init__.py这样的文件:

File "project/__init__.py", line 19, in <module> app.config.from_object(os.environ['PROJECT_SETTINGS'])

或者,如果我设置了环境变量,则会收到有关缺少数据库表的错误。

当然,只有在测试运行且配置变量已在test()函数中设置时,应用程序才应初始化。

1 个答案:

答案 0 :(得分:1)

要使其发挥作用,您需要做一些事情。

  1. 设置缺少的环境变量(就像您已经说过的那样)。

  2. 为要使用的测试创建测试数据库,并让测试包含setupteardown函数,这些函数分别创建表并删除它们。

  3. 为了解决第一步,我建议使用Flask application factory pattern,它允许您将应用程序创建封装在一个函数中。这将允许您传入在测试环境下运行应用程序所需的任何变量等,例如。

    def create_application(is_test=False):
        app = Flask(__name__)
        if not is_test:
           setup_app_not_for_test(app)
        else:
           setup_test_for_app(app)
    
        return app
    

    关于步骤2,如果您使用pytest或nose或任何使用fixture的测试框架,您可以轻松添加setupteardown函数来添加/删除数据库表。此外,如果您使用像sqlalchemy这样的ORM,您可以非常轻松地创建SQLite in memory database来运行您的测试。

    # create db instance
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite://:memory:"
    
    # create all your tables
    db.create_all()
    
    # drop all your tables
    db.drop_all()