[英]How to Completely Teardown Flask App After Each Test in pytest?
我正在使用Pytest测试我的Flask应用程序。 我有3个文件
tests/
--conftest.py
--test_one.py
--test_two.py
如果我使用以下命令运行test_one.py
或 test_two.py
,它将正常工作。
python -m pytest tests/test_one.py
当我尝试使用以下命令运行所有测试时出现问题:
python -m pytest tests
我收到此错误:
AssertionError: View function mapping is overwriting an existing endpoint function: serve_static
我真的不会对这个错误感到惊讶,因为init_app(app)
被调用两次(每个文件一次),我不会拆除实际的app
。
我的问题是, 有没有办法彻底拆除烧瓶应用程序并为每个单独的测试重建它? 我正在寻找拆除的实际命令(即app.teardown()
)
编辑:我愿意接受设置Flask应用测试环境的其他方法,如果能解决这个问题(不创建新问题)。
编辑2:我发现了这个问题。 它是类似的,可以解决我的问题,但它涉及导入函数内部。 我怀疑必须有更好的方法。
conftest.py
import os
import pytest
from app import app, init_app
from config import TestConfig
@pytest.fixture(scope='function')
def client():
app.config.from_object(TestConfig)
with app.test_client() as client:
with app.app_context():
init_app(app)
yield client
try:
os.remove('tests/testing.db')
except FileNotFoundError:
pass
应用程序/ __ init__.py
app = Flask(__name__)
app.url_map._rules.clear()
db = SQLAlchemy(app)
migrate = Migrate(app, db)
def init_app(app):
...
我会在每个继承TestCase的文件中创建一个Class。 这样,您可以使用函数setup()
在每次测试之前将testclient生成为Instance-Variable。 这样,您可以确保每个测试都具有相同的环境。
from unittest import TestCase
from app import app as application
class TestApplication(TestCase):
def setUp(self):
self.client = application.app.test_client()
def test_sth(self):
r = self.client.get('/approute2sth')
self.assertEqual(r.status_code, 200)
def test_sth_else(self):
r = self.client.get('/approute2sth_else')
self.assertEqual(r.status_code, 200)
我正在考虑一个解决方案,但不涉及拆除烧瓶应用程序。 我不喜欢为每个测试用例拆掉它,因为这本身会导致每个测试用例的正常运行时间增加(除非烧瓶应用初始化对于每个测试用例都是唯一的)
由于测试在pytest中并行运行,因此您可以执行以下操作
try:
app
except NameError:
app.config.from_object(TestConfig)
with app.test_client() as client:
with app.app_context():
init_app(app)
else:
print("App is already configured. Let us proceed with the test case")
您可以将它包装在单个类中,而不是采用上述方法
以下某些组合可能有效。 我相信这是做旧的方式(尽管我自己从未做过)。 我的印象是pytest
使用灯具的概念来直接teardown()
。
#clear current db session
db.session.remove()
#drop all tables in db
db.drop_all()
#remove app_context
app.app_context.pop()
有关更多讨论,请参阅pytest上的此博客文章 。
最终我的问题是我如何创建我的app
。 由于它是在__init__.py
创建的一个gloval变量,因此我无法为每次测试重新制作它。 我重构了__init__.py
(以及我的其余代码)以使用create_app
函数,我可以一遍又一遍地创建相同的应用程序。 以下代码最终正常运行。
应用程序/ __ init__.py
def create_app(config)
app = Flask(__name__)
app.url_map._rules.clear()
from .models import db
app.config.from_object(config)
with app.app_context():
return app
def init_app(app):
...
conftest.py
import os
import pytest
from app import create_app, init_app
from config import TestConfig
@pytest.fixture(scope='function')
def client():
app = create_app()
app.config.from_object(TestConfig)
with app.test_client() as client:
with app.app_context():
from app.models import db
init_app(app, db)
yield client
try:
os.remove('tests/testing.db')
except FileNotFoundError:
pass
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.