159 lines
4.3 KiB
Python
159 lines
4.3 KiB
Python
"""Generic (non-gomill-specific) test framework code."""
|
|
|
|
import sys
|
|
|
|
if sys.version_info >= (2, 7):
|
|
import unittest as unittest2
|
|
else:
|
|
try:
|
|
import unittest2
|
|
except ImportError, e:
|
|
e.unittest2_missing = True
|
|
raise
|
|
|
|
# This makes TestResult ignore lines from this module in tracebacks
|
|
__unittest = True
|
|
|
|
class SupporterError(StandardError):
|
|
"""Exception raised by support objects when something goes wrong.
|
|
|
|
This is raised to indicate things like sequencing errors detected by mock
|
|
objects.
|
|
|
|
"""
|
|
|
|
class FrameworkTestCase(unittest2.TestCase):
|
|
"""unittest2-style TestCase implementation with a few tweaks."""
|
|
|
|
# This is default in unittest2 but not python 2.7 unittest, so force it on.
|
|
longMessage = True
|
|
|
|
def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
|
|
"""Variant implementation of standard assertItemsEqual.
|
|
|
|
This uses the unorderable_list_difference check even if the lists are
|
|
sortable: I prefer its output.
|
|
|
|
"""
|
|
expected = list(expected_seq)
|
|
actual = list(actual_seq)
|
|
missing, unexpected = unittest2.util.unorderable_list_difference(
|
|
expected, actual, ignore_duplicate=False
|
|
)
|
|
errors = []
|
|
if missing:
|
|
errors.append('Expected, but missing:\n %s' %
|
|
unittest2.util.safe_repr(missing))
|
|
if unexpected:
|
|
errors.append('Unexpected, but present:\n %s' %
|
|
unittest2.util.safe_repr(unexpected))
|
|
if errors:
|
|
standardMsg = '\n'.join(errors)
|
|
self.fail(self._formatMessage(msg, standardMsg))
|
|
|
|
|
|
class SimpleTestCase(FrameworkTestCase):
|
|
"""TestCase which runs a single function.
|
|
|
|
Instantiate with the test function, which takes a TestCase parameter, eg:
|
|
def test_xxx(tc):
|
|
tc.assertEqual(2+2, 4)
|
|
|
|
"""
|
|
|
|
def __init__(self, fn):
|
|
FrameworkTestCase.__init__(self)
|
|
self.fn = fn
|
|
try:
|
|
self.name = fn.__module__.split(".", 1)[-1] + "." + fn.__name__
|
|
except AttributeError:
|
|
self.name = str(fn)
|
|
|
|
def runTest(self):
|
|
self.fn(self)
|
|
|
|
def id(self):
|
|
return self.name
|
|
|
|
def shortDescription(self):
|
|
return None
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
def __repr__(self):
|
|
return "<SimpleTestCase: %s>" % self.name
|
|
|
|
|
|
class ParameterisedTestCase(FrameworkTestCase):
|
|
"""Parameterised testcase.
|
|
|
|
Subclasses should define:
|
|
test_name -- short string
|
|
parameter_names -- list of identifiers
|
|
runTest
|
|
|
|
"""
|
|
def __init__(self, code, *parameters):
|
|
FrameworkTestCase.__init__(self)
|
|
self.code = code
|
|
self.name = "%s.%s:%s" % (self.__class__.__module__.split(".", 1)[-1],
|
|
self.test_name, code)
|
|
for name, value in zip(self.parameter_names, parameters):
|
|
setattr(self, name, value)
|
|
|
|
def runTest(self):
|
|
raise NotImplementedError
|
|
|
|
def id(self):
|
|
return self.name
|
|
|
|
def shortDescription(self):
|
|
return None
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
def __repr__(self):
|
|
return "<%s: %s>" % (self.__class__.__name__, self.name)
|
|
|
|
|
|
|
|
def _function_sort_key(fn):
|
|
try:
|
|
return fn.__code__.co_firstlineno
|
|
except AttributeError:
|
|
return str(fn)
|
|
|
|
def make_simple_tests(source, prefix="test_", testcase_class=SimpleTestCase):
|
|
"""Make test cases from a module's test_xxx functions.
|
|
|
|
source -- dict (usually a module's globals()).
|
|
prefix -- string (default "test_")
|
|
testcase_class -- SimpleTestCase subclass to use
|
|
|
|
Returns a list of TestCase objects.
|
|
|
|
This makes a TestCase for each function in the values of 'source' whose
|
|
name begins with 'prefix'.
|
|
|
|
The list is in the order of function definition (using the line number
|
|
attribute).
|
|
|
|
"""
|
|
functions = [value for name, value in source.iteritems()
|
|
if name.startswith(prefix) and callable(value)]
|
|
functions.sort(key=_function_sort_key)
|
|
return [testcase_class(fn) for fn in functions]
|
|
|
|
|
|
class Fixture(object):
|
|
"""A testing fixture.
|
|
|
|
Instantiate fixture objects with a TestCase parameter.
|
|
|
|
The fixture arranges for any necessary cleanup to be performed by calling
|
|
TestCase.addCleanUp.
|
|
|
|
"""
|