[Python-checkins] r72191 - in python/trunk: Doc/library/unittest.rst Doc/whatsnew/2.7.rst Lib/test/test_unittest.py Lib/unittest.py
michael.foord
python-checkins at python.org
Sat May 2 13:43:07 CEST 2009
Author: michael.foord
Date: Sat May 2 13:43:06 2009
New Revision: 72191
Log:
Adds an exit parameter to unittest.main(). If False main no longer
calls sys.exit.
Closes issue 3379.
Michael Foord
Modified:
python/trunk/Doc/library/unittest.rst
python/trunk/Doc/whatsnew/2.7.rst
python/trunk/Lib/test/test_unittest.py
python/trunk/Lib/unittest.py
Modified: python/trunk/Doc/library/unittest.rst
==============================================================================
--- python/trunk/Doc/library/unittest.rst (original)
+++ python/trunk/Doc/library/unittest.rst Sat May 2 13:43:06 2009
@@ -1364,7 +1364,7 @@
subclasses to provide a custom ``TestResult``.
-.. function:: main([module[, defaultTest[, argv[, testRunner[, testLoader]]]]])
+.. function:: main([module[, defaultTest[, argv[, testRunner[, testLoader[, exit]]]]]])
A command-line program that runs a set of tests; this is primarily for making
test modules conveniently executable. The simplest use for this function is to
@@ -1374,4 +1374,18 @@
unittest.main()
The *testRunner* argument can either be a test runner class or an already
- created instance of it.
+ created instance of it. By default ``main`` calls :func:`sys.exit` with
+ an exit code indicating success or failure of the tests run.
+
+ ``main`` supports being used from the interactive interpreter by passing in the
+ argument ``exit=False``. This displays the result on standard output without
+ calling :func:`sys.exit`::
+
+ >>> from unittest import main
+ >>> main(module='test_module', exit=False)
+
+ Calling ``main`` actually returns an instance of the ``TestProgram`` class.
+ This stores the result of the tests run as the ``result`` attribute.
+
+ .. versionchanged:: 2.7
+ The ``exit`` parameter was added.
Modified: python/trunk/Doc/whatsnew/2.7.rst
==============================================================================
--- python/trunk/Doc/whatsnew/2.7.rst (original)
+++ python/trunk/Doc/whatsnew/2.7.rst Sat May 2 13:43:06 2009
@@ -477,6 +477,10 @@
to provide additional information about why the two objects are
matching, much as the new sequence comparison methods do.
+ :func:`unittest.main` now takes an optional ``exit`` argument.
+ If False ``main`` doesn't call :func:`sys.exit` allowing it to
+ be used from the interactive interpreter. :issue:`3379`.
+
* The :func:`is_zipfile` function in the :mod:`zipfile` module will now
accept a file object, in addition to the path names accepted in earlier
versions. (Contributed by Gabriel Genellina; :issue:`4756`.)
Modified: python/trunk/Lib/test/test_unittest.py
==============================================================================
--- python/trunk/Lib/test/test_unittest.py (original)
+++ python/trunk/Lib/test/test_unittest.py Sat May 2 13:43:06 2009
@@ -9,9 +9,10 @@
import re
from test import test_support
import unittest
-from unittest import TestCase
+from unittest import TestCase, TestProgram
import types
from copy import deepcopy
+from cStringIO import StringIO
### Support code
################################################################
@@ -3040,6 +3041,73 @@
"^unexpectedly identical: None : oops$"])
+class Test_TestProgram(TestCase):
+
+ # Horrible white box test
+ def testNoExit(self):
+ result = object()
+ test = object()
+
+ class FakeRunner(object):
+ def run(self, test):
+ self.test = test
+ return result
+
+ runner = FakeRunner()
+
+ try:
+ oldParseArgs = TestProgram.parseArgs
+ TestProgram.parseArgs = lambda *args: None
+ TestProgram.test = test
+
+ program = TestProgram(testRunner=runner, exit=False)
+
+ self.assertEqual(program.result, result)
+ self.assertEqual(runner.test, test)
+
+ finally:
+ TestProgram.parseArgs = oldParseArgs
+ del TestProgram.test
+
+
+ class FooBar(unittest.TestCase):
+ def testPass(self):
+ assert True
+ def testFail(self):
+ assert False
+
+ class FooBarLoader(unittest.TestLoader):
+ """Test loader that returns a suite containing FooBar."""
+ def loadTestsFromModule(self, module):
+ return self.suiteClass(
+ [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
+
+
+ def test_NonExit(self):
+ program = unittest.main(exit=False,
+ testRunner=unittest.TextTestRunner(stream=StringIO()),
+ testLoader=self.FooBarLoader())
+ self.assertTrue(hasattr(program, 'result'))
+
+
+ def test_Exit(self):
+ self.assertRaises(
+ SystemExit,
+ unittest.main,
+ testRunner=unittest.TextTestRunner(stream=StringIO()),
+ exit=True,
+ testLoader=self.FooBarLoader())
+
+
+ def test_ExitAsDefault(self):
+ self.assertRaises(
+ SystemExit,
+ unittest.main,
+ testRunner=unittest.TextTestRunner(stream=StringIO()),
+ testLoader=self.FooBarLoader())
+
+
+
######################################################################
## Main
######################################################################
@@ -3047,7 +3115,8 @@
def test_main():
test_support.run_unittest(Test_TestCase, Test_TestLoader,
Test_TestSuite, Test_TestResult, Test_FunctionTestCase,
- Test_TestSkipping, Test_Assertions, TestLongMessage)
+ Test_TestSkipping, Test_Assertions, TestLongMessage,
+ Test_TestProgram)
if __name__ == "__main__":
test_main()
Modified: python/trunk/Lib/unittest.py
==============================================================================
--- python/trunk/Lib/unittest.py (original)
+++ python/trunk/Lib/unittest.py Sat May 2 13:43:06 2009
@@ -1015,7 +1015,7 @@
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
- return self._tests == other._tests
+ return list(self) == list(other)
def __ne__(self, other):
return not self == other
@@ -1469,7 +1469,7 @@
"""
def __init__(self, module='__main__', defaultTest=None,
argv=None, testRunner=TextTestRunner,
- testLoader=defaultTestLoader):
+ testLoader=defaultTestLoader, exit=True):
if isinstance(module, basestring):
self.module = __import__(module)
for part in module.split('.')[1:]:
@@ -1478,6 +1478,8 @@
self.module = module
if argv is None:
argv = sys.argv
+
+ self.exit = exit
self.verbosity = 1
self.defaultTest = defaultTest
self.testRunner = testRunner
@@ -1529,15 +1531,12 @@
else:
# it is assumed to be a TestRunner instance
testRunner = self.testRunner
- result = testRunner.run(self.test)
- sys.exit(not result.wasSuccessful())
+ self.result = testRunner.run(self.test)
+ if self.exit:
+ sys.exit(not self.result.wasSuccessful())
main = TestProgram
-##############################################################################
-# Executing this module from the command line
-##############################################################################
-
if __name__ == "__main__":
main(module=None)
More information about the Python-checkins
mailing list