Мы расширяем 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) выглядит так: это основано на описанном стиле здесь.
# 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. Однако после запуска функции test setUp в some-tests.py мне каким-то образом нужно получить объект Flask, используя конфигурацию testing, например воссоздав приложение Flask с конфигурацией testing, как сейчас.
Я хотел бы иметь указатели на то, как приступить к реализации тестовой команды flask-cli, в которой создается только один объект Flask, который повторно используется среди различных тестовых примеров без необходимости явной настройки среды на testing, прежде чем я запустил flask test на командная строка.





Я не уверен, будет ли этот ответ соответствовать вашим требованиям, но я бы попытался подойти к этой проблеме именно так. К сожалению, если вы хотите использовать интерфейс CLI по умолчанию во Flask, вам нужно вызвать 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. Затем вы можете создать команду cli test для своего приложения:
import pytest
@app.cli.command()
def test():
'''
Run tests.
'''
pytest.main(['--rootdir', './tests'])
И назовите его так flask test.
@RajatArora Я думаю, вам следует проверить документацию pytest, чтобы узнать, есть ли для этого флаг.
нашел это полезным. Небольшой вопрос, как вы публикуете результаты, используя этот подход? например, для что-то вроде --junitxml results.xml