bpo-32972: Add unittest.AsyncioTestCase by dave-shawley · Pull Request #10296 · python/cpython (original) (raw)

This PR adds co-routine support to unittest by adding a new sub-class of unittest.TestCase named unittest.AsyncioTestCase. It extends unittest.TestCase by adding the following functionality:

I made the following conscious decisions during the implementation that may be somewhat controversial so I want to mention them here (in no particular order) along with the rationale.

  1. there is no direct support for other event loop implementation: other event loop implementations can be plugged in using a custom EventLoopPolicy implementation. It can be inserted by overriding setUpClass. I believe that other loop implementations can either plug in using the event loop policy or provide their own asynchronous test case implementation (e.g., tornado.testing).
  2. asyncio.iscoroutine is used to detect async methods: the two places that I need to detect whether a callable is a co-routine or not are: (a) test methods and (b) cleanup hooks added with addCleanup. Both are explicit (opt-in) actions so they are completely controlled by the test writer.
  3. outstanding asyncio Tasks are not terminated: I'm still on the fence about whether the test should fail if there are outstanding tasks or if it should gather them.
  4. async test case is a separate class: I decided to use a sub-class so that it is immediately obvious that a test methods are intended to run on the event loop. This also insulates unittest.TestCase from unexpected breakages and maintains it's current behavior.

Open Questions

  1. What should happen when len(asyncio.all_tasks()) is non-zero after cleanups are run?
  2. Should unittest.AsyncioTestCase include a global test run timeout?

I still have to amend commits to update documentation but I wanted to have the discussion about the implementation choices before I started writing up examples and updating the existing documentation suite.

https://bugs.python.org/issue32972