我们正在使用一些自定义命令扩展Flask-cli。命令test
就是其中之一:
# run.py: specified by FLASK_APP
# This is the Flask application object
app = create_app(os.getenv('FLASK_ENV') or 'default')
@app.cli.command()
def test():
"""Run the unit tests."""
tests = unittest.TestLoader().discover('tests')
test_runner = unittest.TextTestRunner()
test_runner.run(tests)
然而,典型的测试(使用Python的内置unittest模块)看起来像是基于here描述的风格。
# some-tests.py: unittest-based test case.
class SomeTestCase(unittest.TestCase):
def setUp(self):
self.app = create_app('testing')
self.app_context = self.app.app_context()
self.app_context.push()
def tearDown(self):
self.app_context.pop()
def test_load(self):
pass
我显然在这里遇到了一个反模式:我用默认的(development
)配置初始化了一个烧瓶对象,因为我需要它用于@app.cli.command()
装饰器,这一切都发生在run.py
。然而,一旦我在some-tests.py
中运行测试setUp函数,我就不得不使用testing
配置获得Flask对象,例如通过使用testing
配置重新创建Flask应用程序,就像现在发生的那样。
我想指出如何实现一个flask-cli
测试命令,其中只创建了一个Flask
对象,它在各种测试用例中重用,而不需要在我运行testing
之前明确地将环境设置为flask test
。命令行。
我不确定这个答案是否符合您的要求,但这就是我试图解决这个问题的方法。不幸的是,如果你想在Flask中使用默认的CLI界面,你需要调用create_app
来调用flask test
命令。你可以做的是尝试使用pytest
。它允许您创建可在多个测试用例中使用的夹具。例如,在你的tests
包中创建一个名为conftest.py
的文件并声明一些默认的装置,如下所示:
@pytest.fixture
def app():
return create_app('testing')
@pytest.fixture
def client(app):
return app.test_client()
@pytest.fixture
def database(app):
_db.app = app
with app.app_context():
_db.create_all()
yield _db
_db.session.close()
_db.drop_all()
然后在您的测试用例文件(例如test_login.py)中,您可以使用这样的灯具:
# Notice argument names are the same as name of our fixtures
# You don't need to import fixtures to this file - pytest will
# automatically recognize fixtures for you
def test_registration(app, client):
response = client.post(
'/api/auth/login',
json={
'username': 'user1',
'password': '$dwq3&jNYGu'
})
assert response.status_code == 200
json_data = response.get_json()
assert json_data['access_token']
assert json_data['refresh_token']
这种方法最好的事情是你不需要创建setUp
和tearDown
方法。然后,您可以为您的应用程序创建test
cli命令:
import pytest
@app.cli.command()
def test():
'''
Run tests.
'''
pytest.main(['--rootdir', './tests'])
并称之为flask test
。