mirror of https://github.com/python/cpython
#14533: if a test has no test_main, use loadTestsFromModule.
This moves us further in the direction of using normal unittest facilities instead of specialized regrtest ones. Any test module that can be correctly run currently using 'python unittest -m test.test_xxx' can now be converted to use normal unittest test loading by simply deleting its test_main, thus no longer requiring manual maintenance of the list of tests to run. (Not all tests can be converted that easily, since test_main sometimes does some additional things (such as reap_children or reap_threads). In those cases the extra code may be moved to setUpModule/tearDownModule methods, or perhaps the same ends can be achieved in a different way, such as moving the decorators to the test classes that need them, etc.) I don't advocate going through and making this change wholesale, but any time a list of tests in test_main would otherwise need to be updated, consideration should instead be given to deleting test_main.
This commit is contained in:
parent
b019ee752a
commit
78fc25c77f
|
@ -80,17 +80,12 @@ A basic boilerplate is often used::
|
||||||
|
|
||||||
... more test classes ...
|
... more test classes ...
|
||||||
|
|
||||||
def test_main():
|
|
||||||
support.run_unittest(MyTestCase1,
|
|
||||||
MyTestCase2,
|
|
||||||
... list other tests ...
|
|
||||||
)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_main()
|
unittest.main()
|
||||||
|
|
||||||
This boilerplate code allows the testing suite to be run by :mod:`test.regrtest`
|
This code pattern allows the testing suite to be run by :mod:`test.regrtest`,
|
||||||
as well as on its own as a script.
|
on its own as a script that supports the :mod:`unittest` CLI, or via the
|
||||||
|
`python -m unittest` CLI.
|
||||||
|
|
||||||
The goal for regression testing is to try to break code. This leads to a few
|
The goal for regression testing is to try to break code. This leads to a few
|
||||||
guidelines to be followed:
|
guidelines to be followed:
|
||||||
|
@ -129,22 +124,27 @@ guidelines to be followed:
|
||||||
as what type of input is used. Minimize code duplication by subclassing a
|
as what type of input is used. Minimize code duplication by subclassing a
|
||||||
basic test class with a class that specifies the input::
|
basic test class with a class that specifies the input::
|
||||||
|
|
||||||
class TestFuncAcceptsSequences(unittest.TestCase):
|
class TestFuncAcceptsSequencesMixin:
|
||||||
|
|
||||||
func = mySuperWhammyFunction
|
func = mySuperWhammyFunction
|
||||||
|
|
||||||
def test_func(self):
|
def test_func(self):
|
||||||
self.func(self.arg)
|
self.func(self.arg)
|
||||||
|
|
||||||
class AcceptLists(TestFuncAcceptsSequences):
|
class AcceptLists(TestFuncAcceptsSequencesMixin, unittest.TestCase):
|
||||||
arg = [1, 2, 3]
|
arg = [1, 2, 3]
|
||||||
|
|
||||||
class AcceptStrings(TestFuncAcceptsSequences):
|
class AcceptStrings(TestFuncAcceptsSequencesMixin, unittest.TestCase):
|
||||||
arg = 'abc'
|
arg = 'abc'
|
||||||
|
|
||||||
class AcceptTuples(TestFuncAcceptsSequences):
|
class AcceptTuples(TestFuncAcceptsSequencesMixin, unittest.TestCase):
|
||||||
arg = (1, 2, 3)
|
arg = (1, 2, 3)
|
||||||
|
|
||||||
|
When using this pattern, remember that all classes that inherit from
|
||||||
|
`unittest.TestCase` are run as tests. The `Mixin` class in the example above
|
||||||
|
does not have any data and so can't be run by itself, thus it does not
|
||||||
|
inherit from `unittest.TestCase`.
|
||||||
|
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
|
@ -164,10 +164,12 @@ test.regrtest` used in previous Python versions still works).
|
||||||
Running the script by itself automatically starts running all regression
|
Running the script by itself automatically starts running all regression
|
||||||
tests in the :mod:`test` package. It does this by finding all modules in the
|
tests in the :mod:`test` package. It does this by finding all modules in the
|
||||||
package whose name starts with ``test_``, importing them, and executing the
|
package whose name starts with ``test_``, importing them, and executing the
|
||||||
function :func:`test_main` if present. The names of tests to execute may also
|
function :func:`test_main` if present or loading the tests via
|
||||||
|
unittest.TestLoader.loadTestsFromModule if ``test_main`` does not exist.
|
||||||
|
The names of tests to execute may also
|
||||||
be passed to the script. Specifying a single regression test (:program:`python
|
be passed to the script. Specifying a single regression test (:program:`python
|
||||||
-m test test_spam`) will minimize output and only print
|
-m test test_spam`) will minimize output and only print
|
||||||
whether the test passed or failed and thus minimize output.
|
whether the test passed or failed.
|
||||||
|
|
||||||
Running :mod:`test` directly allows what resources are available for
|
Running :mod:`test` directly allows what resources are available for
|
||||||
tests to use to be set. You do this by using the ``-u`` command-line
|
tests to use to be set. You do this by using the ``-u`` command-line
|
||||||
|
|
|
@ -1228,14 +1228,15 @@ def runtest_inner(test, verbose, quiet,
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
the_package = __import__(abstest, globals(), locals(), [])
|
the_package = __import__(abstest, globals(), locals(), [])
|
||||||
the_module = getattr(the_package, test)
|
the_module = getattr(the_package, test)
|
||||||
# Old tests run to completion simply as a side-effect of
|
# If the test has a test_main, that will run the appropriate
|
||||||
# being imported. For tests based on unittest or doctest,
|
# tests. If not, use normal unittest test loading.
|
||||||
# explicitly invoke their test_main() function (if it exists).
|
test_runner = getattr(the_module, "test_main", None)
|
||||||
indirect_test = getattr(the_module, "test_main", None)
|
if test_runner is None:
|
||||||
if indirect_test is not None:
|
tests = unittest.TestLoader().loadTestsFromModule(the_module)
|
||||||
indirect_test()
|
test_runner = lambda: support.run_unittest(tests)
|
||||||
|
test_runner()
|
||||||
if huntrleaks:
|
if huntrleaks:
|
||||||
refleak = dash_R(the_module, test, indirect_test,
|
refleak = dash_R(the_module, test, test_runner,
|
||||||
huntrleaks)
|
huntrleaks)
|
||||||
test_time = time.time() - start_time
|
test_time = time.time() - start_time
|
||||||
except support.ResourceDenied as msg:
|
except support.ResourceDenied as msg:
|
||||||
|
|
|
@ -51,6 +51,12 @@ Library
|
||||||
|
|
||||||
- Issue #14493: Use gvfs-open or xdg-open in webbrowser.
|
- Issue #14493: Use gvfs-open or xdg-open in webbrowser.
|
||||||
|
|
||||||
|
Tests
|
||||||
|
-----
|
||||||
|
|
||||||
|
- Issue #14355: Regrtest now supports the standard unittest test loading, and
|
||||||
|
will use it if a test file contains no `test_main` method.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 3.3.0 Alpha 2?
|
What's New in Python 3.3.0 Alpha 2?
|
||||||
===================================
|
===================================
|
||||||
|
|
Loading…
Reference in New Issue