我正在努力編寫py.test fixtures來管理我的應用程序的數據庫,以最大限度地提高速度,支持pytest-xdist
並行化的測試,並隔離測試彼此。如何將py.test裝置與Flask-SQLAlchemy和PostgreSQL結合使用?
我正在使用Flask-SQLAlchemy 2.1針對PostgreSQL 9.4數據庫。
這裏是什麼,我試圖完成的大致輪廓:
$ py.test -n 3
旋轉起來運行測試三個測試會議。在每個會話中,py.test夾具運行一次以建立事務,創建數據庫表,然後在會話結束時它回滾事務。創建數據庫表需要在只對特定測試會話可見的PostgreSQL事務內發生,否則由
pytest-xdist
創建的並行化測試會話會相互衝突。爲每個測試運行的第二個py.test夾具連接到現有事務,以便查看創建的表,創建嵌套保存點,運行測試,然後回滾到嵌套保存點。
理想情況下,這些pytest夾具支持調用
db.session.rollback()
的測試。在此SQLAlchemy doc的底部有一個可能的配方來完成此操作。理想的pytest燈具應產生
db
對象,而不僅僅是會話,以便 人可以編寫測試,而無需記住使用一個會話這 比他們在整個應用程序中使用的標準不同db.session
。
這是我到目前爲止有:
import pytest
# create_app() is my Flask application factory
# db is just 'db = SQLAlchemy()' + 'db.init_app(app)' within the create_app() function
from app import create_app, db as _db
@pytest.yield_fixture(scope='session', autouse=True)
def app():
'''Session-wide test application'''
a = create_app('testing')
with a.app_context():
yield a
@pytest.yield_fixture(scope='session')
def db_tables(app):
'''Session-wide test database'''
connection = _db.engine.connect()
trans = connection.begin() # begin a non-ORM transaction
# Theoretically this creates the tables within the transaction
_db.create_all()
yield _db
trans.rollback()
connection.close()
@pytest.yield_fixture(scope='function')
def db(db_tables):
'''db session that is joined to existing transaction'''
# I am quite sure this is broken, but it's the general idea
# bind an individual Session to the existing transaction
db_tables.session = db_tables.Session(bind=db_tables.connection)
# start the session in a SAVEPOINT...
db_tables.session.begin_nested()
# yield the db object, not just the session so that tests
# can be written transparently using the db object
# without requiring someone to understand the intricacies of these
# py.test fixtures or having to remember when to use a session that's
# different than db.session
yield db_tables
# rollback to the savepoint before the test ran
db_tables.session.rollback()
db_tables.session.remove() # not sure this is needed
這裏的,而谷歌搜索,我已經找到了最有用的參考資料:
https://github.com/mitsuhiko/flask-sqlalchemy/pull/249