我尝试在 Flask 应用程序上使用 Pytest 实现单元测试,但我很难做到这一点。
我的 Flask 应用程序使用大多数功能的配置文件(此处为 some_method)来进行说明。所以看来我应该为我想测试的任何方法的每次调用提供一个上下文。看来我可以在每次调用时通过“with app.app_context():”来实现它。
我阅读了官方测试文档,但他们谈论了创建客户端。因为我想做单元测试,所以我需要调用不是顶级的子函数。
有没有一种方法可以始终提供上下文,而无需在每次调用时手动推送上下文?请在下面找到我当前的实现:
main.py
from flask import current_app
def main(request):
current_app.config.from_envvar('APPLICATION_SETTINGS')
print(some_method())
return 'OK'
def some_method():
# doing some stuff using the context
world = current_app.config['SECRET_KEY']
return world
test_main.py
import pytest
from flask import current_app, Flask
from main import main, some_method
@pytest.fixture
def app():
app = Flask(__name__)
# load here any potential configuration configuration
return app
def test_some_method(app):
with app.app_context():
# calling and doing some assertion
some_method()
PS:我的主文件中没有 app = Flask(
pytest-flask似乎可以在任何调用中配置上下文。
conftest.py
import pytest
from flask import Flask
@pytest.fixture
def app():
app = Flask(__name__)
return app
test_main.py
import pytest
from flask import current_app, Flask
from main import main, some_method
def test_some_method(app):
#with app.app_context():
# calling and doing some assertion
some_method()
有效。
# conftest.py
from flask import Flask
from flask.testing import FlaskClient
@pytest.fixture()
def app() -> Flask:
app = Flask(__name__)
# configure app
app.config.update({"TESTING": True})
return app
@pytest.fixture()
def client(app: Flask) -> FlaskClient:
return app.test_client()
@pytest.fixture(autouse=True)
def _provide_app_context(app: Flask):
with app.app_context():
yield
# test_main.py
from main import some_method
def test_some_method():
# app context automatically provided via the _provide_app_context fixture
some_method()
def test_with_app_and_client_fixtures(app, client):
pass
这可能会减慢您的测试运行速度,因此,如果您同意在测试之间共享实例,则可以缓存应用程序以避免在每次测试运行时创建它。这个实现可以像你想要的那样复杂,但在基础层面上,类似下面的东西应该可以工作。
# conftest.py
from flask import Flask
from flask.testing import FlaskClient
CACHED_APP = Flask(__name__)
CACHED_APP.config.update({"TESTING": True})
@pytest.fixture()
def app() -> Flask:
return CACHED_APP
# ...