-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-32972: Add unittest.AsyncioTestCase #10296
bpo-32972: Add unittest.AsyncioTestCase #10296
Conversation
This is the core of running a test. It is also the portion of run() that requires specialization for asyncio support.
This method is essentially ``_runTest`` with a Outcome object that does nothing. This commit inserts a new class that is a no-op Outcome so that the method can be re-used.
See discussion under https://bugs.python.org/issue32972
This makes AsyncioTestCase.doCleanups() safe to call at any time. The previous version terminated the event loop unnecessarily.
Hi, Thanks for your PR, but this one is not related to the issue. In this PR, you add the support for asyncio but it is not the topic of the bpo issue. Maybe you have to open an other issue and assign this PR to the issue. |
@matrixise ick ... early morning mistake. This is associated with BPO 32972, renaming the PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank for your contribution but could you add a NEWS entry with the blurb tool.
pip install blurb
Lib/unittest/case.py
Outdated
is stopped and closed. | ||
|
||
When subclassing AsyncioTestCase, the event loop is available | ||
via the ``event_loop`` property. Tests can assume that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
about event_loop
I am not sure, usually we found loop
in the documentation of asyncio
Lib/unittest/case.py
Outdated
self.__event_loop = None | ||
|
||
def doCleanups(self): | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring should start on the first line, https://www.python.org/dev/peps/pep-0008/#documentation-strings
Lib/unittest/case.py
Outdated
@@ -81,6 +82,16 @@ def testPartExecutor(self, test_case, isTest=False): | |||
self.success = self.success and old_success | |||
|
|||
|
|||
class _IgnoredOutcome(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Python3, we prefer to use the new style
https://docs.python.org/3/reference/compound_stmts.html#class-definitions
# new style
class _IgnoredOutcome:
pass
is equivalent to
# old style
class _IgnoredOutcome(object):
pass
so in this case, use the new style and not the old one.
import unittest | ||
|
||
|
||
class Test(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my previous comment about the construction of a class
class Test:
pass
is better
Lib/unittest/case.py
Outdated
self.tearDown() | ||
|
||
@property | ||
def event_loop(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the documentation, we prefer to use the loop
variable for the reference to the event loop.
Examples:
:meth:`loop.call_soon`
or :meth:`loop.set_debug`
etc...
maybe you should do the same.
raise AssertionError(f'test {test_class} unexpectedly failed') | ||
|
||
|
||
class EventLoopTracking(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just class EventLoopTracking:
`loop` is consistent with the Standard Library spelling of the current event loop. See python#10296
@matrixise - thanks for the review. I amended a few commits to address your feedback. I still intend to add some documentation in Doc/library/unittest.rst and Doc/library/asyncio.rst as well. I wanted to make sure that the implementation was acceptable before starting the documentation related tasks. |
if self.__loop is None: | ||
self.__loop = asyncio.new_event_loop() | ||
self.__loop.set_debug(True) | ||
asyncio.set_event_loop(self.__loop) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the test case have to modify the global state like this? It is calling self.loop.run_until_complete
when running things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it does. This is the only way to ensure that the code under test gets the correct loop.
Please take a look on #13386 |
Implemented by #13386 |
This PR adds co-routine support to unittest by adding a new sub-class of
unittest.TestCase
namedunittest.AsyncioTestCase
. It extendsunittest.TestCase
by adding the following functionality:asyncSetUp
andasyncTearDown
async
keyword are run on the event loop. Undecorated methods are run as normal methods.async
keyword are run on the event loop. Undecorated methods are run as normal methods.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.
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).unittest.TestCase
from unexpected breakages and maintains it's current behavior.Open Questions
len(asyncio.all_tasks())
is non-zero after cleanups are run?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