【发布时间】:2015-12-04 02:48:22
【问题描述】:
我正在努力编写 py.test 固定装置来管理我的应用程序的数据库,以最大限度地提高速度,支持 pytest-xdist 并行化测试,并将测试相互隔离。
我正在对 PostgreSQL 9.4 数据库使用 Flask-SQLAlchemy 2.1。
这是我要完成的工作的大致轮廓:
$ 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
这是我在谷歌搜索时发现的最有用的参考资料:
【问题讨论】:
-
你能解决这个问题吗?
-
@einSelbst 不,我两年没看过了。
标签: postgresql flask sqlalchemy flask-sqlalchemy pytest