Emit a warning when a async def function is not handled by a plugin
Fix #2224
This commit is contained in:
parent
90597226eb
commit
40072b9511
|
@ -0,0 +1,4 @@
|
||||||
|
``async`` test functions are skipped and a warning is emitted when a suitable
|
||||||
|
async plugin is not installed (such as ``pytest-asyncio`` or ``pytest-trio``).
|
||||||
|
|
||||||
|
Previously ``async`` functions would not execute at all but still be marked as "passed".
|
|
@ -43,6 +43,7 @@ from _pytest.mark import MARK_GEN
|
||||||
from _pytest.mark.structures import get_unpacked_marks
|
from _pytest.mark.structures import get_unpacked_marks
|
||||||
from _pytest.mark.structures import normalize_mark_list
|
from _pytest.mark.structures import normalize_mark_list
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
|
from _pytest.outcomes import skip
|
||||||
from _pytest.pathlib import parts
|
from _pytest.pathlib import parts
|
||||||
from _pytest.warning_types import PytestWarning
|
from _pytest.warning_types import PytestWarning
|
||||||
|
|
||||||
|
@ -156,6 +157,15 @@ def pytest_configure(config):
|
||||||
@hookimpl(trylast=True)
|
@hookimpl(trylast=True)
|
||||||
def pytest_pyfunc_call(pyfuncitem):
|
def pytest_pyfunc_call(pyfuncitem):
|
||||||
testfunction = pyfuncitem.obj
|
testfunction = pyfuncitem.obj
|
||||||
|
iscoroutinefunction = getattr(inspect, "iscoroutinefunction", None)
|
||||||
|
if iscoroutinefunction is not None and iscoroutinefunction(testfunction):
|
||||||
|
msg = "Coroutine functions are not natively supported and have been skipped.\n"
|
||||||
|
msg += "You need to install a suitable plugin for your async framework, for example:\n"
|
||||||
|
msg += " - pytest-asyncio\n"
|
||||||
|
msg += " - pytest-trio\n"
|
||||||
|
msg += " - pytest-tornasync"
|
||||||
|
warnings.warn(PytestWarning(msg.format(pyfuncitem.nodeid)))
|
||||||
|
skip(msg="coroutine function and no async plugin installed (see warnings)")
|
||||||
funcargs = pyfuncitem.funcargs
|
funcargs = pyfuncitem.funcargs
|
||||||
testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames}
|
testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames}
|
||||||
testfunction(**testargs)
|
testfunction(**testargs)
|
||||||
|
|
|
@ -1179,3 +1179,31 @@ def test_fixture_mock_integration(testdir):
|
||||||
def test_usage_error_code(testdir):
|
def test_usage_error_code(testdir):
|
||||||
result = testdir.runpytest("-unknown-option-")
|
result = testdir.runpytest("-unknown-option-")
|
||||||
assert result.ret == EXIT_USAGEERROR
|
assert result.ret == EXIT_USAGEERROR
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
sys.version_info[:2] < (3, 5), reason="async def syntax python 3.5+ only"
|
||||||
|
)
|
||||||
|
@pytest.mark.filterwarnings("default")
|
||||||
|
def test_warn_on_async_function(testdir):
|
||||||
|
testdir.makepyfile(
|
||||||
|
test_async="""
|
||||||
|
async def test_1():
|
||||||
|
pass
|
||||||
|
async def test_2():
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
[
|
||||||
|
"test_async.py::test_1",
|
||||||
|
"test_async.py::test_2",
|
||||||
|
"*Coroutine functions are not natively supported*",
|
||||||
|
"*2 skipped, 2 warnings in*",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# ensure our warning message appears only once
|
||||||
|
assert (
|
||||||
|
result.stdout.str().count("Coroutine functions are not natively supported") == 1
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue