[英]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.