使用 @pytest.fixture(scope="module") 和 @pytest.mark.asyncio
Using @pytest.fixture(scope="module") with @pytest.mark.asyncio
我认为下面的示例是一个非常常见的用例:
- 创建到数据库的连接一次,
- 传递这个连接来测试哪个插入数据
- 将连接传递给验证数据的测试。
更改 @pytest.fixture(scope="module")
的范围会导致 ScopeMismatch: You tried to access the 'function' scoped fixture 'event_loop' with a 'module' scoped request object, involved factories
。
此外,test_insert
和 test_find
协程不需要 event_loop 参数,因为通过传递连接已经可以访问循环。
有解决这两个问题的想法吗?
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"
解决方案是用模块作用域重新定义 event_loop fixture。将其包含在测试文件中。
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
loop.close()
在 github 中针对 pytest-asyncio (link) 提出了类似的 ScopeMismatch 问题。解决方案(如下)适用于我:
@pytest.yield_fixture(scope='class')
def event_loop(request):
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
我认为下面的示例是一个非常常见的用例:
- 创建到数据库的连接一次,
- 传递这个连接来测试哪个插入数据
- 将连接传递给验证数据的测试。
更改 @pytest.fixture(scope="module")
的范围会导致 ScopeMismatch: You tried to access the 'function' scoped fixture 'event_loop' with a 'module' scoped request object, involved factories
。
此外,test_insert
和 test_find
协程不需要 event_loop 参数,因为通过传递连接已经可以访问循环。
有解决这两个问题的想法吗?
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"
解决方案是用模块作用域重新定义 event_loop fixture。将其包含在测试文件中。
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
loop.close()
在 github 中针对 pytest-asyncio (link) 提出了类似的 ScopeMismatch 问题。解决方案(如下)适用于我:
@pytest.yield_fixture(scope='class')
def event_loop(request):
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()