serhiy-storchaka · GitHub

test.support.subTests() wraps the test method in a synchronous function. For an asynchronous test the wrapper calls it and discards the resulting coroutine without awaiting it, so the test does not run at all.

It is not even reported as an error, because IsolatedAsyncioTestCase decides whether to await the test method with inspect.iscoroutinefunction(), which does not follow __wrapped__, and so does not notice that the test is asynchronous.

import unittest
from test import support
class Tests(unittest.IsolatedAsyncioTestCase):
    @support.subTests('a', [1, 2])
    async def test_it(self, a):
        self.fail('this is never reported')
if __name__ == '__main__':
    unittest.main()
$ ./python -W always repro.py
Lib/test/support/__init__.py:1124: RuntimeWarning: coroutine 'Tests.test_it' was never awaited
  func(self, *args, **kwargs, **subtest_kwargs)
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK

None of the 195 subTests() call sites in the stdlib is currently affected, as none of them decorates an async def, but fixing this allows using subTests() in asynchronous tests.

Affects 3.13+.

Linked PRs

Read the original on github.com ↗