简体   繁体   English

使用 @pytest.fixture(scope="module") 和 @pytest.mark.asyncio

[英]Using @pytest.fixture(scope="module") with @pytest.mark.asyncio

I think the example below is a really common use case:我认为下面的例子是一个非常常见的用例:

  1. create a connection to a database once ,创建与数据库的连接一次
  2. pass this connection around to test which insert data传递此连接以测试哪些插入数据
  3. pass the connection to a test which verifies the data.将连接传递给验证数据的测试。

Changing the scope of @pytest.fixture(scope="module") causes ScopeMismatch: You tried to access the 'function' scoped fixture 'event_loop' with a 'module' scoped request object, involved factories .更改@pytest.fixture(scope="module")会导致ScopeMismatch: You tried to access the 'function' scoped fixture 'event_loop' with a 'module' scoped request object, involved factories

Also, the test_insert and test_find coroutine do not need the event_loop argument because the loop is accessible already by passing the connection.此外, test_inserttest_find协程不需要 event_loop 参数,因为通过传递连接已经可以访问循环。

Any ideas how to fix those two issues?任何想法如何解决这两个问题?

import pytest

@pytest.fixture(scope="function")  # <-- want this to be scope="module"; run once!
@pytest.mark.asyncio
async def connection(event_loop):
    """ Expensive function; want to do in the module scope. Only this function needs `event_loop`!
    """
    conn await = make_connection(event_loop)
    return conn


@pytest.mark.dependency()
@pytest.mark.asyncio
async def test_insert(connection, event_loop):  # <-- does not need event_loop arg
    """ Test insert into database.

        NB does not need event_loop argument; just the connection.
    """
    _id = 0
    success = await connection.insert(_id, "data")
    assert success == True


@pytest.mark.dependency(depends=['test_insert'])
@pytest.mark.asyncio
async def test_find(connection, event_loop):  # <-- does not need event_loop arg
    """ Test database find.

        NB does not need event_loop argument; just the connection.
    """
    _id = 0
    data = await connection.find(_id)
    assert data == "data"

The solution is to redefine the event_loop fixture with the module scope.解决方案是重新定义具有模块作用域的 event_loop 夹具。 Include that in the test file.将其包含在测试文件中。

@pytest.fixture(scope="module")
def event_loop():
    loop = asyncio.get_event_loop()
    yield loop
    loop.close()

Similar ScopeMismatch issue was raised in github for pytest-asyncio ( link ).在 github 中为 pytest-asyncio (链接) 提出了类似的 ScopeMismatch 问题。 The solution (below) works for me:解决方案(如下)对我有用:

@pytest.yield_fixture(scope='class')
def event_loop(request):
    loop = asyncio.get_event_loop_policy().new_event_loop()
    yield loop
    loop.close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM