tornadoweb / tornado

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
http://www.tornadoweb.org/
Apache License 2.0
21.77k stars 5.51k forks source link

testing: allow to instantiate an empty AsyncTestCase #3374

Closed bluetech closed 5 months ago

bluetech commented 7 months ago

unittest.TestCase has a feature where it allows instantiating MyTestClass() with the default method name runTest even if a runTest method doesn't actually exist. This is documented in TestCase's docs under "Changed in version 3.2" (link).

Since version 8.2, pytest relies on this, and started breaking on Tornado's AsyncTestCase, see https://github.com/pytest-dev/pytest/issues/12263.

Change AsyncTestCase to allow empty instatiation, by matching the upstream code.

arossert commented 6 months ago

@bluetech Any estimation when this will be merged and released?

bdarnell commented 6 months ago

I want to look at this next week and understand what's going on. Catching an exception and disabling the _TestMethodWrapper for pytest users doesn't seem like the right solution and the "new in 3.2" docs look unrelated (it sounds like this is when the methodName parameter got its default value but has no bearing on whether the named method must exist).

bluetech commented 5 months ago

Catching an exception and disabling the _TestMethodWrapper for pytest users doesn't seem like the right solution

Let me try to clarify: pytest instantiates the test class in two situations:

  1. Once per test class, to collect fixtures and tests and such.
  2. One per test, to use as the test's self.

This PR is meant to support the first case. It is not disabling the _TestMethodWrapper in the second case, when it matters, only in the first, when no method is being run.

the "new in 3.2" docs look unrelated (it sounds like this is when the methodName parameter got its default value but has no bearing on whether the named method must exist).

Hmm yes that note is ambiguous but let me try to clarify it. It says: "Changed in version 3.2: TestCase can be instantiated successfully without providing a methodName". The situation before was that there was a methodName="runTest" default, but the runTest method was actually expected to exist, so in effect TestCase could not be instantiated successfully without providing a methodName. What the change did was to take "runTest" as a sentinel value to allow to instantiate even if a runTest method is not defined. Here is the original upstream commit: https://github.com/python/cpython/commit/32e1d8340c05fa62ba51dbd942bdc09a21e65f6e

bdarnell commented 5 months ago

Yes, I was just researching this and was pulling on the history. I see a better fix for this by moving the check in _TestCaseWrapper to a different location instead of __init__ time. New PR coming soon.

bdarnell commented 5 months ago

Replacement PR is #3382