如何使用coroutine作为pytest夹具?

时间:2016-12-28 11:06:19

标签: python tornado pytest

是否有可能将pytest灯具写成龙卷风协同程序?例如,我想编写一个用于创建数据库的fixture,如下所示:

from tornado import gen
import pytest

@pytest.fixture
@gen.coroutine
def get_db_connection():
    # set up
    db_name = yield create_db()
    connection = yield connect_to_db(db_name)

    yield connection

    # tear down
    yield drop_db(db_name)


@pytest.mark.gen_test
def test_something(get_db_connection):
    # some tests

显然,这个装置不能按预期工作,因为它被称为一个函数,而不是协程。有办法解决吗?

1 个答案:

答案 0 :(得分:0)

经过一番研究,我得出了这个解决方案:

from functools import partial
from tornado import gen
import pytest

@pytest.fixture
def get_db_connection(request, io_loop): # io_loop is a fixture from pytest-tornado
    def fabric():
        @gen.coroutine
        def set_up(): 
            db_name = yield create_db()
            connection = yield connect_to_db(db_name)
            raise gen.Return(connection)
        @gen.coroutine
        def tear_down():
            yield drop_db(db_name)
        request.addfinalizer(partial(io_loop.run_sync, tear_down))
        connection = io_loop.run_sync(set_up)
        return connection

    return fabric


@pytest.mark.gen_test
def test_something(get_db_connection):
    connection = get_db_connection()  # note brackets

我敢肯定,使用一些pylint魔法可以做得更干净。 我发现here非常有用。

编辑:我发现上述方法有局限性。你不能改变get_db_connection fixture的范围,因为它使用范围为“function”的io_loop fixture。