This commit is contained in:
parent
7430989cda
commit
07ef487a96
|
@ -1318,6 +1318,20 @@ Loading and running tests
|
||||||
The default implementation does nothing.
|
The default implementation does nothing.
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: startTestRun(test)
|
||||||
|
|
||||||
|
Called once before any tests are executed.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: stopTestRun(test)
|
||||||
|
|
||||||
|
Called once before any tests are executed.
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
|
|
||||||
.. method:: addError(test, err)
|
.. method:: addError(test, err)
|
||||||
|
|
||||||
Called when the test case *test* raises an unexpected exception *err* is a
|
Called when the test case *test* raises an unexpected exception *err* is a
|
||||||
|
|
|
@ -517,6 +517,10 @@ changes, or look through the Subversion logs for all the details.
|
||||||
If False ``main`` doesn't call :func:`sys.exit` allowing it to
|
If False ``main`` doesn't call :func:`sys.exit` allowing it to
|
||||||
be used from the interactive interpreter. :issue:`3379`.
|
be used from the interactive interpreter. :issue:`3379`.
|
||||||
|
|
||||||
|
:class:`TestResult` has new :meth:`startTestRun` and
|
||||||
|
:meth:`stopTestRun` methods; called immediately before
|
||||||
|
and after a test run. :issue:`5728` by Robert Collins.
|
||||||
|
|
||||||
* The :func:`is_zipfile` function in the :mod:`zipfile` module will now
|
* 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
|
accept a file object, in addition to the path names accepted in earlier
|
||||||
versions. (Contributed by Gabriel Genellina; :issue:`4756`.)
|
versions. (Contributed by Gabriel Genellina; :issue:`4756`.)
|
||||||
|
|
|
@ -6,6 +6,7 @@ Still need testing:
|
||||||
TestCase.{assert,fail}* methods (some are tested implicitly)
|
TestCase.{assert,fail}* methods (some are tested implicitly)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from StringIO import StringIO
|
||||||
import re
|
import re
|
||||||
from test import test_support
|
from test import test_support
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -26,10 +27,18 @@ class LoggingResult(unittest.TestResult):
|
||||||
self._events.append('startTest')
|
self._events.append('startTest')
|
||||||
super(LoggingResult, self).startTest(test)
|
super(LoggingResult, self).startTest(test)
|
||||||
|
|
||||||
|
def startTestRun(self):
|
||||||
|
self._events.append('startTestRun')
|
||||||
|
super(LoggingResult, self).startTestRun()
|
||||||
|
|
||||||
def stopTest(self, test):
|
def stopTest(self, test):
|
||||||
self._events.append('stopTest')
|
self._events.append('stopTest')
|
||||||
super(LoggingResult, self).stopTest(test)
|
super(LoggingResult, self).stopTest(test)
|
||||||
|
|
||||||
|
def stopTestRun(self):
|
||||||
|
self._events.append('stopTestRun')
|
||||||
|
super(LoggingResult, self).stopTestRun()
|
||||||
|
|
||||||
def addFailure(self, *args):
|
def addFailure(self, *args):
|
||||||
self._events.append('addFailure')
|
self._events.append('addFailure')
|
||||||
super(LoggingResult, self).addFailure(*args)
|
super(LoggingResult, self).addFailure(*args)
|
||||||
|
@ -1817,6 +1826,12 @@ class Test_TestResult(TestCase):
|
||||||
self.assertEqual(result.testsRun, 1)
|
self.assertEqual(result.testsRun, 1)
|
||||||
self.assertEqual(result.shouldStop, False)
|
self.assertEqual(result.shouldStop, False)
|
||||||
|
|
||||||
|
# "Called before and after tests are run. The default implementation does nothing."
|
||||||
|
def test_startTestRun_stopTestRun(self):
|
||||||
|
result = unittest.TestResult()
|
||||||
|
result.startTestRun()
|
||||||
|
result.stopTestRun()
|
||||||
|
|
||||||
# "addSuccess(test)"
|
# "addSuccess(test)"
|
||||||
# ...
|
# ...
|
||||||
# "Called when the test case test succeeds"
|
# "Called when the test case test succeeds"
|
||||||
|
@ -1964,6 +1979,53 @@ class Foo(unittest.TestCase):
|
||||||
class Bar(Foo):
|
class Bar(Foo):
|
||||||
def test2(self): pass
|
def test2(self): pass
|
||||||
|
|
||||||
|
class LoggingTestCase(unittest.TestCase):
|
||||||
|
"""A test case which logs its calls."""
|
||||||
|
|
||||||
|
def __init__(self, events):
|
||||||
|
super(LoggingTestCase, self).__init__('test')
|
||||||
|
self.events = events
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.events.append('setUp')
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
self.events.append('test')
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.events.append('tearDown')
|
||||||
|
|
||||||
|
class ResultWithNoStartTestRunStopTestRun(object):
|
||||||
|
"""An object honouring TestResult before startTestRun/stopTestRun."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.failures = []
|
||||||
|
self.errors = []
|
||||||
|
self.testsRun = 0
|
||||||
|
self.skipped = []
|
||||||
|
self.expectedFailures = []
|
||||||
|
self.unexpectedSuccesses = []
|
||||||
|
self.shouldStop = False
|
||||||
|
|
||||||
|
def startTest(self, test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stopTest(self, test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def addError(self, test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def addFailure(self, test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def addSuccess(self, test):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def wasSuccessful(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
### /Support code for Test_TestCase
|
### /Support code for Test_TestCase
|
||||||
|
|
||||||
|
@ -2058,21 +2120,32 @@ class Test_TestCase(TestCase, TestEquality, TestHashing):
|
||||||
events = []
|
events = []
|
||||||
result = LoggingResult(events)
|
result = LoggingResult(events)
|
||||||
|
|
||||||
class Foo(unittest.TestCase):
|
class Foo(LoggingTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
events.append('setUp')
|
super(Foo, self).setUp()
|
||||||
raise RuntimeError('raised by Foo.setUp')
|
raise RuntimeError('raised by Foo.setUp')
|
||||||
|
|
||||||
def test(self):
|
Foo(events).run(result)
|
||||||
events.append('test')
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
events.append('tearDown')
|
|
||||||
|
|
||||||
Foo('test').run(result)
|
|
||||||
expected = ['startTest', 'setUp', 'addError', 'stopTest']
|
expected = ['startTest', 'setUp', 'addError', 'stopTest']
|
||||||
self.assertEqual(events, expected)
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
|
# "With a temporary result stopTestRun is called when setUp errors.
|
||||||
|
def test_run_call_order__error_in_setUp_default_result(self):
|
||||||
|
events = []
|
||||||
|
|
||||||
|
class Foo(LoggingTestCase):
|
||||||
|
def defaultTestResult(self):
|
||||||
|
return LoggingResult(self.events)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(Foo, self).setUp()
|
||||||
|
raise RuntimeError('raised by Foo.setUp')
|
||||||
|
|
||||||
|
Foo(events).run()
|
||||||
|
expected = ['startTestRun', 'startTest', 'setUp', 'addError',
|
||||||
|
'stopTest', 'stopTestRun']
|
||||||
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
# "When a setUp() method is defined, the test runner will run that method
|
# "When a setUp() method is defined, the test runner will run that method
|
||||||
# prior to each test. Likewise, if a tearDown() method is defined, the
|
# prior to each test. Likewise, if a tearDown() method is defined, the
|
||||||
# test runner will invoke that method after each test. In the example,
|
# test runner will invoke that method after each test. In the example,
|
||||||
|
@ -2084,20 +2157,32 @@ class Test_TestCase(TestCase, TestEquality, TestHashing):
|
||||||
events = []
|
events = []
|
||||||
result = LoggingResult(events)
|
result = LoggingResult(events)
|
||||||
|
|
||||||
class Foo(unittest.TestCase):
|
class Foo(LoggingTestCase):
|
||||||
def setUp(self):
|
|
||||||
events.append('setUp')
|
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
events.append('test')
|
super(Foo, self).test()
|
||||||
raise RuntimeError('raised by Foo.test')
|
raise RuntimeError('raised by Foo.test')
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
events.append('tearDown')
|
|
||||||
|
|
||||||
expected = ['startTest', 'setUp', 'test', 'addError', 'tearDown',
|
expected = ['startTest', 'setUp', 'test', 'addError', 'tearDown',
|
||||||
'stopTest']
|
'stopTest']
|
||||||
Foo('test').run(result)
|
Foo(events).run(result)
|
||||||
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
|
# "With a default result, an error in the test still results in stopTestRun
|
||||||
|
# being called."
|
||||||
|
def test_run_call_order__error_in_test_default_result(self):
|
||||||
|
events = []
|
||||||
|
|
||||||
|
class Foo(LoggingTestCase):
|
||||||
|
def defaultTestResult(self):
|
||||||
|
return LoggingResult(self.events)
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
super(Foo, self).test()
|
||||||
|
raise RuntimeError('raised by Foo.test')
|
||||||
|
|
||||||
|
expected = ['startTestRun', 'startTest', 'setUp', 'test', 'addError',
|
||||||
|
'tearDown', 'stopTest', 'stopTestRun']
|
||||||
|
Foo(events).run()
|
||||||
self.assertEqual(events, expected)
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
# "When a setUp() method is defined, the test runner will run that method
|
# "When a setUp() method is defined, the test runner will run that method
|
||||||
|
@ -2111,20 +2196,30 @@ class Test_TestCase(TestCase, TestEquality, TestHashing):
|
||||||
events = []
|
events = []
|
||||||
result = LoggingResult(events)
|
result = LoggingResult(events)
|
||||||
|
|
||||||
class Foo(unittest.TestCase):
|
class Foo(LoggingTestCase):
|
||||||
def setUp(self):
|
|
||||||
events.append('setUp')
|
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
events.append('test')
|
super(Foo, self).test()
|
||||||
self.fail('raised by Foo.test')
|
self.fail('raised by Foo.test')
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
events.append('tearDown')
|
|
||||||
|
|
||||||
expected = ['startTest', 'setUp', 'test', 'addFailure', 'tearDown',
|
expected = ['startTest', 'setUp', 'test', 'addFailure', 'tearDown',
|
||||||
'stopTest']
|
'stopTest']
|
||||||
Foo('test').run(result)
|
Foo(events).run(result)
|
||||||
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
|
# "When a test fails with a default result stopTestRun is still called."
|
||||||
|
def test_run_call_order__failure_in_test_default_result(self):
|
||||||
|
|
||||||
|
class Foo(LoggingTestCase):
|
||||||
|
def defaultTestResult(self):
|
||||||
|
return LoggingResult(self.events)
|
||||||
|
def test(self):
|
||||||
|
super(Foo, self).test()
|
||||||
|
self.fail('raised by Foo.test')
|
||||||
|
|
||||||
|
expected = ['startTestRun', 'startTest', 'setUp', 'test', 'addFailure',
|
||||||
|
'tearDown', 'stopTest', 'stopTestRun']
|
||||||
|
events = []
|
||||||
|
Foo(events).run()
|
||||||
self.assertEqual(events, expected)
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
# "When a setUp() method is defined, the test runner will run that method
|
# "When a setUp() method is defined, the test runner will run that method
|
||||||
|
@ -2138,22 +2233,44 @@ class Test_TestCase(TestCase, TestEquality, TestHashing):
|
||||||
events = []
|
events = []
|
||||||
result = LoggingResult(events)
|
result = LoggingResult(events)
|
||||||
|
|
||||||
class Foo(unittest.TestCase):
|
class Foo(LoggingTestCase):
|
||||||
def setUp(self):
|
|
||||||
events.append('setUp')
|
|
||||||
|
|
||||||
def test(self):
|
|
||||||
events.append('test')
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
events.append('tearDown')
|
super(Foo, self).tearDown()
|
||||||
raise RuntimeError('raised by Foo.tearDown')
|
raise RuntimeError('raised by Foo.tearDown')
|
||||||
|
|
||||||
Foo('test').run(result)
|
Foo(events).run(result)
|
||||||
expected = ['startTest', 'setUp', 'test', 'tearDown', 'addError',
|
expected = ['startTest', 'setUp', 'test', 'tearDown', 'addError',
|
||||||
'stopTest']
|
'stopTest']
|
||||||
self.assertEqual(events, expected)
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
|
# "When tearDown errors with a default result stopTestRun is still called."
|
||||||
|
def test_run_call_order__error_in_tearDown_default_result(self):
|
||||||
|
|
||||||
|
class Foo(LoggingTestCase):
|
||||||
|
def defaultTestResult(self):
|
||||||
|
return LoggingResult(self.events)
|
||||||
|
def tearDown(self):
|
||||||
|
super(Foo, self).tearDown()
|
||||||
|
raise RuntimeError('raised by Foo.tearDown')
|
||||||
|
|
||||||
|
events = []
|
||||||
|
Foo(events).run()
|
||||||
|
expected = ['startTestRun', 'startTest', 'setUp', 'test', 'tearDown',
|
||||||
|
'addError', 'stopTest', 'stopTestRun']
|
||||||
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
|
# "TestCase.run() still works when the defaultTestResult is a TestResult
|
||||||
|
# that does not support startTestRun and stopTestRun.
|
||||||
|
def test_run_call_order_default_result(self):
|
||||||
|
|
||||||
|
class Foo(unittest.TestCase):
|
||||||
|
def defaultTestResult(self):
|
||||||
|
return ResultWithNoStartTestRunStopTestRun()
|
||||||
|
def test(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
Foo('test').run()
|
||||||
|
|
||||||
# "This class attribute gives the exception raised by the test() method.
|
# "This class attribute gives the exception raised by the test() method.
|
||||||
# If a test framework needs to use a specialized exception, possibly to
|
# If a test framework needs to use a specialized exception, possibly to
|
||||||
# carry additional information, it must subclass this exception in
|
# carry additional information, it must subclass this exception in
|
||||||
|
@ -2244,7 +2361,9 @@ class Test_TestCase(TestCase, TestEquality, TestHashing):
|
||||||
self.failUnless(isinstance(Foo().id(), basestring))
|
self.failUnless(isinstance(Foo().id(), basestring))
|
||||||
|
|
||||||
# "If result is omitted or None, a temporary result object is created
|
# "If result is omitted or None, a temporary result object is created
|
||||||
# and used, but is not made available to the caller"
|
# and used, but is not made available to the caller. As TestCase owns the
|
||||||
|
# temporary result startTestRun and stopTestRun are called.
|
||||||
|
|
||||||
def test_run__uses_defaultTestResult(self):
|
def test_run__uses_defaultTestResult(self):
|
||||||
events = []
|
events = []
|
||||||
|
|
||||||
|
@ -2258,7 +2377,8 @@ class Test_TestCase(TestCase, TestEquality, TestHashing):
|
||||||
# Make run() find a result object on its own
|
# Make run() find a result object on its own
|
||||||
Foo('test').run()
|
Foo('test').run()
|
||||||
|
|
||||||
expected = ['startTest', 'test', 'addSuccess', 'stopTest']
|
expected = ['startTestRun', 'startTest', 'test', 'addSuccess',
|
||||||
|
'stopTest', 'stopTestRun']
|
||||||
self.assertEqual(events, expected)
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
def testShortDescriptionWithoutDocstring(self):
|
def testShortDescriptionWithoutDocstring(self):
|
||||||
|
@ -3215,6 +3335,46 @@ class Test_TestProgram(TestCase):
|
||||||
testLoader=self.FooBarLoader())
|
testLoader=self.FooBarLoader())
|
||||||
|
|
||||||
|
|
||||||
|
class Test_TextTestRunner(TestCase):
|
||||||
|
"""Tests for TextTestRunner."""
|
||||||
|
|
||||||
|
def test_works_with_result_without_startTestRun_stopTestRun(self):
|
||||||
|
class OldTextResult(ResultWithNoStartTestRunStopTestRun):
|
||||||
|
separator2 = ''
|
||||||
|
def printErrors(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Runner(unittest.TextTestRunner):
|
||||||
|
def __init__(self):
|
||||||
|
super(Runner, self).__init__(StringIO())
|
||||||
|
|
||||||
|
def _makeResult(self):
|
||||||
|
return OldTextResult()
|
||||||
|
|
||||||
|
runner = Runner()
|
||||||
|
runner.run(unittest.TestSuite())
|
||||||
|
|
||||||
|
def test_startTestRun_stopTestRun_called(self):
|
||||||
|
class LoggingTextResult(LoggingResult):
|
||||||
|
separator2 = ''
|
||||||
|
def printErrors(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class LoggingRunner(unittest.TextTestRunner):
|
||||||
|
def __init__(self, events):
|
||||||
|
super(LoggingRunner, self).__init__(StringIO())
|
||||||
|
self._events = events
|
||||||
|
|
||||||
|
def _makeResult(self):
|
||||||
|
return LoggingTextResult(self._events)
|
||||||
|
|
||||||
|
events = []
|
||||||
|
runner = LoggingRunner(events)
|
||||||
|
runner.run(unittest.TestSuite())
|
||||||
|
expected = ['startTestRun', 'stopTestRun']
|
||||||
|
self.assertEqual(events, expected)
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
## Main
|
## Main
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
|
@ -186,10 +186,22 @@ class TestResult(object):
|
||||||
"Called when the given test is about to be run"
|
"Called when the given test is about to be run"
|
||||||
self.testsRun = self.testsRun + 1
|
self.testsRun = self.testsRun + 1
|
||||||
|
|
||||||
|
def startTestRun(self):
|
||||||
|
"""Called once before any tests are executed.
|
||||||
|
|
||||||
|
See startTest for a method called before each test.
|
||||||
|
"""
|
||||||
|
|
||||||
def stopTest(self, test):
|
def stopTest(self, test):
|
||||||
"Called when the given test has been run"
|
"Called when the given test has been run"
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def stopTestRun(self):
|
||||||
|
"""Called once after all tests are executed.
|
||||||
|
|
||||||
|
See stopTest for a method called after each test.
|
||||||
|
"""
|
||||||
|
|
||||||
def addError(self, test, err):
|
def addError(self, test, err):
|
||||||
"""Called when an error has occurred. 'err' is a tuple of values as
|
"""Called when an error has occurred. 'err' is a tuple of values as
|
||||||
returned by sys.exc_info().
|
returned by sys.exc_info().
|
||||||
|
@ -437,8 +449,13 @@ class TestCase(object):
|
||||||
(_strclass(self.__class__), self._testMethodName)
|
(_strclass(self.__class__), self._testMethodName)
|
||||||
|
|
||||||
def run(self, result=None):
|
def run(self, result=None):
|
||||||
|
orig_result = result
|
||||||
if result is None:
|
if result is None:
|
||||||
result = self.defaultTestResult()
|
result = self.defaultTestResult()
|
||||||
|
startTestRun = getattr(result, 'startTestRun', None)
|
||||||
|
if startTestRun is not None:
|
||||||
|
startTestRun()
|
||||||
|
|
||||||
self._result = result
|
self._result = result
|
||||||
result.startTest(self)
|
result.startTest(self)
|
||||||
testMethod = getattr(self, self._testMethodName)
|
testMethod = getattr(self, self._testMethodName)
|
||||||
|
@ -478,6 +495,10 @@ class TestCase(object):
|
||||||
result.addSuccess(self)
|
result.addSuccess(self)
|
||||||
finally:
|
finally:
|
||||||
result.stopTest(self)
|
result.stopTest(self)
|
||||||
|
if orig_result is None:
|
||||||
|
stopTestRun = getattr(result, 'stopTestRun', None)
|
||||||
|
if stopTestRun is not None:
|
||||||
|
stopTestRun()
|
||||||
|
|
||||||
def doCleanups(self):
|
def doCleanups(self):
|
||||||
"""Execute all cleanup functions. Normally called for you after
|
"""Execute all cleanup functions. Normally called for you after
|
||||||
|
@ -1433,7 +1454,15 @@ class TextTestRunner(object):
|
||||||
"Run the given test case or test suite."
|
"Run the given test case or test suite."
|
||||||
result = self._makeResult()
|
result = self._makeResult()
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
|
startTestRun = getattr(result, 'startTestRun', None)
|
||||||
|
if startTestRun is not None:
|
||||||
|
startTestRun()
|
||||||
|
try:
|
||||||
test(result)
|
test(result)
|
||||||
|
finally:
|
||||||
|
stopTestRun = getattr(result, 'stopTestRun', None)
|
||||||
|
if stopTestRun is not None:
|
||||||
|
stopTestRun()
|
||||||
stopTime = time.time()
|
stopTime = time.time()
|
||||||
timeTaken = stopTime - startTime
|
timeTaken = stopTime - startTime
|
||||||
result.printErrors()
|
result.printErrors()
|
||||||
|
|
11
Misc/NEWS
11
Misc/NEWS
|
@ -359,6 +359,17 @@ Library
|
||||||
- unittest.assertNotEqual() now uses the inequality operator (!=) instead
|
- unittest.assertNotEqual() now uses the inequality operator (!=) instead
|
||||||
of the equality operator.
|
of the equality operator.
|
||||||
|
|
||||||
|
- Issue #5679: The methods unittest.TestCase.addCleanup and doCleanups were added.
|
||||||
|
addCleanup allows you to add cleanup functions that will be called
|
||||||
|
unconditionally (after setUp if setUp fails, otherwise after tearDown). This
|
||||||
|
allows for much simpler resource allocation and deallocation during tests.
|
||||||
|
|
||||||
|
- 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 #5728: unittest.TestResult has new startTestRun and stopTestRun methods;
|
||||||
|
called immediately before and after a test run.
|
||||||
|
|
||||||
- Issue #5663: better failure messages for unittest asserts. Default assertTrue
|
- Issue #5663: better failure messages for unittest asserts. Default assertTrue
|
||||||
and assertFalse messages are now useful. TestCase has a longMessage attribute.
|
and assertFalse messages are now useful. TestCase has a longMessage attribute.
|
||||||
This defaults to False, but if set to True useful error messages are shown in
|
This defaults to False, but if set to True useful error messages are shown in
|
||||||
|
|
Loading…
Reference in New Issue