【问题标题】:Using pytest fixtures and peewee transactions together一起使用 pytest 固定装置和 peewee 事务
【发布时间】: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


    【解决方案1】:

    如果你想回滚测试中创建的所有事务,你可以有一个夹具来处理事务本身并让模型夹具使用它:

    @pytest.fixture
    def transaction():
        with db.transaction() as txn:  # `db` is my database object
            yield txn
            txn.rollback()
    
    @pytest.fixture
    def test_model_a(txn):
        yield ModelA.create(...)        
    
    @pytest.fixture
    def test_model_b(txn):
        yield ModelB.create(...)            
    
    def test_models(test_model_a, test_model_b):
        # ...
    

    这样,所有模型都在同一个事务中创建,并在测试结束时回滚。

    【讨论】:

      【解决方案2】:

      如果您想针对干净的数据库运行单独的测试,您可以使用 peewee 文档中指定的 Database.bind_ctx()Model.bind_ctx() 方法:

      http://docs.peewee-orm.com/en/latest/peewee/database.html#testing-peewee-applications

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-10
        • 1970-01-01
        • 2020-10-04
        • 1970-01-01
        • 2020-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多