Skip to content

Commit 451aef6

Browse files
prepare tests and disable warnings for asyncio unittest cases
shoehorn unittest async results into python test result interpretation changelog
1 parent ce42938 commit 451aef6

File tree

5 files changed

+48
-4
lines changed

5 files changed

+48
-4
lines changed

changelog/6924.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Ensure a ``unittest.IsolatedAsyncioTestCase`` is actually awaited.

src/_pytest/python.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,33 @@ def async_warn(nodeid: str) -> None:
175175
@hookimpl(trylast=True)
176176
def pytest_pyfunc_call(pyfuncitem: "Function"):
177177
testfunction = pyfuncitem.obj
178-
if iscoroutinefunction(testfunction) or (
179-
sys.version_info >= (3, 6) and inspect.isasyncgenfunction(testfunction)
180-
):
178+
179+
try:
180+
# ignoring type as the import is invalid in py37 and mypy thinks its a error
181+
from unittest import IsolatedAsyncioTestCase # type: ignore
182+
except ImportError:
183+
async_ok_in_stdlib = False
184+
else:
185+
async_ok_in_stdlib = isinstance(
186+
getattr(testfunction, "__self__", None), IsolatedAsyncioTestCase
187+
)
188+
189+
if (
190+
iscoroutinefunction(testfunction)
191+
or (sys.version_info >= (3, 6) and inspect.isasyncgenfunction(testfunction))
192+
) and not async_ok_in_stdlib:
181193
async_warn(pyfuncitem.nodeid)
182194
funcargs = pyfuncitem.funcargs
183195
testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames}
184196
result = testfunction(**testargs)
185197
if hasattr(result, "__await__") or hasattr(result, "__aiter__"):
186-
async_warn(pyfuncitem.nodeid)
198+
if async_ok_in_stdlib:
199+
# todo: investigate moving this to the unittest plugin
200+
# by a test call result hook
201+
testcase = testfunction.__self__
202+
testcase._callMaybeAsync(lambda: result)
203+
else:
204+
async_warn(pyfuncitem.nodeid)
187205
return True
188206

189207

testing/example_scripts/pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
# dummy pytest.ini to ease direct running of example scripts
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from unittest import IsolatedAsyncioTestCase # type: ignore
2+
3+
4+
class AsyncArguments(IsolatedAsyncioTestCase):
5+
async def test_something_async(self):
6+
async def addition(x, y):
7+
return x + y
8+
9+
self.assertEqual(await addition(2, 2), 4)
10+
11+
async def test_something_async_fails(self):
12+
async def addition(x, y):
13+
return x + y
14+
15+
self.assertEqual(await addition(2, 2), 3)

testing/test_unittest.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,3 +1129,11 @@ def test(self):
11291129
result = testdir.runpytest("--trace", str(p1))
11301130
assert len(calls) == 2
11311131
assert result.ret == 0
1132+
1133+
1134+
def test_async_support(testdir):
1135+
pytest.importorskip("unittest.async_case")
1136+
1137+
testdir.copy_example("unittest/test_unittest_asyncio.py")
1138+
reprec = testdir.inline_run()
1139+
reprec.assertoutcome(failed=1, passed=1)

0 commit comments

Comments
 (0)