From 5d31e057c572602282e66f3987b3d5d343a8f817 Mon Sep 17 00:00:00 2001 From: Michael Foord Date: Mon, 11 May 2009 17:59:43 +0000 Subject: [PATCH] Adds a verbosity keyword argument to unittest.main plus a minor fix allowing you to specify test modules / classes from the command line. Closes issue 5995. Michael Foord --- Doc/library/unittest.rst | 36 +++++++++++++++++++++++++++++++++--- Lib/test/test_unittest.py | 25 ++++++++++++++----------- Lib/unittest.py | 7 +++++-- Misc/NEWS | 6 ++++++ 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index e1d416d607a..0af3ea36b12 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -91,6 +91,31 @@ need to derive from a specific class. `python-mock `_ and `minimock `_ Tools for creating mock test objects (objects simulating external resources). +Command Line Interface +---------------------- + +The unittest module can be used from the command line to run tests from +modules, classes or even individual test methods:: + + python -m unittest test_module1 test_module2 + python -m unittest test_module.TestClass + python -m unittest test_module.TestClass.test_method + +You can pass in a list with any combination of module names, and fully qualified class or +method names. + +You can run tests with more detail (higher verbosity) by passing in the -v flag:: + + python-m unittest -v test_module + +For a list of all the command line options:: + + python -m unittest -h + +.. versionchanged:: 27 + In earlier versions it was only possible to run individual test methods and not modules + or classes. + .. _unittest-minimal-example: Basic example @@ -178,7 +203,6 @@ The above examples show the most commonly used :mod:`unittest` features which are sufficient to meet many everyday testing needs. The remainder of the documentation explores the full feature set from first principles. - .. _organizing-tests: Organizing test code @@ -1408,7 +1432,7 @@ Loading and running tests subclasses to provide a custom ``TestResult``. -.. function:: main([module[, defaultTest[, argv[, testRunner[, testLoader[, exit]]]]]]) +.. function:: main([module[, defaultTest[, argv[, testRunner[, testLoader[, exit, [verbosity]]]]]]]) 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 @@ -1417,6 +1441,12 @@ Loading and running tests if __name__ == '__main__': unittest.main() + You can run tests with more detailed information by passing in the verbosity + argument:: + + if __name__ == '__main__': + unittest.main(verbosity=2) + The *testRunner* argument can either be a test runner class or an already created instance of it. By default ``main`` calls :func:`sys.exit` with an exit code indicating success or failure of the tests run. @@ -1432,4 +1462,4 @@ Loading and running tests This stores the result of the tests run as the ``result`` attribute. .. versionchanged:: 2.7 - The ``exit`` parameter was added. + The ``exit`` and ``verbosity`` parameters were added. diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py index c77cc16f256..d815a11389d 100644 --- a/Lib/test/test_unittest.py +++ b/Lib/test/test_unittest.py @@ -3280,19 +3280,22 @@ class Test_TestProgram(TestCase): 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: + oldParseArgs = TestProgram.parseArgs + def restoreParseArgs(): TestProgram.parseArgs = oldParseArgs + TestProgram.parseArgs = lambda *args: None + self.addCleanup(restoreParseArgs) + + def removeTest(): del TestProgram.test + TestProgram.test = test + self.addCleanup(removeTest) + + program = TestProgram(testRunner=runner, exit=False, verbosity=2) + + self.assertEqual(program.result, result) + self.assertEqual(runner.test, test) + self.assertEqual(program.verbosity, 2) class FooBar(unittest.TestCase): diff --git a/Lib/unittest.py b/Lib/unittest.py index b2dc320fafd..84520d86169 100644 --- a/Lib/unittest.py +++ b/Lib/unittest.py @@ -1524,7 +1524,8 @@ Examples: """ def __init__(self, module='__main__', defaultTest=None, argv=None, testRunner=TextTestRunner, - testLoader=defaultTestLoader, exit=True): + testLoader=defaultTestLoader, exit=True, + verbosity=1): if isinstance(module, basestring): self.module = __import__(module) for part in module.split('.')[1:]: @@ -1535,7 +1536,7 @@ Examples: argv = sys.argv self.exit = exit - self.verbosity = 1 + self.verbosity = verbosity self.defaultTest = defaultTest self.testRunner = testRunner self.testLoader = testLoader @@ -1566,6 +1567,7 @@ Examples: return if len(args) > 0: self.testNames = args + self.module = None else: self.testNames = (self.defaultTest,) self.createTests() @@ -1598,4 +1600,5 @@ main = TestProgram ############################################################################## if __name__ == "__main__": + sys.modules['unittest'] = sys.modules['__main__'] main(module=None) diff --git a/Misc/NEWS b/Misc/NEWS index c79ee755295..8689f141954 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -428,6 +428,12 @@ Library - Issue #3379: unittest.main now takes an optional exit argument. If False main doesn't call sys.exit allowing it to be used from the interactive interpreter. + +- Issue #5995: unittest.main now takes an optional verbosity argument allowing + test modules to be run with a higher than default verbosity. + +- Issue 5995: A fix to allow you to run "python -m unittest test_module" or + "python -m unittest test_module.TestClass" from the command line. - Issue #5728: unittest.TestResult has new startTestRun and stopTestRun methods; called immediately before and after a test run.