我正在尝试使用 pytest 测试异步 Python 函数。我的测试通过了警告,但它应该失败。
这是我的测试:
import asynctest
import pytest
from Foo.bar import posts
@pytest.mark.asyncio
async def test_get_post_exists():
returned_post = await posts.get_post('0')
assert returned_post.id == 0
assert returned_post.text == 'Text for the post body.'
assert True == False
Run Code Online (Sandbox Code Playgroud)
它通过以下消息:
================================== test session starts ===================================
platform darwin -- Python 3.6.4, pytest-3.4.2, py-1.5.2, pluggy-0.6.0
rootdir: /path/path/path/path, inifile:
collected 1 item
tests/unit/route_logic/test_post_helpers.py . [100%]
==================================== warnings summary ====================================
tests/unit/route_logic/test_post_helpers.py::test_get_post_exists
/usr/local/lib/python3.6/site-packages/_pytest/python.py:155: RuntimeWarning: coroutine 'test_get_post_exists' was never awaited
testfunction(**testargs)
-- Docs: http://doc.pytest.org/en/latest/warnings.html
========================== 1 passed, 1 warnings in 0.10 seconds ==========================
Run Code Online (Sandbox Code Playgroud)
pytest这是使用和 的工作演示pytest-asyncio:
Foo/bar/posts.py:
from collections import namedtuple
Post = namedtuple('Post', 'id text')
async def get_post(id: str):
return Post(id=int(id), text='Text for the post body.')
Run Code Online (Sandbox Code Playgroud)
test_post_helpers.py:
import pytest
from Foo.bar import posts
@pytest.mark.asyncio
async def test_get_post_exists():
returned_post = await posts.get_post('0')
assert returned_post.id == 0
assert returned_post.text == 'Text for the post body.'
assert True == False
Run Code Online (Sandbox Code Playgroud)
单元测试结果:
========================================================================================================================================================================= test session starts ==========================================================================================================================================================================
platform darwin -- Python 3.7.5, pytest-5.3.1, py-1.8.0, pluggy-0.13.1
rootdir: /Users/ldu020/workspace/github.com/mrdulin/python-codelab
plugins: asyncio-0.10.0
collected 1 item
src/stackoverflow/49350821/test_post_helpers.py F [100%]
=============================================================================================================================================================================== FAILURES ===============================================================================================================================================================================
_________________________________________________________________________________________________________________________________________________________________________ test_get_post_exists _________________________________________________________________________________________________________________________________________________________________________
@pytest.mark.asyncio
async def test_get_post_exists():
returned_post = await posts.get_post('0')
assert returned_post.id == 0
assert returned_post.text == 'Text for the post body.'
> assert True == False
E assert True == False
src/stackoverflow/49350821/test_post_helpers.py:11: AssertionError
========================================================================================================================================================================== 1 failed in 0.15s ===========================================================================================================================================================================
Run Code Online (Sandbox Code Playgroud)
assert True == False导致断言如您所愿失败。
源代码:https ://github.com/mrdulin/python-codelab/tree/master/src/stackoverflow/49350821
您必须安装pytest-asyncio。
pip install pytest-asyncio
Run Code Online (Sandbox Code Playgroud)
您不必将其导入到任何地方。只需用 装饰 async def 测试即可@pytest.mark.asyncio。
@hoefling 评论中提到了这一点,我发布这个答案只是为了使其更加明显:
coroutine 'my_coro' was never awaited意味着协程对象从未放入事件循环中,所以我想您要么缺少将测试放入事件循环中的 pytest-asyncio 。
如果没有 pytest-asyncio,pytest 不知道它应该进行await异步测试。它只是将其作为非异步函数运行,这不足以实际执行异步函数体:
$ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
>>> async def foo():
... raise Excepion('this is never raised')
...
>>> foo()
<coroutine object foo at 0x7f7d857d4cc8>
>>> exit()
sys:1: RuntimeWarning: coroutine 'foo' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7136 次 |
| 最近记录: |