【发布时间】:2017-01-28 07:45:19
【问题描述】:
我正在为使用peewee 实现的某些数据库模型编写一组使用pytest 的单元测试。我想使用数据库事务(数据库是 Postgres 的,如果相关的话)以便在每次测试后回滚任何数据库更改。
我有一种情况,我想在测试中使用两个夹具,但两个夹具都通过 rollback 方法清理它们的数据库模型,如下所示:
@pytest.fixture
def test_model_a():
with db.transaction() as txn: # `db` is my database object
yield ModelA.create(...)
txn.rollback()
@pytest.fixture
def test_model_b():
with db.transaction() as txn: # `db` is my database object
yield ModelB.create(...)
txn.rollback()
def test_models(test_model_a, test_model_b):
# ...
这可行,但阅读documentation for peewee 表明这很容易出错:
如果您尝试使用
transaction()上下文管理器将事务与 peewee 嵌套,则只会使用最外层的事务。但是如果嵌套块中发生异常,这可能会导致不可预知的行为,因此强烈建议您使用atomic()。
但是,atomic() 不提供rollback() 方法。似乎在显式管理事务时,关键是使用最外层的transaction(),并在该事务中使用savepoint() 上下文管理器。但是在我上面的测试代码中,可以这么说,两个fixture处于同一个“级别”,我不知道在哪里创建事务,以及在哪里创建保存点。
我唯一的另一个想法是使用固定装置的评估顺序来决定将交易放在哪里 (which seems to be alphabetical),但这看起来确实很脆弱。
有没有办法做到这一点?还是我的测试设计需要重新思考?
【问题讨论】:
标签: python postgresql transactions pytest peewee