mirror of
https://github.com/python/cpython.git
synced 2025-10-17 04:08:28 +00:00
- New fail*() methods, and comprehensive set of assert*() synonyms
- TestCase.failureException defines the exception that indicates a test failure - Docstrings for TestLoader class - Added exc_info() hack back in
This commit is contained in:
parent
5c9aad6043
commit
15d8927f7e
1 changed files with 63 additions and 28 deletions
|
@ -131,6 +131,13 @@ class TestCase:
|
||||||
of the classes are instantiated automatically by parts of the framework
|
of the classes are instantiated automatically by parts of the framework
|
||||||
in order to be run.
|
in order to be run.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# This attribute determines which exception will be raised when
|
||||||
|
# the instance's assertion methods fail; test methods raising this
|
||||||
|
# exception will be deemed to have 'failed' rather than 'errored'
|
||||||
|
|
||||||
|
failureException = AssertionError
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
"""Create an instance of the class that will use the named test
|
"""Create an instance of the class that will use the named test
|
||||||
method when executed. Raises a ValueError if the instance does
|
method when executed. Raises a ValueError if the instance does
|
||||||
|
@ -189,22 +196,22 @@ class TestCase:
|
||||||
try:
|
try:
|
||||||
self.setUp()
|
self.setUp()
|
||||||
except:
|
except:
|
||||||
result.addError(self,sys.exc_info())
|
result.addError(self,self.__exc_info())
|
||||||
return
|
return
|
||||||
|
|
||||||
ok = 0
|
ok = 0
|
||||||
try:
|
try:
|
||||||
testMethod()
|
testMethod()
|
||||||
ok = 1
|
ok = 1
|
||||||
except AssertionError, e:
|
except self.failureException, e:
|
||||||
result.addFailure(self,sys.exc_info())
|
result.addFailure(self,self.__exc_info())
|
||||||
except:
|
except:
|
||||||
result.addError(self,sys.exc_info())
|
result.addError(self,self.__exc_info())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.tearDown()
|
self.tearDown()
|
||||||
except:
|
except:
|
||||||
result.addError(self,sys.exc_info())
|
result.addError(self,self.__exc_info())
|
||||||
ok = 0
|
ok = 0
|
||||||
if ok: result.addSuccess(self)
|
if ok: result.addSuccess(self)
|
||||||
finally:
|
finally:
|
||||||
|
@ -216,21 +223,33 @@ class TestCase:
|
||||||
getattr(self, self.__testMethodName)()
|
getattr(self, self.__testMethodName)()
|
||||||
self.tearDown()
|
self.tearDown()
|
||||||
|
|
||||||
def assert_(self, expr, msg=None):
|
def __exc_info(self):
|
||||||
"""Equivalent of built-in 'assert', but is not optimised out when
|
"""Return a version of sys.exc_info() with the traceback frame
|
||||||
__debug__ is false.
|
minimised; usually the top level of the traceback frame is not
|
||||||
|
needed.
|
||||||
"""
|
"""
|
||||||
if not expr:
|
exctype, excvalue, tb = sys.exc_info()
|
||||||
raise AssertionError, msg
|
if sys.platform[:4] == 'java': ## tracebacks look different in Jython
|
||||||
|
return (exctype, excvalue, tb)
|
||||||
|
newtb = tb.tb_next
|
||||||
|
if newtb is None:
|
||||||
|
return (exctype, excvalue, tb)
|
||||||
|
return (exctype, excvalue, newtb)
|
||||||
|
|
||||||
failUnless = assert_
|
def fail(self, msg=None):
|
||||||
|
"""Fail immediately, with the given message."""
|
||||||
|
raise self.failureException, msg
|
||||||
|
|
||||||
def failIf(self, expr, msg=None):
|
def failIf(self, expr, msg=None):
|
||||||
"Fail the test if the expression is true."
|
"Fail the test if the expression is true."
|
||||||
apply(self.assert_,(not expr,msg))
|
if expr: raise self.failureException, msg
|
||||||
|
|
||||||
def assertRaises(self, excClass, callableObj, *args, **kwargs):
|
def failUnless(self, expr, msg=None):
|
||||||
"""Assert that an exception of class excClass is thrown
|
"""Fail the test unless the expression is true."""
|
||||||
|
if not expr: raise self.failureException, msg
|
||||||
|
|
||||||
|
def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
|
||||||
|
"""Fail unless an exception of class excClass is thrown
|
||||||
by callableObj when invoked with arguments args and keyword
|
by callableObj when invoked with arguments args and keyword
|
||||||
arguments kwargs. If a different type of exception is
|
arguments kwargs. If a different type of exception is
|
||||||
thrown, it will not be caught, and the test case will be
|
thrown, it will not be caught, and the test case will be
|
||||||
|
@ -244,27 +263,30 @@ class TestCase:
|
||||||
else:
|
else:
|
||||||
if hasattr(excClass,'__name__'): excName = excClass.__name__
|
if hasattr(excClass,'__name__'): excName = excClass.__name__
|
||||||
else: excName = str(excClass)
|
else: excName = str(excClass)
|
||||||
raise AssertionError, excName
|
raise self.failureException, excName
|
||||||
|
|
||||||
def assertEquals(self, first, second, msg=None):
|
def failUnlessEqual(self, first, second, msg=None):
|
||||||
"""Assert that the two objects are equal as determined by the '=='
|
"""Fail if the two objects are unequal as determined by the '!='
|
||||||
operator.
|
operator.
|
||||||
"""
|
"""
|
||||||
self.assert_((first == second), msg or '%s != %s' % (first, second))
|
if first != second:
|
||||||
|
raise self.failureException, (msg or '%s != %s' % (first, second))
|
||||||
|
|
||||||
def assertNotEquals(self, first, second, msg=None):
|
def failIfEqual(self, first, second, msg=None):
|
||||||
"""Assert that the two objects are unequal as determined by the '!='
|
"""Fail if the two objects are equal as determined by the '=='
|
||||||
operator.
|
operator.
|
||||||
"""
|
"""
|
||||||
self.assert_((first != second), msg or '%s == %s' % (first, second))
|
if first == second:
|
||||||
|
raise self.failureException, (msg or '%s != %s' % (first, second))
|
||||||
|
|
||||||
assertEqual = assertEquals
|
assertEqual = assertEquals = failUnlessEqual
|
||||||
|
|
||||||
assertNotEqual = assertNotEquals
|
assertNotEqual = assertNotEquals = failIfEqual
|
||||||
|
|
||||||
|
assertRaises = failUnlessRaises
|
||||||
|
|
||||||
|
assert_ = failUnless
|
||||||
|
|
||||||
def fail(self, msg=None):
|
|
||||||
"""Fail immediately, with the given message."""
|
|
||||||
raise AssertionError, msg
|
|
||||||
|
|
||||||
|
|
||||||
class TestSuite:
|
class TestSuite:
|
||||||
|
@ -364,18 +386,18 @@ class FunctionTestCase(TestCase):
|
||||||
class TestLoader:
|
class TestLoader:
|
||||||
"""This class is responsible for loading tests according to various
|
"""This class is responsible for loading tests according to various
|
||||||
criteria and returning them wrapped in a Test
|
criteria and returning them wrapped in a Test
|
||||||
|
|
||||||
It can load all tests within a given, module
|
|
||||||
"""
|
"""
|
||||||
testMethodPrefix = 'test'
|
testMethodPrefix = 'test'
|
||||||
sortTestMethodsUsing = cmp
|
sortTestMethodsUsing = cmp
|
||||||
suiteClass = TestSuite
|
suiteClass = TestSuite
|
||||||
|
|
||||||
def loadTestsFromTestCase(self, testCaseClass):
|
def loadTestsFromTestCase(self, testCaseClass):
|
||||||
|
"""Return a suite of all tests cases contained in testCaseClass"""
|
||||||
return self.suiteClass(map(testCaseClass,
|
return self.suiteClass(map(testCaseClass,
|
||||||
self.getTestCaseNames(testCaseClass)))
|
self.getTestCaseNames(testCaseClass)))
|
||||||
|
|
||||||
def loadTestsFromModule(self, module):
|
def loadTestsFromModule(self, module):
|
||||||
|
"""Return a suite of all tests cases contained in the given module"""
|
||||||
tests = []
|
tests = []
|
||||||
for name in dir(module):
|
for name in dir(module):
|
||||||
obj = getattr(module, name)
|
obj = getattr(module, name)
|
||||||
|
@ -384,6 +406,14 @@ class TestLoader:
|
||||||
return self.suiteClass(tests)
|
return self.suiteClass(tests)
|
||||||
|
|
||||||
def loadTestsFromName(self, name, module=None):
|
def loadTestsFromName(self, name, module=None):
|
||||||
|
"""Return a suite of all tests cases given a string specifier.
|
||||||
|
|
||||||
|
The name may resolve either to a module, a test case class, a
|
||||||
|
test method within a test case class, or a callable object which
|
||||||
|
returns a TestCase or TestSuite instance.
|
||||||
|
|
||||||
|
The method optionally resolves the names relative to a given module.
|
||||||
|
"""
|
||||||
parts = string.split(name, '.')
|
parts = string.split(name, '.')
|
||||||
if module is None:
|
if module is None:
|
||||||
if not parts:
|
if not parts:
|
||||||
|
@ -419,12 +449,17 @@ class TestLoader:
|
||||||
raise ValueError, "don't know how to make test from: %s" % obj
|
raise ValueError, "don't know how to make test from: %s" % obj
|
||||||
|
|
||||||
def loadTestsFromNames(self, names, module=None):
|
def loadTestsFromNames(self, names, module=None):
|
||||||
|
"""Return a suite of all tests cases found using the given sequence
|
||||||
|
of string specifiers. See 'loadTestsFromName()'.
|
||||||
|
"""
|
||||||
suites = []
|
suites = []
|
||||||
for name in names:
|
for name in names:
|
||||||
suites.append(self.loadTestsFromName(name, module))
|
suites.append(self.loadTestsFromName(name, module))
|
||||||
return self.suiteClass(suites)
|
return self.suiteClass(suites)
|
||||||
|
|
||||||
def getTestCaseNames(self, testCaseClass):
|
def getTestCaseNames(self, testCaseClass):
|
||||||
|
"""Return a sorted sequence of method names found within testCaseClass
|
||||||
|
"""
|
||||||
testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p,
|
testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p,
|
||||||
dir(testCaseClass))
|
dir(testCaseClass))
|
||||||
for baseclass in testCaseClass.__bases__:
|
for baseclass in testCaseClass.__bases__:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue