Ticket #12991: unittest2-addition.diff
File unittest2-addition.diff, 124.8 KB (added by , 14 years ago) |
---|
-
django/test/simple.py
1 1 import sys 2 2 import signal 3 import unittest4 3 5 4 from django.conf import settings 6 5 from django.db.models import get_app, get_apps 7 6 from django.test import _doctest as doctest 8 7 from django.test.utils import setup_test_environment, teardown_test_environment 9 8 from django.test.testcases import OutputChecker, DocTestRunner, TestCase 9 from django.utils import unittest 10 10 11 11 # The module name for tests outside models.py 12 12 TEST_MODULE = 'tests' -
django/test/testcases.py
1 1 import re 2 import unittest3 2 from urlparse import urlsplit, urlunsplit 4 3 from xml.dom.minidom import parseString, Node 5 4 … … 11 10 from django.http import QueryDict 12 11 from django.test import _doctest as doctest 13 12 from django.test.client import Client 14 from django.utils import simplejson 13 from django.utils import simplejson, unittest 15 14 from django.utils.encoding import smart_str 16 15 17 16 try: -
django/test/__init__.py
4 4 5 5 from django.test.client import Client 6 6 from django.test.testcases import TestCase, TransactionTestCase 7 from django.test.utils import skipIfDBEngine -
django/test/utils.py
2 2 from django.conf import settings 3 3 from django.core import mail 4 4 from django.core.mail.backends import locmem 5 from django.db import DEFAULT_DB_ALIAS 5 6 from django.test import signals 6 7 from django.template import Template 7 8 from django.utils.translation import deactivate 9 from django.utils.unittest import skipIf 8 10 9 11 class ContextList(list): 10 12 """A wrapper that provides direct key access to context items contained … … 77 79 test_module = __import__(test_module_name, {}, {}, test_path[-1]) 78 80 test_runner = getattr(test_module, test_path[-1]) 79 81 return test_runner 82 83 def skipIfDBEngine(engine, reason=None): 84 """ 85 Decorator to skip tests on a given database engine. 86 87 Note that you can pass a single engine or an iterable here 88 """ 89 if not reason: 90 reason = "not supported on this database" 91 settings_engine = settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] 92 if isinstance(engine, basestring): 93 return skipIf(settings_engine == engine, reason) 94 return skipIf(settings_engine in engine, reason) -
django/utils/unittest/compatibility.py
1 import os 2 import sys 3 4 try: 5 from functools import wraps 6 except ImportError: 7 # only needed for Python 2.4 8 def wraps(_): 9 def _wraps(func): 10 return func 11 return _wraps 12 13 __unittest = True 14 15 def _relpath_nt(path, start=os.path.curdir): 16 """Return a relative version of a path""" 17 18 if not path: 19 raise ValueError("no path specified") 20 start_list = os.path.abspath(start).split(os.path.sep) 21 path_list = os.path.abspath(path).split(os.path.sep) 22 if start_list[0].lower() != path_list[0].lower(): 23 unc_path, rest = os.path.splitunc(path) 24 unc_start, rest = os.path.splitunc(start) 25 if bool(unc_path) ^ bool(unc_start): 26 raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)" 27 % (path, start)) 28 else: 29 raise ValueError("path is on drive %s, start on drive %s" 30 % (path_list[0], start_list[0])) 31 # Work out how much of the filepath is shared by start and path. 32 for i in range(min(len(start_list), len(path_list))): 33 if start_list[i].lower() != path_list[i].lower(): 34 break 35 else: 36 i += 1 37 38 rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] 39 if not rel_list: 40 return os.path.curdir 41 return os.path.join(*rel_list) 42 43 # default to posixpath definition 44 def _relpath_posix(path, start=os.path.curdir): 45 """Return a relative version of a path""" 46 47 if not path: 48 raise ValueError("no path specified") 49 50 start_list = os.path.abspath(start).split(os.path.sep) 51 path_list = os.path.abspath(path).split(os.path.sep) 52 53 # Work out how much of the filepath is shared by start and path. 54 i = len(os.path.commonprefix([start_list, path_list])) 55 56 rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] 57 if not rel_list: 58 return os.path.curdir 59 return os.path.join(*rel_list) 60 61 if os.path is sys.modules.get('ntpath'): 62 relpath = _relpath_nt 63 else: 64 relpath = _relpath_posix -
django/utils/unittest/runner.py
1 """Running tests""" 2 3 import sys 4 import time 5 import unittest 6 7 from django.utils.unittest import result 8 9 try: 10 from django.utils.unittest.signals import registerResult 11 except ImportError: 12 def registerResult(_): 13 pass 14 15 __unittest = True 16 17 18 class _WritelnDecorator(object): 19 """Used to decorate file-like objects with a handy 'writeln' method""" 20 def __init__(self,stream): 21 self.stream = stream 22 23 def __getattr__(self, attr): 24 if attr in ('stream', '__getstate__'): 25 raise AttributeError(attr) 26 return getattr(self.stream,attr) 27 28 def writeln(self, arg=None): 29 if arg: 30 self.write(arg) 31 self.write('\n') # text-mode streams translate to \r\n if needed 32 33 34 class TextTestResult(result.TestResult): 35 """A test result class that can print formatted text results to a stream. 36 37 Used by TextTestRunner. 38 """ 39 separator1 = '=' * 70 40 separator2 = '-' * 70 41 42 def __init__(self, stream, descriptions, verbosity): 43 super(TextTestResult, self).__init__() 44 self.stream = stream 45 self.showAll = verbosity > 1 46 self.dots = verbosity == 1 47 self.descriptions = descriptions 48 49 def getDescription(self, test): 50 doc_first_line = test.shortDescription() 51 if self.descriptions and doc_first_line: 52 return '\n'.join((str(test), doc_first_line)) 53 else: 54 return str(test) 55 56 def startTest(self, test): 57 super(TextTestResult, self).startTest(test) 58 if self.showAll: 59 self.stream.write(self.getDescription(test)) 60 self.stream.write(" ... ") 61 self.stream.flush() 62 63 def addSuccess(self, test): 64 super(TextTestResult, self).addSuccess(test) 65 if self.showAll: 66 self.stream.writeln("ok") 67 elif self.dots: 68 self.stream.write('.') 69 self.stream.flush() 70 71 def addError(self, test, err): 72 super(TextTestResult, self).addError(test, err) 73 if self.showAll: 74 self.stream.writeln("ERROR") 75 elif self.dots: 76 self.stream.write('E') 77 self.stream.flush() 78 79 def addFailure(self, test, err): 80 super(TextTestResult, self).addFailure(test, err) 81 if self.showAll: 82 self.stream.writeln("FAIL") 83 elif self.dots: 84 self.stream.write('F') 85 self.stream.flush() 86 87 def addSkip(self, test, reason): 88 super(TextTestResult, self).addSkip(test, reason) 89 if self.showAll: 90 self.stream.writeln("skipped %r" % (reason,)) 91 elif self.dots: 92 self.stream.write("s") 93 self.stream.flush() 94 95 def addExpectedFailure(self, test, err): 96 super(TextTestResult, self).addExpectedFailure(test, err) 97 if self.showAll: 98 self.stream.writeln("expected failure") 99 elif self.dots: 100 self.stream.write("x") 101 self.stream.flush() 102 103 def addUnexpectedSuccess(self, test): 104 super(TextTestResult, self).addUnexpectedSuccess(test) 105 if self.showAll: 106 self.stream.writeln("unexpected success") 107 elif self.dots: 108 self.stream.write("u") 109 self.stream.flush() 110 111 def printErrors(self): 112 if self.dots or self.showAll: 113 self.stream.writeln() 114 self.printErrorList('ERROR', self.errors) 115 self.printErrorList('FAIL', self.failures) 116 117 def printErrorList(self, flavour, errors): 118 for test, err in errors: 119 self.stream.writeln(self.separator1) 120 self.stream.writeln("%s: %s" % (flavour, self.getDescription(test))) 121 self.stream.writeln(self.separator2) 122 self.stream.writeln("%s" % err) 123 124 def stopTestRun(self): 125 super(TextTestResult, self).stopTestRun() 126 self.printErrors() 127 128 129 class TextTestRunner(unittest.TextTestRunner): 130 """A test runner class that displays results in textual form. 131 132 It prints out the names of tests as they are run, errors as they 133 occur, and a summary of the results at the end of the test run. 134 """ 135 resultclass = TextTestResult 136 137 def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, 138 failfast=False, buffer=False, resultclass=None): 139 self.stream = _WritelnDecorator(stream) 140 self.descriptions = descriptions 141 self.verbosity = verbosity 142 self.failfast = failfast 143 self.buffer = buffer 144 if resultclass is not None: 145 self.resultclass = resultclass 146 147 def _makeResult(self): 148 return self.resultclass(self.stream, self.descriptions, self.verbosity) 149 150 def run(self, test): 151 "Run the given test case or test suite." 152 result = self._makeResult() 153 result.failfast = self.failfast 154 result.buffer = self.buffer 155 registerResult(result) 156 157 startTime = time.time() 158 startTestRun = getattr(result, 'startTestRun', None) 159 if startTestRun is not None: 160 startTestRun() 161 try: 162 test(result) 163 finally: 164 stopTestRun = getattr(result, 'stopTestRun', None) 165 if stopTestRun is not None: 166 stopTestRun() 167 else: 168 result.printErrors() 169 stopTime = time.time() 170 timeTaken = stopTime - startTime 171 if hasattr(result, 'separator2'): 172 self.stream.writeln(result.separator2) 173 run = result.testsRun 174 self.stream.writeln("Ran %d test%s in %.3fs" % 175 (run, run != 1 and "s" or "", timeTaken)) 176 self.stream.writeln() 177 178 expectedFails = unexpectedSuccesses = skipped = 0 179 try: 180 results = map(len, (result.expectedFailures, 181 result.unexpectedSuccesses, 182 result.skipped)) 183 expectedFails, unexpectedSuccesses, skipped = results 184 except AttributeError: 185 pass 186 infos = [] 187 if not result.wasSuccessful(): 188 self.stream.write("FAILED") 189 failed, errored = map(len, (result.failures, result.errors)) 190 if failed: 191 infos.append("failures=%d" % failed) 192 if errored: 193 infos.append("errors=%d" % errored) 194 else: 195 self.stream.write("OK") 196 if skipped: 197 infos.append("skipped=%d" % skipped) 198 if expectedFails: 199 infos.append("expected failures=%d" % expectedFails) 200 if unexpectedSuccesses: 201 infos.append("unexpected successes=%d" % unexpectedSuccesses) 202 if infos: 203 self.stream.writeln(" (%s)" % (", ".join(infos),)) 204 else: 205 self.stream.write("\n") 206 return result -
django/utils/unittest/suite.py
1 """TestSuite""" 2 3 import sys 4 import unittest 5 from django.utils.unittest import case, util 6 7 __unittest = True 8 9 10 class BaseTestSuite(unittest.TestSuite): 11 """A simple test suite that doesn't provide class or module shared fixtures. 12 """ 13 def __init__(self, tests=()): 14 self._tests = [] 15 self.addTests(tests) 16 17 def __repr__(self): 18 return "<%s tests=%s>" % (util.strclass(self.__class__), list(self)) 19 20 def __eq__(self, other): 21 if not isinstance(other, self.__class__): 22 return NotImplemented 23 return list(self) == list(other) 24 25 def __ne__(self, other): 26 return not self == other 27 28 # Can't guarantee hash invariant, so flag as unhashable 29 __hash__ = None 30 31 def __iter__(self): 32 return iter(self._tests) 33 34 def countTestCases(self): 35 cases = 0 36 for test in self: 37 cases += test.countTestCases() 38 return cases 39 40 def addTest(self, test): 41 # sanity checks 42 if not hasattr(test, '__call__'): 43 raise TypeError("%r is not callable" % (repr(test),)) 44 if isinstance(test, type) and issubclass(test, 45 (case.TestCase, TestSuite)): 46 raise TypeError("TestCases and TestSuites must be instantiated " 47 "before passing them to addTest()") 48 self._tests.append(test) 49 50 def addTests(self, tests): 51 if isinstance(tests, basestring): 52 raise TypeError("tests must be an iterable of tests, not a string") 53 for test in tests: 54 self.addTest(test) 55 56 def run(self, result): 57 for test in self: 58 if result.shouldStop: 59 break 60 test(result) 61 return result 62 63 def __call__(self, *args, **kwds): 64 return self.run(*args, **kwds) 65 66 def debug(self): 67 """Run the tests without collecting errors in a TestResult""" 68 for test in self: 69 test.debug() 70 71 72 class TestSuite(BaseTestSuite): 73 """A test suite is a composite test consisting of a number of TestCases. 74 75 For use, create an instance of TestSuite, then add test case instances. 76 When all tests have been added, the suite can be passed to a test 77 runner, such as TextTestRunner. It will run the individual test cases 78 in the order in which they were added, aggregating the results. When 79 subclassing, do not forget to call the base class constructor. 80 """ 81 82 83 def run(self, result): 84 self._wrapped_run(result) 85 self._tearDownPreviousClass(None, result) 86 self._handleModuleTearDown(result) 87 return result 88 89 def debug(self): 90 """Run the tests without collecting errors in a TestResult""" 91 debug = _DebugResult() 92 self._wrapped_run(debug, True) 93 self._tearDownPreviousClass(None, debug) 94 self._handleModuleTearDown(debug) 95 96 ################################ 97 # private methods 98 def _wrapped_run(self, result, debug=False): 99 for test in self: 100 if result.shouldStop: 101 break 102 103 if _isnotsuite(test): 104 self._tearDownPreviousClass(test, result) 105 self._handleModuleFixture(test, result) 106 self._handleClassSetUp(test, result) 107 result._previousTestClass = test.__class__ 108 109 if (getattr(test.__class__, '_classSetupFailed', False) or 110 getattr(result, '_moduleSetUpFailed', False)): 111 continue 112 113 if hasattr(test, '_wrapped_run'): 114 test._wrapped_run(result, debug) 115 elif not debug: 116 test(result) 117 else: 118 test.debug() 119 120 def _handleClassSetUp(self, test, result): 121 previousClass = getattr(result, '_previousTestClass', None) 122 currentClass = test.__class__ 123 if currentClass == previousClass: 124 return 125 if result._moduleSetUpFailed: 126 return 127 if getattr(currentClass, "__unittest_skip__", False): 128 return 129 130 try: 131 currentClass._classSetupFailed = False 132 except TypeError: 133 # test may actually be a function 134 # so its class will be a builtin-type 135 pass 136 137 setUpClass = getattr(currentClass, 'setUpClass', None) 138 if setUpClass is not None: 139 try: 140 setUpClass() 141 except Exception, e: 142 if isinstance(result, _DebugResult): 143 raise 144 currentClass._classSetupFailed = True 145 className = util.strclass(currentClass) 146 errorName = 'setUpClass (%s)' % className 147 self._addClassOrModuleLevelException(result, e, errorName) 148 149 def _get_previous_module(self, result): 150 previousModule = None 151 previousClass = getattr(result, '_previousTestClass', None) 152 if previousClass is not None: 153 previousModule = previousClass.__module__ 154 return previousModule 155 156 157 def _handleModuleFixture(self, test, result): 158 previousModule = self._get_previous_module(result) 159 currentModule = test.__class__.__module__ 160 if currentModule == previousModule: 161 return 162 163 self._handleModuleTearDown(result) 164 165 166 result._moduleSetUpFailed = False 167 try: 168 module = sys.modules[currentModule] 169 except KeyError: 170 return 171 setUpModule = getattr(module, 'setUpModule', None) 172 if setUpModule is not None: 173 try: 174 setUpModule() 175 except Exception, e: 176 if isinstance(result, _DebugResult): 177 raise 178 result._moduleSetUpFailed = True 179 errorName = 'setUpModule (%s)' % currentModule 180 self._addClassOrModuleLevelException(result, e, errorName) 181 182 def _addClassOrModuleLevelException(self, result, exception, errorName): 183 error = _ErrorHolder(errorName) 184 addSkip = getattr(result, 'addSkip', None) 185 if addSkip is not None and isinstance(exception, case.SkipTest): 186 addSkip(error, str(exception)) 187 else: 188 result.addError(error, sys.exc_info()) 189 190 def _handleModuleTearDown(self, result): 191 previousModule = self._get_previous_module(result) 192 if previousModule is None: 193 return 194 if result._moduleSetUpFailed: 195 return 196 197 try: 198 module = sys.modules[previousModule] 199 except KeyError: 200 return 201 202 tearDownModule = getattr(module, 'tearDownModule', None) 203 if tearDownModule is not None: 204 try: 205 tearDownModule() 206 except Exception, e: 207 if isinstance(result, _DebugResult): 208 raise 209 errorName = 'tearDownModule (%s)' % previousModule 210 self._addClassOrModuleLevelException(result, e, errorName) 211 212 def _tearDownPreviousClass(self, test, result): 213 previousClass = getattr(result, '_previousTestClass', None) 214 currentClass = test.__class__ 215 if currentClass == previousClass: 216 return 217 if getattr(previousClass, '_classSetupFailed', False): 218 return 219 if getattr(result, '_moduleSetUpFailed', False): 220 return 221 if getattr(previousClass, "__unittest_skip__", False): 222 return 223 224 tearDownClass = getattr(previousClass, 'tearDownClass', None) 225 if tearDownClass is not None: 226 try: 227 tearDownClass() 228 except Exception, e: 229 if isinstance(result, _DebugResult): 230 raise 231 className = util.strclass(previousClass) 232 errorName = 'tearDownClass (%s)' % className 233 self._addClassOrModuleLevelException(result, e, errorName) 234 235 236 class _ErrorHolder(object): 237 """ 238 Placeholder for a TestCase inside a result. As far as a TestResult 239 is concerned, this looks exactly like a unit test. Used to insert 240 arbitrary errors into a test suite run. 241 """ 242 # Inspired by the ErrorHolder from Twisted: 243 # http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py 244 245 # attribute used by TestResult._exc_info_to_string 246 failureException = None 247 248 def __init__(self, description): 249 self.description = description 250 251 def id(self): 252 return self.description 253 254 def shortDescription(self): 255 return None 256 257 def __repr__(self): 258 return "<ErrorHolder description=%r>" % (self.description,) 259 260 def __str__(self): 261 return self.id() 262 263 def run(self, result): 264 # could call result.addError(...) - but this test-like object 265 # shouldn't be run anyway 266 pass 267 268 def __call__(self, result): 269 return self.run(result) 270 271 def countTestCases(self): 272 return 0 273 274 def _isnotsuite(test): 275 "A crude way to tell apart testcases and suites with duck-typing" 276 try: 277 iter(test) 278 except TypeError: 279 return True 280 return False 281 282 283 class _DebugResult(object): 284 "Used by the TestSuite to hold previous class when running in debug." 285 _previousTestClass = None 286 _moduleSetUpFailed = False 287 shouldStop = False -
django/utils/unittest/case.py
1 """Test case implementation""" 2 3 import sys 4 import difflib 5 import pprint 6 import re 7 import unittest 8 import warnings 9 10 if sys.version_info[:2] == (2,3): 11 from sets import Set as set 12 from sets import ImmutableSet as frozenset 13 14 from django.utils.unittest import result 15 from django.utils.unittest.util import\ 16 safe_repr, safe_str, strclass,\ 17 unorderable_list_difference 18 19 from django.utils.unittest.compatibility import wraps 20 21 __unittest = True 22 23 24 DIFF_OMITTED = ('\nDiff is %s characters long. ' 25 'Set self.maxDiff to None to see it.') 26 27 class SkipTest(Exception): 28 """ 29 Raise this exception in a test to skip it. 30 31 Usually you can use TestResult.skip() or one of the skipping decorators 32 instead of raising this directly. 33 """ 34 35 class _ExpectedFailure(Exception): 36 """ 37 Raise this when a test is expected to fail. 38 39 This is an implementation detail. 40 """ 41 42 def __init__(self, exc_info): 43 # can't use super because Python 2.4 exceptions are old style 44 Exception.__init__(self) 45 self.exc_info = exc_info 46 47 class _UnexpectedSuccess(Exception): 48 """ 49 The test was supposed to fail, but it didn't! 50 """ 51 52 def _id(obj): 53 return obj 54 55 def skip(reason): 56 """ 57 Unconditionally skip a test. 58 """ 59 def decorator(test_item): 60 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)): 61 def skip_wrapper(*args, **kwargs): 62 raise SkipTest(reason) 63 skip_wrapper = wraps(test_item)(skip_wrapper) 64 test_item = skip_wrapper 65 66 test_item.__unittest_skip__ = True 67 test_item.__unittest_skip_why__ = reason 68 return test_item 69 return decorator 70 71 def skipIf(condition, reason): 72 """ 73 Skip a test if the condition is true. 74 """ 75 if condition: 76 return skip(reason) 77 return _id 78 79 def skipUnless(condition, reason): 80 """ 81 Skip a test unless the condition is true. 82 """ 83 if not condition: 84 return skip(reason) 85 return _id 86 87 88 def expectedFailure(func): 89 def wrapper(*args, **kwargs): 90 try: 91 func(*args, **kwargs) 92 except Exception: 93 raise _ExpectedFailure(sys.exc_info()) 94 raise _UnexpectedSuccess 95 wrapper = wraps(func)(wrapper) 96 return wrapper 97 98 99 class _AssertRaisesContext(object): 100 """A context manager used to implement TestCase.assertRaises* methods.""" 101 102 def __init__(self, expected, test_case, expected_regexp=None): 103 self.expected = expected 104 self.failureException = test_case.failureException 105 self.expected_regexp = expected_regexp 106 107 def __enter__(self): 108 return self 109 110 def __exit__(self, exc_type, exc_value, tb): 111 if exc_type is None: 112 try: 113 exc_name = self.expected.__name__ 114 except AttributeError: 115 exc_name = str(self.expected) 116 raise self.failureException( 117 "%s not raised" % (exc_name,)) 118 if not issubclass(exc_type, self.expected): 119 # let unexpected exceptions pass through 120 return False 121 self.exception = exc_value # store for later retrieval 122 if self.expected_regexp is None: 123 return True 124 125 expected_regexp = self.expected_regexp 126 if isinstance(expected_regexp, basestring): 127 expected_regexp = re.compile(expected_regexp) 128 if not expected_regexp.search(str(exc_value)): 129 raise self.failureException('"%s" does not match "%s"' % 130 (expected_regexp.pattern, str(exc_value))) 131 return True 132 133 134 class _TypeEqualityDict(object): 135 136 def __init__(self, testcase): 137 self.testcase = testcase 138 self._store = {} 139 140 def __setitem__(self, key, value): 141 self._store[key] = value 142 143 def __getitem__(self, key): 144 value = self._store[key] 145 if isinstance(value, basestring): 146 return getattr(self.testcase, value) 147 return value 148 149 def get(self, key, default=None): 150 if key in self._store: 151 return self[key] 152 return default 153 154 155 class TestCase(unittest.TestCase): 156 """A class whose instances are single test cases. 157 158 By default, the test code itself should be placed in a method named 159 'runTest'. 160 161 If the fixture may be used for many test cases, create as 162 many test methods as are needed. When instantiating such a TestCase 163 subclass, specify in the constructor arguments the name of the test method 164 that the instance is to execute. 165 166 Test authors should subclass TestCase for their own tests. Construction 167 and deconstruction of the test's environment ('fixture') can be 168 implemented by overriding the 'setUp' and 'tearDown' methods respectively. 169 170 If it is necessary to override the __init__ method, the base class 171 __init__ method must always be called. It is important that subclasses 172 should not change the signature of their __init__ method, since instances 173 of the classes are instantiated automatically by parts of the framework 174 in order to be run. 175 """ 176 177 # This attribute determines which exception will be raised when 178 # the instance's assertion methods fail; test methods raising this 179 # exception will be deemed to have 'failed' rather than 'errored' 180 181 failureException = AssertionError 182 183 # This attribute sets the maximum length of a diff in failure messages 184 # by assert methods using difflib. It is looked up as an instance attribute 185 # so can be configured by individual tests if required. 186 187 maxDiff = 80*8 188 189 # This attribute determines whether long messages (including repr of 190 # objects used in assert methods) will be printed on failure in *addition* 191 # to any explicit message passed. 192 193 longMessage = True 194 195 # Attribute used by TestSuite for classSetUp 196 197 _classSetupFailed = False 198 199 def __init__(self, methodName='runTest'): 200 """Create an instance of the class that will use the named test 201 method when executed. Raises a ValueError if the instance does 202 not have a method with the specified name. 203 """ 204 self._testMethodName = methodName 205 self._resultForDoCleanups = None 206 try: 207 testMethod = getattr(self, methodName) 208 except AttributeError: 209 raise ValueError("no such test method in %s: %s" % \ 210 (self.__class__, methodName)) 211 self._testMethodDoc = testMethod.__doc__ 212 self._cleanups = [] 213 214 # Map types to custom assertEqual functions that will compare 215 # instances of said type in more detail to generate a more useful 216 # error message. 217 self._type_equality_funcs = _TypeEqualityDict(self) 218 self.addTypeEqualityFunc(dict, 'assertDictEqual') 219 self.addTypeEqualityFunc(list, 'assertListEqual') 220 self.addTypeEqualityFunc(tuple, 'assertTupleEqual') 221 self.addTypeEqualityFunc(set, 'assertSetEqual') 222 self.addTypeEqualityFunc(frozenset, 'assertSetEqual') 223 self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual') 224 225 def addTypeEqualityFunc(self, typeobj, function): 226 """Add a type specific assertEqual style function to compare a type. 227 228 This method is for use by TestCase subclasses that need to register 229 their own type equality functions to provide nicer error messages. 230 231 Args: 232 typeobj: The data type to call this function on when both values 233 are of the same type in assertEqual(). 234 function: The callable taking two arguments and an optional 235 msg= argument that raises self.failureException with a 236 useful error message when the two arguments are not equal. 237 """ 238 self._type_equality_funcs[typeobj] = function 239 240 def addCleanup(self, function, *args, **kwargs): 241 """Add a function, with arguments, to be called when the test is 242 completed. Functions added are called on a LIFO basis and are 243 called after tearDown on test failure or success. 244 245 Cleanup items are called even if setUp fails (unlike tearDown).""" 246 self._cleanups.append((function, args, kwargs)) 247 248 def setUp(self): 249 "Hook method for setting up the test fixture before exercising it." 250 251 def setUpClass(cls): 252 "Hook method for setting up class fixture before running tests in the class." 253 setUpClass = classmethod(setUpClass) 254 255 def tearDownClass(cls): 256 "Hook method for deconstructing the class fixture after running all tests in the class." 257 tearDownClass = classmethod(tearDownClass) 258 259 def tearDown(self): 260 "Hook method for deconstructing the test fixture after testing it." 261 262 def countTestCases(self): 263 return 1 264 265 def defaultTestResult(self): 266 return result.TestResult() 267 268 def shortDescription(self): 269 """Returns a one-line description of the test, or None if no 270 description has been provided. 271 272 The default implementation of this method returns the first line of 273 the specified test method's docstring. 274 """ 275 doc = self._testMethodDoc 276 return doc and doc.split("\n")[0].strip() or None 277 278 279 def id(self): 280 return "%s.%s" % (strclass(self.__class__), self._testMethodName) 281 282 def __eq__(self, other): 283 if type(self) is not type(other): 284 return NotImplemented 285 286 return self._testMethodName == other._testMethodName 287 288 def __ne__(self, other): 289 return not self == other 290 291 def __hash__(self): 292 return hash((type(self), self._testMethodName)) 293 294 def __str__(self): 295 return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) 296 297 def __repr__(self): 298 return "<%s testMethod=%s>" % \ 299 (strclass(self.__class__), self._testMethodName) 300 301 def _addSkip(self, result, reason): 302 addSkip = getattr(result, 'addSkip', None) 303 if addSkip is not None: 304 addSkip(self, reason) 305 else: 306 warnings.warn("Use of a TestResult without an addSkip method is deprecated", 307 DeprecationWarning, 2) 308 result.addSuccess(self) 309 310 def run(self, result=None): 311 orig_result = result 312 if result is None: 313 result = self.defaultTestResult() 314 startTestRun = getattr(result, 'startTestRun', None) 315 if startTestRun is not None: 316 startTestRun() 317 318 self._resultForDoCleanups = result 319 result.startTest(self) 320 321 testMethod = getattr(self, self._testMethodName) 322 323 if (getattr(self.__class__, "__unittest_skip__", False) or 324 getattr(testMethod, "__unittest_skip__", False)): 325 # If the class or method was skipped. 326 try: 327 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 328 or getattr(testMethod, '__unittest_skip_why__', '')) 329 self._addSkip(result, skip_why) 330 finally: 331 result.stopTest(self) 332 return 333 try: 334 success = False 335 try: 336 self.setUp() 337 except SkipTest, e: 338 self._addSkip(result, str(e)) 339 except Exception: 340 result.addError(self, sys.exc_info()) 341 else: 342 try: 343 testMethod() 344 except self.failureException: 345 result.addFailure(self, sys.exc_info()) 346 except _ExpectedFailure, e: 347 addExpectedFailure = getattr(result, 'addExpectedFailure', None) 348 if addExpectedFailure is not None: 349 addExpectedFailure(self, e.exc_info) 350 else: 351 warnings.warn("Use of a TestResult without an addExpectedFailure method is deprecated", 352 DeprecationWarning) 353 result.addSuccess(self) 354 except _UnexpectedSuccess: 355 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None) 356 if addUnexpectedSuccess is not None: 357 addUnexpectedSuccess(self) 358 else: 359 warnings.warn("Use of a TestResult without an addUnexpectedSuccess method is deprecated", 360 DeprecationWarning) 361 result.addFailure(self, sys.exc_info()) 362 except SkipTest, e: 363 self._addSkip(result, str(e)) 364 except Exception: 365 result.addError(self, sys.exc_info()) 366 else: 367 success = True 368 369 try: 370 self.tearDown() 371 except Exception: 372 result.addError(self, sys.exc_info()) 373 success = False 374 375 cleanUpSuccess = self.doCleanups() 376 success = success and cleanUpSuccess 377 if success: 378 result.addSuccess(self) 379 finally: 380 result.stopTest(self) 381 if orig_result is None: 382 stopTestRun = getattr(result, 'stopTestRun', None) 383 if stopTestRun is not None: 384 stopTestRun() 385 386 def doCleanups(self): 387 """Execute all cleanup functions. Normally called for you after 388 tearDown.""" 389 result = self._resultForDoCleanups 390 ok = True 391 while self._cleanups: 392 function, args, kwargs = self._cleanups.pop(-1) 393 try: 394 function(*args, **kwargs) 395 except Exception: 396 ok = False 397 result.addError(self, sys.exc_info()) 398 return ok 399 400 def __call__(self, *args, **kwds): 401 return self.run(*args, **kwds) 402 403 def debug(self): 404 """Run the test without collecting errors in a TestResult""" 405 self.setUp() 406 getattr(self, self._testMethodName)() 407 self.tearDown() 408 while self._cleanups: 409 function, args, kwargs = self._cleanups.pop(-1) 410 function(*args, **kwargs) 411 412 def skipTest(self, reason): 413 """Skip this test.""" 414 raise SkipTest(reason) 415 416 def fail(self, msg=None): 417 """Fail immediately, with the given message.""" 418 raise self.failureException(msg) 419 420 def assertFalse(self, expr, msg=None): 421 "Fail the test if the expression is true." 422 if expr: 423 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr)) 424 raise self.failureException(msg) 425 426 def assertTrue(self, expr, msg=None): 427 """Fail the test unless the expression is true.""" 428 if not expr: 429 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr)) 430 raise self.failureException(msg) 431 432 def _formatMessage(self, msg, standardMsg): 433 """Honour the longMessage attribute when generating failure messages. 434 If longMessage is False this means: 435 * Use only an explicit message if it is provided 436 * Otherwise use the standard message for the assert 437 438 If longMessage is True: 439 * Use the standard message 440 * If an explicit message is provided, plus ' : ' and the explicit message 441 """ 442 if not self.longMessage: 443 return msg or standardMsg 444 if msg is None: 445 return standardMsg 446 try: 447 return '%s : %s' % (standardMsg, msg) 448 except UnicodeDecodeError: 449 return '%s : %s' % (safe_str(standardMsg), safe_str(msg)) 450 451 452 def assertRaises(self, excClass, callableObj=None, *args, **kwargs): 453 """Fail unless an exception of class excClass is thrown 454 by callableObj when invoked with arguments args and keyword 455 arguments kwargs. If a different type of exception is 456 thrown, it will not be caught, and the test case will be 457 deemed to have suffered an error, exactly as for an 458 unexpected exception. 459 460 If called with callableObj omitted or None, will return a 461 context object used like this:: 462 463 with self.assertRaises(SomeException): 464 do_something() 465 466 The context manager keeps a reference to the exception as 467 the 'exception' attribute. This allows you to inspect the 468 exception after the assertion:: 469 470 with self.assertRaises(SomeException) as cm: 471 do_something() 472 the_exception = cm.exception 473 self.assertEqual(the_exception.error_code, 3) 474 """ 475 if callableObj is None: 476 return _AssertRaisesContext(excClass, self) 477 try: 478 callableObj(*args, **kwargs) 479 except excClass: 480 return 481 482 if hasattr(excClass,'__name__'): 483 excName = excClass.__name__ 484 else: 485 excName = str(excClass) 486 raise self.failureException, "%s not raised" % excName 487 488 def _getAssertEqualityFunc(self, first, second): 489 """Get a detailed comparison function for the types of the two args. 490 491 Returns: A callable accepting (first, second, msg=None) that will 492 raise a failure exception if first != second with a useful human 493 readable error message for those types. 494 """ 495 # 496 # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) 497 # and vice versa. I opted for the conservative approach in case 498 # subclasses are not intended to be compared in detail to their super 499 # class instances using a type equality func. This means testing 500 # subtypes won't automagically use the detailed comparison. Callers 501 # should use their type specific assertSpamEqual method to compare 502 # subclasses if the detailed comparison is desired and appropriate. 503 # See the discussion in http://bugs.python.org/issue2578. 504 # 505 if type(first) is type(second): 506 asserter = self._type_equality_funcs.get(type(first)) 507 if asserter is not None: 508 return asserter 509 510 return self._baseAssertEqual 511 512 def _baseAssertEqual(self, first, second, msg=None): 513 """The default assertEqual implementation, not type specific.""" 514 if not first == second: 515 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second)) 516 msg = self._formatMessage(msg, standardMsg) 517 raise self.failureException(msg) 518 519 def assertEqual(self, first, second, msg=None): 520 """Fail if the two objects are unequal as determined by the '==' 521 operator. 522 """ 523 assertion_func = self._getAssertEqualityFunc(first, second) 524 assertion_func(first, second, msg=msg) 525 526 def assertNotEqual(self, first, second, msg=None): 527 """Fail if the two objects are equal as determined by the '==' 528 operator. 529 """ 530 if not first != second: 531 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), 532 safe_repr(second))) 533 raise self.failureException(msg) 534 535 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None): 536 """Fail if the two objects are unequal as determined by their 537 difference rounded to the given number of decimal places 538 (default 7) and comparing to zero, or by comparing that the 539 between the two objects is more than the given delta. 540 541 Note that decimal places (from zero) are usually not the same 542 as significant digits (measured from the most signficant digit). 543 544 If the two objects compare equal then they will automatically 545 compare almost equal. 546 """ 547 if first == second: 548 # shortcut 549 return 550 if delta is not None and places is not None: 551 raise TypeError("specify delta or places not both") 552 553 if delta is not None: 554 if abs(first - second) <= delta: 555 return 556 557 standardMsg = '%s != %s within %s delta' % (safe_repr(first), 558 safe_repr(second), 559 safe_repr(delta)) 560 else: 561 if places is None: 562 places = 7 563 564 if round(abs(second-first), places) == 0: 565 return 566 567 standardMsg = '%s != %s within %r places' % (safe_repr(first), 568 safe_repr(second), 569 places) 570 msg = self._formatMessage(msg, standardMsg) 571 raise self.failureException(msg) 572 573 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None): 574 """Fail if the two objects are equal as determined by their 575 difference rounded to the given number of decimal places 576 (default 7) and comparing to zero, or by comparing that the 577 between the two objects is less than the given delta. 578 579 Note that decimal places (from zero) are usually not the same 580 as significant digits (measured from the most signficant digit). 581 582 Objects that are equal automatically fail. 583 """ 584 if delta is not None and places is not None: 585 raise TypeError("specify delta or places not both") 586 if delta is not None: 587 if not (first == second) and abs(first - second) > delta: 588 return 589 standardMsg = '%s == %s within %s delta' % (safe_repr(first), 590 safe_repr(second), 591 safe_repr(delta)) 592 else: 593 if places is None: 594 places = 7 595 if not (first == second) and round(abs(second-first), places) != 0: 596 return 597 standardMsg = '%s == %s within %r places' % (safe_repr(first), 598 safe_repr(second), 599 places) 600 601 msg = self._formatMessage(msg, standardMsg) 602 raise self.failureException(msg) 603 604 # Synonyms for assertion methods 605 606 # The plurals are undocumented. Keep them that way to discourage use. 607 # Do not add more. Do not remove. 608 # Going through a deprecation cycle on these would annoy many people. 609 assertEquals = assertEqual 610 assertNotEquals = assertNotEqual 611 assertAlmostEquals = assertAlmostEqual 612 assertNotAlmostEquals = assertNotAlmostEqual 613 assert_ = assertTrue 614 615 # These fail* assertion method names are pending deprecation and will 616 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578 617 def _deprecate(original_func): 618 def deprecated_func(*args, **kwargs): 619 warnings.warn( 620 ('Please use %s instead.' % original_func.__name__), 621 PendingDeprecationWarning, 2) 622 return original_func(*args, **kwargs) 623 return deprecated_func 624 625 failUnlessEqual = _deprecate(assertEqual) 626 failIfEqual = _deprecate(assertNotEqual) 627 failUnlessAlmostEqual = _deprecate(assertAlmostEqual) 628 failIfAlmostEqual = _deprecate(assertNotAlmostEqual) 629 failUnless = _deprecate(assertTrue) 630 failUnlessRaises = _deprecate(assertRaises) 631 failIf = _deprecate(assertFalse) 632 633 def assertSequenceEqual(self, seq1, seq2, 634 msg=None, seq_type=None, max_diff=80*8): 635 """An equality assertion for ordered sequences (like lists and tuples). 636 637 For the purposes of this function, a valid ordered sequence type is one 638 which can be indexed, has a length, and has an equality operator. 639 640 Args: 641 seq1: The first sequence to compare. 642 seq2: The second sequence to compare. 643 seq_type: The expected datatype of the sequences, or None if no 644 datatype should be enforced. 645 msg: Optional message to use on failure instead of a list of 646 differences. 647 max_diff: Maximum size off the diff, larger diffs are not shown 648 """ 649 if seq_type is not None: 650 seq_type_name = seq_type.__name__ 651 if not isinstance(seq1, seq_type): 652 raise self.failureException('First sequence is not a %s: %s' 653 % (seq_type_name, safe_repr(seq1))) 654 if not isinstance(seq2, seq_type): 655 raise self.failureException('Second sequence is not a %s: %s' 656 % (seq_type_name, safe_repr(seq2))) 657 else: 658 seq_type_name = "sequence" 659 660 differing = None 661 try: 662 len1 = len(seq1) 663 except (TypeError, NotImplementedError): 664 differing = 'First %s has no length. Non-sequence?' % ( 665 seq_type_name) 666 667 if differing is None: 668 try: 669 len2 = len(seq2) 670 except (TypeError, NotImplementedError): 671 differing = 'Second %s has no length. Non-sequence?' % ( 672 seq_type_name) 673 674 if differing is None: 675 if seq1 == seq2: 676 return 677 678 seq1_repr = repr(seq1) 679 seq2_repr = repr(seq2) 680 if len(seq1_repr) > 30: 681 seq1_repr = seq1_repr[:30] + '...' 682 if len(seq2_repr) > 30: 683 seq2_repr = seq2_repr[:30] + '...' 684 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr) 685 differing = '%ss differ: %s != %s\n' % elements 686 687 for i in xrange(min(len1, len2)): 688 try: 689 item1 = seq1[i] 690 except (TypeError, IndexError, NotImplementedError): 691 differing += ('\nUnable to index element %d of first %s\n' % 692 (i, seq_type_name)) 693 break 694 695 try: 696 item2 = seq2[i] 697 except (TypeError, IndexError, NotImplementedError): 698 differing += ('\nUnable to index element %d of second %s\n' % 699 (i, seq_type_name)) 700 break 701 702 if item1 != item2: 703 differing += ('\nFirst differing element %d:\n%s\n%s\n' % 704 (i, item1, item2)) 705 break 706 else: 707 if (len1 == len2 and seq_type is None and 708 type(seq1) != type(seq2)): 709 # The sequences are the same, but have differing types. 710 return 711 712 if len1 > len2: 713 differing += ('\nFirst %s contains %d additional ' 714 'elements.\n' % (seq_type_name, len1 - len2)) 715 try: 716 differing += ('First extra element %d:\n%s\n' % 717 (len2, seq1[len2])) 718 except (TypeError, IndexError, NotImplementedError): 719 differing += ('Unable to index element %d ' 720 'of first %s\n' % (len2, seq_type_name)) 721 elif len1 < len2: 722 differing += ('\nSecond %s contains %d additional ' 723 'elements.\n' % (seq_type_name, len2 - len1)) 724 try: 725 differing += ('First extra element %d:\n%s\n' % 726 (len1, seq2[len1])) 727 except (TypeError, IndexError, NotImplementedError): 728 differing += ('Unable to index element %d ' 729 'of second %s\n' % (len1, seq_type_name)) 730 standardMsg = differing 731 diffMsg = '\n' + '\n'.join( 732 difflib.ndiff(pprint.pformat(seq1).splitlines(), 733 pprint.pformat(seq2).splitlines())) 734 735 standardMsg = self._truncateMessage(standardMsg, diffMsg) 736 msg = self._formatMessage(msg, standardMsg) 737 self.fail(msg) 738 739 def _truncateMessage(self, message, diff): 740 max_diff = self.maxDiff 741 if max_diff is None or len(diff) <= max_diff: 742 return message + diff 743 return message + (DIFF_OMITTED % len(diff)) 744 745 def assertListEqual(self, list1, list2, msg=None): 746 """A list-specific equality assertion. 747 748 Args: 749 list1: The first list to compare. 750 list2: The second list to compare. 751 msg: Optional message to use on failure instead of a list of 752 differences. 753 754 """ 755 self.assertSequenceEqual(list1, list2, msg, seq_type=list) 756 757 def assertTupleEqual(self, tuple1, tuple2, msg=None): 758 """A tuple-specific equality assertion. 759 760 Args: 761 tuple1: The first tuple to compare. 762 tuple2: The second tuple to compare. 763 msg: Optional message to use on failure instead of a list of 764 differences. 765 """ 766 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) 767 768 def assertSetEqual(self, set1, set2, msg=None): 769 """A set-specific equality assertion. 770 771 Args: 772 set1: The first set to compare. 773 set2: The second set to compare. 774 msg: Optional message to use on failure instead of a list of 775 differences. 776 777 assertSetEqual uses ducktyping to support 778 different types of sets, and is optimized for sets specifically 779 (parameters must support a difference method). 780 """ 781 try: 782 difference1 = set1.difference(set2) 783 except TypeError, e: 784 self.fail('invalid type when attempting set difference: %s' % e) 785 except AttributeError, e: 786 self.fail('first argument does not support set difference: %s' % e) 787 788 try: 789 difference2 = set2.difference(set1) 790 except TypeError, e: 791 self.fail('invalid type when attempting set difference: %s' % e) 792 except AttributeError, e: 793 self.fail('second argument does not support set difference: %s' % e) 794 795 if not (difference1 or difference2): 796 return 797 798 lines = [] 799 if difference1: 800 lines.append('Items in the first set but not the second:') 801 for item in difference1: 802 lines.append(repr(item)) 803 if difference2: 804 lines.append('Items in the second set but not the first:') 805 for item in difference2: 806 lines.append(repr(item)) 807 808 standardMsg = '\n'.join(lines) 809 self.fail(self._formatMessage(msg, standardMsg)) 810 811 def assertIn(self, member, container, msg=None): 812 """Just like self.assertTrue(a in b), but with a nicer default message.""" 813 if member not in container: 814 standardMsg = '%s not found in %s' % (safe_repr(member), 815 safe_repr(container)) 816 self.fail(self._formatMessage(msg, standardMsg)) 817 818 def assertNotIn(self, member, container, msg=None): 819 """Just like self.assertTrue(a not in b), but with a nicer default message.""" 820 if member in container: 821 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), 822 safe_repr(container)) 823 self.fail(self._formatMessage(msg, standardMsg)) 824 825 def assertIs(self, expr1, expr2, msg=None): 826 """Just like self.assertTrue(a is b), but with a nicer default message.""" 827 if expr1 is not expr2: 828 standardMsg = '%s is not %s' % (safe_repr(expr1), safe_repr(expr2)) 829 self.fail(self._formatMessage(msg, standardMsg)) 830 831 def assertIsNot(self, expr1, expr2, msg=None): 832 """Just like self.assertTrue(a is not b), but with a nicer default message.""" 833 if expr1 is expr2: 834 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) 835 self.fail(self._formatMessage(msg, standardMsg)) 836 837 def assertDictEqual(self, d1, d2, msg=None): 838 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') 839 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') 840 841 if d1 != d2: 842 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) 843 diff = ('\n' + '\n'.join(difflib.ndiff( 844 pprint.pformat(d1).splitlines(), 845 pprint.pformat(d2).splitlines()))) 846 standardMsg = self._truncateMessage(standardMsg, diff) 847 self.fail(self._formatMessage(msg, standardMsg)) 848 849 def assertDictContainsSubset(self, expected, actual, msg=None): 850 """Checks whether actual is a superset of expected.""" 851 missing = [] 852 mismatched = [] 853 for key, value in expected.iteritems(): 854 if key not in actual: 855 missing.append(key) 856 else: 857 try: 858 are_equal = (value == actual[key]) 859 except UnicodeDecodeError: 860 are_equal = False 861 if not are_equal: 862 mismatched.append('%s, expected: %s, actual: %s' % 863 (safe_repr(key), safe_repr(value), 864 safe_repr(actual[key]))) 865 866 if not (missing or mismatched): 867 return 868 869 standardMsg = '' 870 if missing: 871 standardMsg = 'Missing: %s' % ','.join([safe_repr(m) for m in 872 missing]) 873 if mismatched: 874 if standardMsg: 875 standardMsg += '; ' 876 standardMsg += 'Mismatched values: %s' % ','.join(mismatched) 877 878 self.fail(self._formatMessage(msg, standardMsg)) 879 880 def assertItemsEqual(self, expected_seq, actual_seq, msg=None): 881 """An unordered sequence specific comparison. It asserts that 882 expected_seq and actual_seq contain the same elements. It is 883 the equivalent of:: 884 885 self.assertEqual(sorted(expected_seq), sorted(actual_seq)) 886 887 Raises with an error message listing which elements of expected_seq 888 are missing from actual_seq and vice versa if any. 889 890 Asserts that each element has the same count in both sequences. 891 Example: 892 - [0, 1, 1] and [1, 0, 1] compare equal. 893 - [0, 0, 1] and [0, 1] compare unequal. 894 """ 895 try: 896 897 expected = expected_seq[:] 898 expected.sort() 899 actual = actual_seq[:] 900 actual.sort() 901 except (TypeError, AttributeError): 902 # Unsortable items (example: set(), complex(), ...) 903 expected = list(expected_seq) 904 actual = list(actual_seq) 905 missing, unexpected = unorderable_list_difference( 906 expected, actual, ignore_duplicate=False 907 ) 908 else: 909 return self.assertSequenceEqual(expected, actual, msg=msg) 910 911 errors = [] 912 if missing: 913 errors.append('Expected, but missing:\n %s' % 914 safe_repr(missing)) 915 if unexpected: 916 errors.append('Unexpected, but present:\n %s' % 917 safe_repr(unexpected)) 918 if errors: 919 standardMsg = '\n'.join(errors) 920 self.fail(self._formatMessage(msg, standardMsg)) 921 922 def assertMultiLineEqual(self, first, second, msg=None): 923 """Assert that two multi-line strings are equal.""" 924 self.assert_(isinstance(first, basestring), ( 925 'First argument is not a string')) 926 self.assert_(isinstance(second, basestring), ( 927 'Second argument is not a string')) 928 929 if first != second: 930 standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True)) 931 diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), 932 second.splitlines(True))) 933 standardMsg = self._truncateMessage(standardMsg, diff) 934 self.fail(self._formatMessage(msg, standardMsg)) 935 936 def assertLess(self, a, b, msg=None): 937 """Just like self.assertTrue(a < b), but with a nicer default message.""" 938 if not a < b: 939 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) 940 self.fail(self._formatMessage(msg, standardMsg)) 941 942 def assertLessEqual(self, a, b, msg=None): 943 """Just like self.assertTrue(a <= b), but with a nicer default message.""" 944 if not a <= b: 945 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b)) 946 self.fail(self._formatMessage(msg, standardMsg)) 947 948 def assertGreater(self, a, b, msg=None): 949 """Just like self.assertTrue(a > b), but with a nicer default message.""" 950 if not a > b: 951 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b)) 952 self.fail(self._formatMessage(msg, standardMsg)) 953 954 def assertGreaterEqual(self, a, b, msg=None): 955 """Just like self.assertTrue(a >= b), but with a nicer default message.""" 956 if not a >= b: 957 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b)) 958 self.fail(self._formatMessage(msg, standardMsg)) 959 960 def assertIsNone(self, obj, msg=None): 961 """Same as self.assertTrue(obj is None), with a nicer default message.""" 962 if obj is not None: 963 standardMsg = '%s is not None' % (safe_repr(obj),) 964 self.fail(self._formatMessage(msg, standardMsg)) 965 966 def assertIsNotNone(self, obj, msg=None): 967 """Included for symmetry with assertIsNone.""" 968 if obj is None: 969 standardMsg = 'unexpectedly None' 970 self.fail(self._formatMessage(msg, standardMsg)) 971 972 def assertIsInstance(self, obj, cls, msg=None): 973 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer 974 default message.""" 975 if not isinstance(obj, cls): 976 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) 977 self.fail(self._formatMessage(msg, standardMsg)) 978 979 def assertNotIsInstance(self, obj, cls, msg=None): 980 """Included for symmetry with assertIsInstance.""" 981 if isinstance(obj, cls): 982 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) 983 self.fail(self._formatMessage(msg, standardMsg)) 984 985 def assertRaisesRegexp(self, expected_exception, expected_regexp, 986 callable_obj=None, *args, **kwargs): 987 """Asserts that the message in a raised exception matches a regexp. 988 989 Args: 990 expected_exception: Exception class expected to be raised. 991 expected_regexp: Regexp (re pattern object or string) expected 992 to be found in error message. 993 callable_obj: Function to be called. 994 args: Extra args. 995 kwargs: Extra kwargs. 996 """ 997 if callable_obj is None: 998 return _AssertRaisesContext(expected_exception, self, expected_regexp) 999 try: 1000 callable_obj(*args, **kwargs) 1001 except expected_exception, exc_value: 1002 if isinstance(expected_regexp, basestring): 1003 expected_regexp = re.compile(expected_regexp) 1004 if not expected_regexp.search(str(exc_value)): 1005 raise self.failureException('"%s" does not match "%s"' % 1006 (expected_regexp.pattern, str(exc_value))) 1007 else: 1008 if hasattr(expected_exception, '__name__'): 1009 excName = expected_exception.__name__ 1010 else: 1011 excName = str(expected_exception) 1012 raise self.failureException, "%s not raised" % excName 1013 1014 1015 def assertRegexpMatches(self, text, expected_regexp, msg=None): 1016 """Fail the test unless the text matches the regular expression.""" 1017 if isinstance(expected_regexp, basestring): 1018 expected_regexp = re.compile(expected_regexp) 1019 if not expected_regexp.search(text): 1020 msg = msg or "Regexp didn't match" 1021 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text) 1022 raise self.failureException(msg) 1023 1024 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None): 1025 """Fail the test if the text matches the regular expression.""" 1026 if isinstance(unexpected_regexp, basestring): 1027 unexpected_regexp = re.compile(unexpected_regexp) 1028 match = unexpected_regexp.search(text) 1029 if match: 1030 msg = msg or "Regexp matched" 1031 msg = '%s: %r matches %r in %r' % (msg, 1032 text[match.start():match.end()], 1033 unexpected_regexp.pattern, 1034 text) 1035 raise self.failureException(msg) 1036 1037 class FunctionTestCase(TestCase): 1038 """A test case that wraps a test function. 1039 1040 This is useful for slipping pre-existing test functions into the 1041 unittest framework. Optionally, set-up and tidy-up functions can be 1042 supplied. As with TestCase, the tidy-up ('tearDown') function will 1043 always be called if the set-up ('setUp') function ran successfully. 1044 """ 1045 1046 def __init__(self, testFunc, setUp=None, tearDown=None, description=None): 1047 super(FunctionTestCase, self).__init__() 1048 self._setUpFunc = setUp 1049 self._tearDownFunc = tearDown 1050 self._testFunc = testFunc 1051 self._description = description 1052 1053 def setUp(self): 1054 if self._setUpFunc is not None: 1055 self._setUpFunc() 1056 1057 def tearDown(self): 1058 if self._tearDownFunc is not None: 1059 self._tearDownFunc() 1060 1061 def runTest(self): 1062 self._testFunc() 1063 1064 def id(self): 1065 return self._testFunc.__name__ 1066 1067 def __eq__(self, other): 1068 if not isinstance(other, self.__class__): 1069 return NotImplemented 1070 1071 return self._setUpFunc == other._setUpFunc and \ 1072 self._tearDownFunc == other._tearDownFunc and \ 1073 self._testFunc == other._testFunc and \ 1074 self._description == other._description 1075 1076 def __ne__(self, other): 1077 return not self == other 1078 1079 def __hash__(self): 1080 return hash((type(self), self._setUpFunc, self._tearDownFunc, 1081 self._testFunc, self._description)) 1082 1083 def __str__(self): 1084 return "%s (%s)" % (strclass(self.__class__), 1085 self._testFunc.__name__) 1086 1087 def __repr__(self): 1088 return "<%s testFunc=%s>" % (strclass(self.__class__), 1089 self._testFunc) 1090 1091 def shortDescription(self): 1092 if self._description is not None: 1093 return self._description 1094 doc = self._testFunc.__doc__ 1095 return doc and doc.split("\n")[0].strip() or None -
django/utils/unittest/util.py
1 """Various utility functions.""" 2 3 __unittest = True 4 5 6 _MAX_LENGTH = 80 7 def safe_repr(obj, short=False): 8 try: 9 result = repr(obj) 10 except Exception: 11 result = object.__repr__(obj) 12 if not short or len(result) < _MAX_LENGTH: 13 return result 14 return result[:_MAX_LENGTH] + ' [truncated]...' 15 16 def safe_str(obj): 17 try: 18 return str(obj) 19 except Exception: 20 return object.__str__(obj) 21 22 def strclass(cls): 23 return "%s.%s" % (cls.__module__, cls.__name__) 24 25 def sorted_list_difference(expected, actual): 26 """Finds elements in only one or the other of two, sorted input lists. 27 28 Returns a two-element tuple of lists. The first list contains those 29 elements in the "expected" list but not in the "actual" list, and the 30 second contains those elements in the "actual" list but not in the 31 "expected" list. Duplicate elements in either input list are ignored. 32 """ 33 i = j = 0 34 missing = [] 35 unexpected = [] 36 while True: 37 try: 38 e = expected[i] 39 a = actual[j] 40 if e < a: 41 missing.append(e) 42 i += 1 43 while expected[i] == e: 44 i += 1 45 elif e > a: 46 unexpected.append(a) 47 j += 1 48 while actual[j] == a: 49 j += 1 50 else: 51 i += 1 52 try: 53 while expected[i] == e: 54 i += 1 55 finally: 56 j += 1 57 while actual[j] == a: 58 j += 1 59 except IndexError: 60 missing.extend(expected[i:]) 61 unexpected.extend(actual[j:]) 62 break 63 return missing, unexpected 64 65 def unorderable_list_difference(expected, actual, ignore_duplicate=False): 66 """Same behavior as sorted_list_difference but 67 for lists of unorderable items (like dicts). 68 69 As it does a linear search per item (remove) it 70 has O(n*n) performance. 71 """ 72 missing = [] 73 unexpected = [] 74 while expected: 75 item = expected.pop() 76 try: 77 actual.remove(item) 78 except ValueError: 79 missing.append(item) 80 if ignore_duplicate: 81 for lst in expected, actual: 82 try: 83 while True: 84 lst.remove(item) 85 except ValueError: 86 pass 87 if ignore_duplicate: 88 while actual: 89 item = actual.pop() 90 unexpected.append(item) 91 try: 92 while True: 93 actual.remove(item) 94 except ValueError: 95 pass 96 return missing, unexpected 97 98 # anything left in actual is unexpected 99 return missing, actual -
django/utils/unittest/result.py
1 """Test result object""" 2 3 import sys 4 import traceback 5 import unittest 6 7 from StringIO import StringIO 8 9 from django.utils.unittest import util 10 from django.utils.unittest.compatibility import wraps 11 12 __unittest = True 13 14 def failfast(method): 15 def inner(self, *args, **kw): 16 if getattr(self, 'failfast', False): 17 self.stop() 18 return method(self, *args, **kw) 19 inner = wraps(method)(inner) 20 return inner 21 22 23 STDOUT_LINE = '\nStdout:\n%s' 24 STDERR_LINE = '\nStderr:\n%s' 25 26 class TestResult(unittest.TestResult): 27 """Holder for test result information. 28 29 Test results are automatically managed by the TestCase and TestSuite 30 classes, and do not need to be explicitly manipulated by writers of tests. 31 32 Each instance holds the total number of tests run, and collections of 33 failures and errors that occurred among those test runs. The collections 34 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the 35 formatted traceback of the error that occurred. 36 """ 37 _previousTestClass = None 38 _moduleSetUpFailed = False 39 40 def __init__(self): 41 self.failfast = False 42 self.failures = [] 43 self.errors = [] 44 self.testsRun = 0 45 self.skipped = [] 46 self.expectedFailures = [] 47 self.unexpectedSuccesses = [] 48 self.shouldStop = False 49 self.buffer = False 50 self._stdout_buffer = None 51 self._stderr_buffer = None 52 self._original_stdout = sys.stdout 53 self._original_stderr = sys.stderr 54 self._mirrorOutput = False 55 56 def startTest(self, test): 57 "Called when the given test is about to be run" 58 self.testsRun += 1 59 self._mirrorOutput = False 60 if self.buffer: 61 if self._stderr_buffer is None: 62 self._stderr_buffer = StringIO() 63 self._stdout_buffer = StringIO() 64 sys.stdout = self._stdout_buffer 65 sys.stderr = self._stderr_buffer 66 67 def startTestRun(self): 68 """Called once before any tests are executed. 69 70 See startTest for a method called before each test. 71 """ 72 73 def stopTest(self, test): 74 """Called when the given test has been run""" 75 if self.buffer: 76 if self._mirrorOutput: 77 output = sys.stdout.getvalue() 78 error = sys.stderr.getvalue() 79 if output: 80 if not output.endswith('\n'): 81 output += '\n' 82 self._original_stdout.write(STDOUT_LINE % output) 83 if error: 84 if not error.endswith('\n'): 85 error += '\n' 86 self._original_stderr.write(STDERR_LINE % error) 87 88 sys.stdout = self._original_stdout 89 sys.stderr = self._original_stderr 90 self._stdout_buffer.seek(0) 91 self._stdout_buffer.truncate() 92 self._stderr_buffer.seek(0) 93 self._stderr_buffer.truncate() 94 self._mirrorOutput = False 95 96 97 def stopTestRun(self): 98 """Called once after all tests are executed. 99 100 See stopTest for a method called after each test. 101 """ 102 103 104 def addError(self, test, err): 105 """Called when an error has occurred. 'err' is a tuple of values as 106 returned by sys.exc_info(). 107 """ 108 self.errors.append((test, self._exc_info_to_string(err, test))) 109 self._mirrorOutput = True 110 addError = failfast(addError) 111 112 def addFailure(self, test, err): 113 """Called when an error has occurred. 'err' is a tuple of values as 114 returned by sys.exc_info().""" 115 self.failures.append((test, self._exc_info_to_string(err, test))) 116 self._mirrorOutput = True 117 addFailure = failfast(addFailure) 118 119 def addSuccess(self, test): 120 "Called when a test has completed successfully" 121 pass 122 123 def addSkip(self, test, reason): 124 """Called when a test is skipped.""" 125 self.skipped.append((test, reason)) 126 127 def addExpectedFailure(self, test, err): 128 """Called when an expected failure/error occured.""" 129 self.expectedFailures.append( 130 (test, self._exc_info_to_string(err, test))) 131 132 def addUnexpectedSuccess(self, test): 133 """Called when a test was expected to fail, but succeed.""" 134 self.unexpectedSuccesses.append(test) 135 addUnexpectedSuccess = failfast(addUnexpectedSuccess) 136 137 def wasSuccessful(self): 138 "Tells whether or not this result was a success" 139 return (len(self.failures) + len(self.errors) == 0) 140 141 def stop(self): 142 "Indicates that the tests should be aborted" 143 self.shouldStop = True 144 145 def _exc_info_to_string(self, err, test): 146 """Converts a sys.exc_info()-style tuple of values into a string.""" 147 exctype, value, tb = err 148 # Skip test runner traceback levels 149 while tb and self._is_relevant_tb_level(tb): 150 tb = tb.tb_next 151 if exctype is test.failureException: 152 # Skip assert*() traceback levels 153 length = self._count_relevant_tb_levels(tb) 154 msgLines = traceback.format_exception(exctype, value, tb, length) 155 else: 156 msgLines = traceback.format_exception(exctype, value, tb) 157 158 if self.buffer: 159 output = sys.stdout.getvalue() 160 error = sys.stderr.getvalue() 161 if output: 162 if not output.endswith('\n'): 163 output += '\n' 164 msgLines.append(STDOUT_LINE % output) 165 if error: 166 if not error.endswith('\n'): 167 error += '\n' 168 msgLines.append(STDERR_LINE % error) 169 return ''.join(msgLines) 170 171 def _is_relevant_tb_level(self, tb): 172 return '__unittest' in tb.tb_frame.f_globals 173 174 def _count_relevant_tb_levels(self, tb): 175 length = 0 176 while tb and not self._is_relevant_tb_level(tb): 177 length += 1 178 tb = tb.tb_next 179 return length 180 181 def __repr__(self): 182 return "<%s run=%i errors=%i failures=%i>" % \ 183 (util.strclass(self.__class__), self.testsRun, len(self.errors), 184 len(self.failures)) -
django/utils/unittest/__init__.py
1 import sys 2 3 #Django hackery to load the appropriate version of unittest 4 5 if sys.version_info >= (2,7): 6 #unittest2 features are native in Python 2.7 7 from unittest import * 8 else: 9 try: 10 #check the system path first 11 from unittest2 import * 12 except ImportError: 13 #otherwise fall back to our bundled version 14 from unittest2_package_init import * -
django/utils/unittest/unittest2_package_init.py
1 """ 2 unittest2 3 4 unittest2 is a backport of the new features added to the unittest testing 5 framework in Python 2.7. It is tested to run on Python 2.4 - 2.6. 6 7 To use unittest2 instead of unittest simply replace ``import unittest`` with 8 ``import unittest2``. 9 10 11 Copyright (c) 1999-2003 Steve Purcell 12 Copyright (c) 2003-2010 Python Software Foundation 13 This module is free software, and you may redistribute it and/or modify 14 it under the same terms as Python itself, so long as this copyright message 15 and disclaimer are retained in their original form. 16 17 IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 18 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF 19 THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 20 DAMAGE. 21 22 THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, 25 AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 26 SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 27 """ 28 29 __all__ = ['TestResult', 'TestCase', 'TestSuite', 30 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 31 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 32 'expectedFailure', 'TextTestResult', '__version__', 'collector'] 33 34 __version__ = '0.5.0 alpha' 35 36 # Expose obsolete functions for backwards compatibility 37 __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) 38 39 40 from django.utils.unittest.collector import collector 41 from django.utils.unittest.result import TestResult 42 from django.utils.unittest.case import \ 43 TestCase, FunctionTestCase, SkipTest, skip, skipIf,\ 44 skipUnless, expectedFailure 45 46 from django.utils.unittest.suite import BaseTestSuite, TestSuite 47 from django.utils.unittest.loader import \ 48 TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,\ 49 findTestCases 50 51 from django.utils.unittest.main import TestProgram, main, main_ 52 from django.utils.unittest.runner import TextTestRunner, TextTestResult 53 54 try: 55 from django.utils.unittest.signals import\ 56 installHandler, registerResult, removeResult, removeHandler 57 except ImportError: 58 # Compatibility with platforms that don't have the signal module 59 pass 60 else: 61 __all__.extend(['installHandler', 'registerResult', 'removeResult', 62 'removeHandler']) 63 64 # deprecated 65 _TextTestResult = TextTestResult 66 67 __unittest = True -
django/utils/unittest/__main__.py
1 """Main entry point""" 2 3 import sys 4 if sys.argv[0].endswith("__main__.py"): 5 sys.argv[0] = "unittest2" 6 7 __unittest = True 8 9 from django.utils.unittest.main import main_ 10 main_() -
django/utils/unittest/signals.py
1 import signal 2 import weakref 3 4 from django.utils.unittest.compatibility import wraps 5 6 __unittest = True 7 8 9 class _InterruptHandler(object): 10 def __init__(self, default_handler): 11 self.called = False 12 self.default_handler = default_handler 13 14 def __call__(self, signum, frame): 15 installed_handler = signal.getsignal(signal.SIGINT) 16 if installed_handler is not self: 17 # if we aren't the installed handler, then delegate immediately 18 # to the default handler 19 self.default_handler(signum, frame) 20 21 if self.called: 22 self.default_handler(signum, frame) 23 self.called = True 24 for result in _results.keys(): 25 result.stop() 26 27 _results = weakref.WeakKeyDictionary() 28 def registerResult(result): 29 _results[result] = 1 30 31 def removeResult(result): 32 return bool(_results.pop(result, None)) 33 34 _interrupt_handler = None 35 def installHandler(): 36 global _interrupt_handler 37 if _interrupt_handler is None: 38 default_handler = signal.getsignal(signal.SIGINT) 39 _interrupt_handler = _InterruptHandler(default_handler) 40 signal.signal(signal.SIGINT, _interrupt_handler) 41 42 43 def removeHandler(method=None): 44 if method is not None: 45 def inner(*args, **kwargs): 46 initial = signal.getsignal(signal.SIGINT) 47 removeHandler() 48 try: 49 return method(*args, **kwargs) 50 finally: 51 signal.signal(signal.SIGINT, initial) 52 inner = wraps(method)(inner) 53 return inner 54 55 global _interrupt_handler 56 if _interrupt_handler is not None: 57 signal.signal(signal.SIGINT, _interrupt_handler.default_handler) -
django/utils/unittest/main.py
1 """Unittest main program""" 2 3 import sys 4 import os 5 import types 6 7 from django.utils.unittest import loader, runner 8 try: 9 from django.utils.unittest.signals import installHandler 10 except ImportError: 11 installHandler = None 12 13 __unittest = True 14 15 FAILFAST = " -f, --failfast Stop on first failure\n" 16 CATCHBREAK = " -c, --catch Catch control-C and display results\n" 17 BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n" 18 19 USAGE_AS_MAIN = """\ 20 Usage: %(progName)s [options] [tests] 21 22 Options: 23 -h, --help Show this message 24 -v, --verbose Verbose output 25 -q, --quiet Minimal output 26 %(failfast)s%(catchbreak)s%(buffer)s 27 Examples: 28 %(progName)s test_module - run tests from test_module 29 %(progName)s test_module.TestClass - run tests from 30 test_module.TestClass 31 %(progName)s test_module.TestClass.test_method - run specified test method 32 33 [tests] can be a list of any number of test modules, classes and test 34 methods. 35 36 Alternative Usage: %(progName)s discover [options] 37 38 Options: 39 -v, --verbose Verbose output 40 %(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default) 41 -p pattern Pattern to match test files ('test*.py' default) 42 -t directory Top level directory of project (default to 43 start directory) 44 45 For test discovery all test modules must be importable from the top 46 level directory of the project. 47 """ 48 49 USAGE_FROM_MODULE = """\ 50 Usage: %(progName)s [options] [test] [...] 51 52 Options: 53 -h, --help Show this message 54 -v, --verbose Verbose output 55 -q, --quiet Minimal output 56 %(failfast)s%(catchbreak)s%(buffer)s 57 Examples: 58 %(progName)s - run default set of tests 59 %(progName)s MyTestSuite - run suite 'MyTestSuite' 60 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething 61 %(progName)s MyTestCase - run all 'test*' test methods 62 in MyTestCase 63 """ 64 65 66 class TestProgram(object): 67 """A command-line program that runs a set of tests; this is primarily 68 for making test modules conveniently executable. 69 """ 70 USAGE = USAGE_FROM_MODULE 71 72 # defaults for testing 73 failfast = catchbreak = buffer = progName = None 74 75 def __init__(self, module='__main__', defaultTest=None, 76 argv=None, testRunner=None, 77 testLoader=loader.defaultTestLoader, exit=True, 78 verbosity=1, failfast=None, catchbreak=None, buffer=None): 79 if isinstance(module, basestring): 80 self.module = __import__(module) 81 for part in module.split('.')[1:]: 82 self.module = getattr(self.module, part) 83 else: 84 self.module = module 85 if argv is None: 86 argv = sys.argv 87 88 self.exit = exit 89 self.verbosity = verbosity 90 self.failfast = failfast 91 self.catchbreak = catchbreak 92 self.buffer = buffer 93 self.defaultTest = defaultTest 94 self.testRunner = testRunner 95 self.testLoader = testLoader 96 self.progName = os.path.basename(argv[0]) 97 self.parseArgs(argv) 98 self.runTests() 99 100 def usageExit(self, msg=None): 101 if msg: 102 print msg 103 usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '', 104 'buffer': ''} 105 if self.failfast != False: 106 usage['failfast'] = FAILFAST 107 if self.catchbreak != False and installHandler is not None: 108 usage['catchbreak'] = CATCHBREAK 109 if self.buffer != False: 110 usage['buffer'] = BUFFEROUTPUT 111 print self.USAGE % usage 112 sys.exit(2) 113 114 def parseArgs(self, argv): 115 if len(argv) > 1 and argv[1].lower() == 'discover': 116 self._do_discovery(argv[2:]) 117 return 118 119 import getopt 120 long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer'] 121 try: 122 options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts) 123 for opt, value in options: 124 if opt in ('-h','-H','--help'): 125 self.usageExit() 126 if opt in ('-q','--quiet'): 127 self.verbosity = 0 128 if opt in ('-v','--verbose'): 129 self.verbosity = 2 130 if opt in ('-f','--failfast'): 131 if self.failfast is None: 132 self.failfast = True 133 # Should this raise an exception if -f is not valid? 134 if opt in ('-c','--catch'): 135 if self.catchbreak is None and installHandler is not None: 136 self.catchbreak = True 137 # Should this raise an exception if -c is not valid? 138 if opt in ('-b','--buffer'): 139 if self.buffer is None: 140 self.buffer = True 141 # Should this raise an exception if -b is not valid? 142 if len(args) == 0 and self.defaultTest is None: 143 # createTests will load tests from self.module 144 self.testNames = None 145 elif len(args) > 0: 146 self.testNames = args 147 if __name__ == '__main__': 148 # to support python -m unittest ... 149 self.module = None 150 else: 151 self.testNames = (self.defaultTest,) 152 self.createTests() 153 except getopt.error, msg: 154 self.usageExit(msg) 155 156 def createTests(self): 157 if self.testNames is None: 158 self.test = self.testLoader.loadTestsFromModule(self.module) 159 else: 160 self.test = self.testLoader.loadTestsFromNames(self.testNames, 161 self.module) 162 163 def _do_discovery(self, argv, Loader=loader.TestLoader): 164 # handle command line args for test discovery 165 self.progName = '%s discover' % self.progName 166 import optparse 167 parser = optparse.OptionParser() 168 parser.prog = self.progName 169 parser.add_option('-v', '--verbose', dest='verbose', default=False, 170 help='Verbose output', action='store_true') 171 if self.failfast != False: 172 parser.add_option('-f', '--failfast', dest='failfast', default=False, 173 help='Stop on first fail or error', 174 action='store_true') 175 if self.catchbreak != False and installHandler is not None: 176 parser.add_option('-c', '--catch', dest='catchbreak', default=False, 177 help='Catch ctrl-C and display results so far', 178 action='store_true') 179 if self.buffer != False: 180 parser.add_option('-b', '--buffer', dest='buffer', default=False, 181 help='Buffer stdout and stderr during tests', 182 action='store_true') 183 parser.add_option('-s', '--start-directory', dest='start', default='.', 184 help="Directory to start discovery ('.' default)") 185 parser.add_option('-p', '--pattern', dest='pattern', default='test*.py', 186 help="Pattern to match tests ('test*.py' default)") 187 parser.add_option('-t', '--top-level-directory', dest='top', default=None, 188 help='Top level directory of project (defaults to start directory)') 189 190 options, args = parser.parse_args(argv) 191 if len(args) > 3: 192 self.usageExit() 193 194 for name, value in zip(('start', 'pattern', 'top'), args): 195 setattr(options, name, value) 196 197 # only set options from the parsing here 198 # if they weren't set explicitly in the constructor 199 if self.failfast is None: 200 self.failfast = options.failfast 201 if self.catchbreak is None and installHandler is not None: 202 self.catchbreak = options.catchbreak 203 if self.buffer is None: 204 self.buffer = options.buffer 205 206 if options.verbose: 207 self.verbosity = 2 208 209 start_dir = options.start 210 pattern = options.pattern 211 top_level_dir = options.top 212 213 loader = Loader() 214 self.test = loader.discover(start_dir, pattern, top_level_dir) 215 216 def runTests(self): 217 if self.catchbreak: 218 installHandler() 219 if self.testRunner is None: 220 self.testRunner = runner.TextTestRunner 221 if isinstance(self.testRunner, (type, types.ClassType)): 222 try: 223 testRunner = self.testRunner(verbosity=self.verbosity, 224 failfast=self.failfast, 225 buffer=self.buffer) 226 except TypeError: 227 # didn't accept the verbosity, buffer or failfast arguments 228 testRunner = self.testRunner() 229 else: 230 # it is assumed to be a TestRunner instance 231 testRunner = self.testRunner 232 self.result = testRunner.run(self.test) 233 if self.exit: 234 sys.exit(not self.result.wasSuccessful()) 235 236 main = TestProgram 237 238 def main_(): 239 TestProgram.USAGE = USAGE_AS_MAIN 240 main(module=None) 241 -
django/utils/unittest/collector.py
1 import os 2 import sys 3 from django.utils.unittest.loader import defaultTestLoader 4 5 def collector(): 6 # import __main__ triggers code re-execution 7 __main__ = sys.modules['__main__'] 8 setupDir = os.path.abspath(os.path.dirname(__main__.__file__)) 9 return defaultTestLoader.discover(setupDir) -
django/utils/unittest/loader.py
1 """Loading unittests.""" 2 3 import os 4 import re 5 import sys 6 import traceback 7 import types 8 import unittest 9 10 from fnmatch import fnmatch 11 12 from django.utils.unittest import case, suite 13 14 try: 15 from os.path import relpath 16 except ImportError: 17 from django.utils.unittest.compatibility import relpath 18 19 __unittest = True 20 21 22 def _CmpToKey(mycmp): 23 'Convert a cmp= function into a key= function' 24 class K(object): 25 def __init__(self, obj): 26 self.obj = obj 27 def __lt__(self, other): 28 return mycmp(self.obj, other.obj) == -1 29 return K 30 31 32 # what about .pyc or .pyo (etc) 33 # we would need to avoid loading the same tests multiple times 34 # from '.py', '.pyc' *and* '.pyo' 35 VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE) 36 37 38 def _make_failed_import_test(name, suiteClass): 39 message = 'Failed to import test module: %s' % name 40 if hasattr(traceback, 'format_exc'): 41 # Python 2.3 compatibility 42 # format_exc returns two frames of discover.py as well 43 message += '\n%s' % traceback.format_exc() 44 return _make_failed_test('ModuleImportFailure', name, ImportError(message), 45 suiteClass) 46 47 def _make_failed_load_tests(name, exception, suiteClass): 48 return _make_failed_test('LoadTestsFailure', name, exception, suiteClass) 49 50 def _make_failed_test(classname, methodname, exception, suiteClass): 51 def testFailure(self): 52 raise exception 53 attrs = {methodname: testFailure} 54 TestClass = type(classname, (case.TestCase,), attrs) 55 return suiteClass((TestClass(methodname),)) 56 57 58 class TestLoader(unittest.TestLoader): 59 """ 60 This class is responsible for loading tests according to various criteria 61 and returning them wrapped in a TestSuite 62 """ 63 testMethodPrefix = 'test' 64 sortTestMethodsUsing = cmp 65 suiteClass = suite.TestSuite 66 _top_level_dir = None 67 68 def loadTestsFromTestCase(self, testCaseClass): 69 """Return a suite of all tests cases contained in testCaseClass""" 70 if issubclass(testCaseClass, suite.TestSuite): 71 raise TypeError("Test cases should not be derived from TestSuite." 72 " Maybe you meant to derive from TestCase?") 73 testCaseNames = self.getTestCaseNames(testCaseClass) 74 if not testCaseNames and hasattr(testCaseClass, 'runTest'): 75 testCaseNames = ['runTest'] 76 loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) 77 return loaded_suite 78 79 def loadTestsFromModule(self, module, use_load_tests=True): 80 """Return a suite of all tests cases contained in the given module""" 81 tests = [] 82 for name in dir(module): 83 obj = getattr(module, name) 84 if isinstance(obj, type) and issubclass(obj, unittest.TestCase): 85 tests.append(self.loadTestsFromTestCase(obj)) 86 87 load_tests = getattr(module, 'load_tests', None) 88 tests = self.suiteClass(tests) 89 if use_load_tests and load_tests is not None: 90 try: 91 return load_tests(self, tests, None) 92 except Exception, e: 93 return _make_failed_load_tests(module.__name__, e, 94 self.suiteClass) 95 return tests 96 97 def loadTestsFromName(self, name, module=None): 98 """Return a suite of all tests cases given a string specifier. 99 100 The name may resolve either to a module, a test case class, a 101 test method within a test case class, or a callable object which 102 returns a TestCase or TestSuite instance. 103 104 The method optionally resolves the names relative to a given module. 105 """ 106 parts = name.split('.') 107 if module is None: 108 parts_copy = parts[:] 109 while parts_copy: 110 try: 111 module = __import__('.'.join(parts_copy)) 112 break 113 except ImportError: 114 del parts_copy[-1] 115 if not parts_copy: 116 raise 117 parts = parts[1:] 118 obj = module 119 for part in parts: 120 parent, obj = obj, getattr(obj, part) 121 122 if isinstance(obj, types.ModuleType): 123 return self.loadTestsFromModule(obj) 124 elif isinstance(obj, type) and issubclass(obj, unittest.TestCase): 125 return self.loadTestsFromTestCase(obj) 126 elif (isinstance(obj, types.UnboundMethodType) and 127 isinstance(parent, type) and 128 issubclass(parent, case.TestCase)): 129 return self.suiteClass([parent(obj.__name__)]) 130 elif isinstance(obj, unittest.TestSuite): 131 return obj 132 elif hasattr(obj, '__call__'): 133 test = obj() 134 if isinstance(test, unittest.TestSuite): 135 return test 136 elif isinstance(test, unittest.TestCase): 137 return self.suiteClass([test]) 138 else: 139 raise TypeError("calling %s returned %s, not a test" % 140 (obj, test)) 141 else: 142 raise TypeError("don't know how to make test from: %s" % obj) 143 144 def loadTestsFromNames(self, names, module=None): 145 """Return a suite of all tests cases found using the given sequence 146 of string specifiers. See 'loadTestsFromName()'. 147 """ 148 suites = [self.loadTestsFromName(name, module) for name in names] 149 return self.suiteClass(suites) 150 151 def getTestCaseNames(self, testCaseClass): 152 """Return a sorted sequence of method names found within testCaseClass 153 """ 154 def isTestMethod(attrname, testCaseClass=testCaseClass, 155 prefix=self.testMethodPrefix): 156 return attrname.startswith(prefix) and \ 157 hasattr(getattr(testCaseClass, attrname), '__call__') 158 testFnNames = filter(isTestMethod, dir(testCaseClass)) 159 if self.sortTestMethodsUsing: 160 # testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing)) 161 testFnNames.sort(self.sortTestMethodsUsing) 162 return testFnNames 163 164 def discover(self, start_dir, pattern='test*.py', top_level_dir=None): 165 """Find and return all test modules from the specified start 166 directory, recursing into subdirectories to find them. Only test files 167 that match the pattern will be loaded. (Using shell style pattern 168 matching.) 169 170 All test modules must be importable from the top level of the project. 171 If the start directory is not the top level directory then the top 172 level directory must be specified separately. 173 174 If a test package name (directory with '__init__.py') matches the 175 pattern then the package will be checked for a 'load_tests' function. If 176 this exists then it will be called with loader, tests, pattern. 177 178 If load_tests exists then discovery does *not* recurse into the package, 179 load_tests is responsible for loading all tests in the package. 180 181 The pattern is deliberately not stored as a loader attribute so that 182 packages can continue discovery themselves. top_level_dir is stored so 183 load_tests does not need to pass this argument in to loader.discover(). 184 """ 185 set_implicit_top = False 186 if top_level_dir is None and self._top_level_dir is not None: 187 # make top_level_dir optional if called from load_tests in a package 188 top_level_dir = self._top_level_dir 189 elif top_level_dir is None: 190 set_implicit_top = True 191 top_level_dir = start_dir 192 193 top_level_dir = os.path.abspath(top_level_dir) 194 195 if not top_level_dir in sys.path: 196 # all test modules must be importable from the top level directory 197 # should we *unconditionally* put the start directory in first 198 # in sys.path to minimise likelihood of conflicts between installed 199 # modules and development versions? 200 sys.path.insert(0, top_level_dir) 201 self._top_level_dir = top_level_dir 202 203 is_not_importable = False 204 if os.path.isdir(os.path.abspath(start_dir)): 205 start_dir = os.path.abspath(start_dir) 206 if start_dir != top_level_dir: 207 is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py')) 208 else: 209 # support for discovery from dotted module names 210 try: 211 __import__(start_dir) 212 except ImportError: 213 is_not_importable = True 214 else: 215 the_module = sys.modules[start_dir] 216 top_part = start_dir.split('.')[0] 217 start_dir = os.path.abspath(os.path.dirname((the_module.__file__))) 218 if set_implicit_top: 219 self._top_level_dir = os.path.abspath(os.path.dirname(os.path.dirname(sys.modules[top_part].__file__))) 220 sys.path.remove(top_level_dir) 221 222 if is_not_importable: 223 raise ImportError('Start directory is not importable: %r' % start_dir) 224 225 tests = list(self._find_tests(start_dir, pattern)) 226 return self.suiteClass(tests) 227 228 def _get_name_from_path(self, path): 229 path = os.path.splitext(os.path.normpath(path))[0] 230 231 _relpath = relpath(path, self._top_level_dir) 232 assert not os.path.isabs(_relpath), "Path must be within the project" 233 assert not _relpath.startswith('..'), "Path must be within the project" 234 235 name = _relpath.replace(os.path.sep, '.') 236 return name 237 238 def _get_module_from_name(self, name): 239 __import__(name) 240 return sys.modules[name] 241 242 def _match_path(self, path, full_path, pattern): 243 # override this method to use alternative matching strategy 244 return fnmatch(path, pattern) 245 246 def _find_tests(self, start_dir, pattern): 247 """Used by discovery. Yields test suites it loads.""" 248 paths = os.listdir(start_dir) 249 250 for path in paths: 251 full_path = os.path.join(start_dir, path) 252 if os.path.isfile(full_path): 253 if not VALID_MODULE_NAME.match(path): 254 # valid Python identifiers only 255 continue 256 if not self._match_path(path, full_path, pattern): 257 continue 258 # if the test file matches, load it 259 name = self._get_name_from_path(full_path) 260 try: 261 module = self._get_module_from_name(name) 262 except: 263 yield _make_failed_import_test(name, self.suiteClass) 264 else: 265 mod_file = os.path.abspath(getattr(module, '__file__', full_path)) 266 realpath = os.path.splitext(mod_file)[0] 267 fullpath_noext = os.path.splitext(full_path)[0] 268 if realpath.lower() != fullpath_noext.lower(): 269 module_dir = os.path.dirname(realpath) 270 mod_name = os.path.splitext(os.path.basename(full_path))[0] 271 expected_dir = os.path.dirname(full_path) 272 msg = ("%r module incorrectly imported from %r. Expected %r. " 273 "Is this module globally installed?") 274 raise ImportError(msg % (mod_name, module_dir, expected_dir)) 275 yield self.loadTestsFromModule(module) 276 elif os.path.isdir(full_path): 277 if not os.path.isfile(os.path.join(full_path, '__init__.py')): 278 continue 279 280 load_tests = None 281 tests = None 282 if fnmatch(path, pattern): 283 # only check load_tests if the package directory itself matches the filter 284 name = self._get_name_from_path(full_path) 285 package = self._get_module_from_name(name) 286 load_tests = getattr(package, 'load_tests', None) 287 tests = self.loadTestsFromModule(package, use_load_tests=False) 288 289 if load_tests is None: 290 if tests is not None: 291 # tests loaded from package file 292 yield tests 293 # recurse into the package 294 for test in self._find_tests(full_path, pattern): 295 yield test 296 else: 297 try: 298 yield load_tests(self, tests, pattern) 299 except Exception, e: 300 yield _make_failed_load_tests(package.__name__, e, 301 self.suiteClass) 302 303 defaultTestLoader = TestLoader() 304 305 306 def _makeLoader(prefix, sortUsing, suiteClass=None): 307 loader = TestLoader() 308 loader.sortTestMethodsUsing = sortUsing 309 loader.testMethodPrefix = prefix 310 if suiteClass: 311 loader.suiteClass = suiteClass 312 return loader 313 314 def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp): 315 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass) 316 317 def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, 318 suiteClass=suite.TestSuite): 319 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass) 320 321 def findTestCases(module, prefix='test', sortUsing=cmp, 322 suiteClass=suite.TestSuite): 323 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module) -
tests/regressiontests/test_client_regress/models.py
34 34 try: 35 35 self.assertContains(response, 'text', status_code=999) 36 36 except AssertionError, e: 37 self.assert Equals(str(e), "Couldn't retrieve content: Response code was 200 (expected 999)")37 self.assertTrue("Couldn't retrieve content: Response code was 200 (expected 999)" in str(e)) 38 38 try: 39 39 self.assertContains(response, 'text', status_code=999, msg_prefix='abc') 40 40 except AssertionError, e: 41 self.assert Equals(str(e), "abc: Couldn't retrieve content: Response code was 200 (expected 999)")41 self.assertTrue("abc: Couldn't retrieve content: Response code was 200 (expected 999)" in str(e)) 42 42 43 43 try: 44 44 self.assertNotContains(response, 'text', status_code=999) 45 45 except AssertionError, e: 46 self.assert Equals(str(e), "Couldn't retrieve content: Response code was 200 (expected 999)")46 self.assertTrue("Couldn't retrieve content: Response code was 200 (expected 999)" in str(e)) 47 47 try: 48 48 self.assertNotContains(response, 'text', status_code=999, msg_prefix='abc') 49 49 except AssertionError, e: 50 self.assert Equals(str(e), "abc: Couldn't retrieve content: Response code was 200 (expected 999)")50 self.assertTrue("abc: Couldn't retrieve content: Response code was 200 (expected 999)" in str(e)) 51 51 52 52 try: 53 53 self.assertNotContains(response, 'once') 54 54 except AssertionError, e: 55 self.assert Equals(str(e), "Response should not contain 'once'")55 self.assertTrue("Response should not contain 'once'" in str(e)) 56 56 try: 57 57 self.assertNotContains(response, 'once', msg_prefix='abc') 58 58 except AssertionError, e: 59 self.assert Equals(str(e), "abc: Response should not contain 'once'")59 self.assertTrue("abc: Response should not contain 'once'" in str(e)) 60 60 61 61 try: 62 62 self.assertContains(response, 'never', 1) 63 63 except AssertionError, e: 64 self.assert Equals(str(e), "Found 0 instances of 'never' in response (expected 1)")64 self.assertTrue("Found 0 instances of 'never' in response (expected 1)" in str(e)) 65 65 try: 66 66 self.assertContains(response, 'never', 1, msg_prefix='abc') 67 67 except AssertionError, e: 68 self.assert Equals(str(e), "abc: Found 0 instances of 'never' in response (expected 1)")68 self.assertTrue("abc: Found 0 instances of 'never' in response (expected 1)" in str(e)) 69 69 70 70 try: 71 71 self.assertContains(response, 'once', 0) 72 72 except AssertionError, e: 73 self.assert Equals(str(e), "Found 1 instances of 'once' in response (expected 0)")73 self.assertTrue("Found 1 instances of 'once' in response (expected 0)" in str(e)) 74 74 try: 75 75 self.assertContains(response, 'once', 0, msg_prefix='abc') 76 76 except AssertionError, e: 77 self.assert Equals(str(e), "abc: Found 1 instances of 'once' in response (expected 0)")77 self.assertTrue("abc: Found 1 instances of 'once' in response (expected 0)" in str(e)) 78 78 79 79 try: 80 80 self.assertContains(response, 'once', 2) 81 81 except AssertionError, e: 82 self.assert Equals(str(e), "Found 1 instances of 'once' in response (expected 2)")82 self.assertTrue("Found 1 instances of 'once' in response (expected 2)" in str(e)) 83 83 try: 84 84 self.assertContains(response, 'once', 2, msg_prefix='abc') 85 85 except AssertionError, e: 86 self.assert Equals(str(e), "abc: Found 1 instances of 'once' in response (expected 2)")86 self.assertTrue("abc: Found 1 instances of 'once' in response (expected 2)" in str(e)) 87 87 88 88 try: 89 89 self.assertContains(response, 'twice', 1) 90 90 except AssertionError, e: 91 self.assert Equals(str(e), "Found 2 instances of 'twice' in response (expected 1)")91 self.assertTrue("Found 2 instances of 'twice' in response (expected 1)" in str(e)) 92 92 try: 93 93 self.assertContains(response, 'twice', 1, msg_prefix='abc') 94 94 except AssertionError, e: 95 self.assert Equals(str(e), "abc: Found 2 instances of 'twice' in response (expected 1)")95 self.assertTrue("abc: Found 2 instances of 'twice' in response (expected 1)" in str(e)) 96 96 97 97 try: 98 98 self.assertContains(response, 'thrice') 99 99 except AssertionError, e: 100 self.assert Equals(str(e), "Couldn't find 'thrice' in response")100 self.assertTrue("Couldn't find 'thrice' in response" in str(e)) 101 101 try: 102 102 self.assertContains(response, 'thrice', msg_prefix='abc') 103 103 except AssertionError, e: 104 self.assert Equals(str(e), "abc: Couldn't find 'thrice' in response")104 self.assertTrue("abc: Couldn't find 'thrice' in response" in str(e)) 105 105 106 106 try: 107 107 self.assertContains(response, 'thrice', 3) 108 108 except AssertionError, e: 109 self.assert Equals(str(e), "Found 0 instances of 'thrice' in response (expected 3)")109 self.assertTrue("Found 0 instances of 'thrice' in response (expected 3)" in str(e)) 110 110 try: 111 111 self.assertContains(response, 'thrice', 3, msg_prefix='abc') 112 112 except AssertionError, e: 113 self.assert Equals(str(e), "abc: Found 0 instances of 'thrice' in response (expected 3)")113 self.assertTrue("abc: Found 0 instances of 'thrice' in response (expected 3)" in str(e)) 114 114 115 115 def test_unicode_contains(self): 116 116 "Unicode characters can be found in template context" … … 140 140 try: 141 141 self.assertTemplateUsed(response, 'GET Template') 142 142 except AssertionError, e: 143 self.assert Equals(str(e), "No templates used to render the response")143 self.assertTrue("No templates used to render the response" in str(e)) 144 144 145 145 try: 146 146 self.assertTemplateUsed(response, 'GET Template', msg_prefix='abc') 147 147 except AssertionError, e: 148 self.assert Equals(str(e), "abc: No templates used to render the response")148 self.assertTrue("abc: No templates used to render the response" in str(e)) 149 149 150 150 def test_single_context(self): 151 151 "Template assertions work when there is a single context" … … 154 154 try: 155 155 self.assertTemplateNotUsed(response, 'Empty GET Template') 156 156 except AssertionError, e: 157 self.assert Equals(str(e), "Template 'Empty GET Template' was used unexpectedly in rendering the response")157 self.assertTrue("Template 'Empty GET Template' was used unexpectedly in rendering the response" in str(e)) 158 158 159 159 try: 160 160 self.assertTemplateNotUsed(response, 'Empty GET Template', msg_prefix='abc') 161 161 except AssertionError, e: 162 self.assert Equals(str(e), "abc: Template 'Empty GET Template' was used unexpectedly in rendering the response")162 self.assertTrue("abc: Template 'Empty GET Template' was used unexpectedly in rendering the response" in str(e)) 163 163 164 164 try: 165 165 self.assertTemplateUsed(response, 'Empty POST Template') 166 166 except AssertionError, e: 167 self.assert Equals(str(e), "Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template")167 self.assertTrue("Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template" in str(e)) 168 168 169 169 try: 170 170 self.assertTemplateUsed(response, 'Empty POST Template', msg_prefix='abc') 171 171 except AssertionError, e: 172 self.assert Equals(str(e), "abc: Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template")172 self.assertTrue("abc: Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template" in str(e)) 173 173 174 174 def test_multiple_context(self): 175 175 "Template assertions work when there are multiple contexts" … … 185 185 try: 186 186 self.assertTemplateNotUsed(response, "form_view.html") 187 187 except AssertionError, e: 188 self.assert Equals(str(e), "Template 'form_view.html' was used unexpectedly in rendering the response")188 self.assertTrue("Template 'form_view.html' was used unexpectedly in rendering the response" in str(e)) 189 189 190 190 try: 191 191 self.assertTemplateNotUsed(response, 'base.html') 192 192 except AssertionError, e: 193 self.assert Equals(str(e), "Template 'base.html' was used unexpectedly in rendering the response")193 self.assertTrue("Template 'base.html' was used unexpectedly in rendering the response" in str(e)) 194 194 195 195 try: 196 196 self.assertTemplateUsed(response, "Valid POST Template") 197 197 except AssertionError, e: 198 self.assert Equals(str(e), "Template 'Valid POST Template' was not a template used to render the response. Actual template(s) used: form_view.html, base.html")198 self.assertTrue("Template 'Valid POST Template' was not a template used to render the response. Actual template(s) used: form_view.html, base.html" in str(e)) 199 199 200 200 class AssertRedirectsTests(TestCase): 201 201 def test_redirect_page(self): … … 205 205 try: 206 206 self.assertRedirects(response, '/test_client/get_view/') 207 207 except AssertionError, e: 208 self.assert Equals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)")208 self.assertTrue("Response didn't redirect as expected: Response code was 301 (expected 302)" in str(e)) 209 209 210 210 try: 211 211 self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') 212 212 except AssertionError, e: 213 self.assert Equals(str(e), "abc: Response didn't redirect as expected: Response code was 301 (expected 302)")213 self.assertTrue("abc: Response didn't redirect as expected: Response code was 301 (expected 302)" in str(e)) 214 214 215 215 def test_lost_query(self): 216 216 "An assertion is raised if the redirect location doesn't preserve GET parameters" … … 218 218 try: 219 219 self.assertRedirects(response, '/test_client/get_view/') 220 220 except AssertionError, e: 221 self.assert Equals(str(e), "Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'")221 self.assertTrue("Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'" in str(e)) 222 222 223 223 try: 224 224 self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') 225 225 except AssertionError, e: 226 self.assert Equals(str(e), "abc: Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'")226 self.assertTrue("abc: Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'" in str(e)) 227 227 228 228 def test_incorrect_target(self): 229 229 "An assertion is raised if the response redirects to another target" … … 232 232 # Should redirect to get_view 233 233 self.assertRedirects(response, '/test_client/some_view/') 234 234 except AssertionError, e: 235 self.assert Equals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)")235 self.assertTrue("Response didn't redirect as expected: Response code was 301 (expected 302)" in str(e)) 236 236 237 237 def test_target_page(self): 238 238 "An assertion is raised if the response redirect target cannot be retrieved as expected" … … 241 241 # The redirect target responds with a 301 code, not 200 242 242 self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/') 243 243 except AssertionError, e: 244 self.assert Equals(str(e), "Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)")244 self.assertTrue("Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)" in str(e)) 245 245 246 246 try: 247 247 # The redirect target responds with a 301 code, not 200 248 248 self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/', msg_prefix='abc') 249 249 except AssertionError, e: 250 self.assert Equals(str(e), "abc: Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)")250 self.assertTrue("abc: Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)" in str(e)) 251 251 252 252 def test_redirect_chain(self): 253 253 "You can follow a redirect chain of multiple redirects" … … 338 338 try: 339 339 self.assertRedirects(response, '/test_client/get_view/') 340 340 except AssertionError, e: 341 self.assert Equals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)")341 self.assertTrue("Response didn't redirect as expected: Response code was 200 (expected 302)" in str(e)) 342 342 343 343 try: 344 344 self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') 345 345 except AssertionError, e: 346 self.assert Equals(str(e), "abc: Response didn't redirect as expected: Response code was 200 (expected 302)")346 self.assertTrue("abc: Response didn't redirect as expected: Response code was 200 (expected 302)" in str(e)) 347 347 348 348 def test_redirect_on_non_redirect_page(self): 349 349 "An assertion is raised if the original page couldn't be retrieved as expected" … … 352 352 try: 353 353 self.assertRedirects(response, '/test_client/get_view/') 354 354 except AssertionError, e: 355 self.assert Equals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)")355 self.assertTrue("Response didn't redirect as expected: Response code was 200 (expected 302)" in str(e)) 356 356 357 357 try: 358 358 self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc') 359 359 except AssertionError, e: 360 self.assert Equals(str(e), "abc: Response didn't redirect as expected: Response code was 200 (expected 302)")360 self.assertTrue("abc: Response didn't redirect as expected: Response code was 200 (expected 302)" in str(e)) 361 361 362 362 363 363 class AssertFormErrorTests(TestCase): … … 377 377 try: 378 378 self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.') 379 379 except AssertionError, e: 380 self.assert Equal(str(e), "The form 'wrong_form' was not used to render the response")380 self.assertTrue("The form 'wrong_form' was not used to render the response" in str(e)) 381 381 try: 382 382 self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.', msg_prefix='abc') 383 383 except AssertionError, e: 384 self.assert Equal(str(e), "abc: The form 'wrong_form' was not used to render the response")384 self.assertTrue("abc: The form 'wrong_form' was not used to render the response" in str(e)) 385 385 386 386 def test_unknown_field(self): 387 387 "An assertion is raised if the field name is unknown" … … 399 399 try: 400 400 self.assertFormError(response, 'form', 'some_field', 'Some error.') 401 401 except AssertionError, e: 402 self.assert Equal(str(e), "The form 'form' in context 0 does not contain the field 'some_field'")402 self.assertTrue("The form 'form' in context 0 does not contain the field 'some_field'" in str(e)) 403 403 try: 404 404 self.assertFormError(response, 'form', 'some_field', 'Some error.', msg_prefix='abc') 405 405 except AssertionError, e: 406 self.assert Equal(str(e), "abc: The form 'form' in context 0 does not contain the field 'some_field'")406 self.assertTrue("abc: The form 'form' in context 0 does not contain the field 'some_field'" in str(e)) 407 407 408 408 def test_noerror_field(self): 409 409 "An assertion is raised if the field doesn't have any errors" … … 421 421 try: 422 422 self.assertFormError(response, 'form', 'value', 'Some error.') 423 423 except AssertionError, e: 424 self.assert Equal(str(e), "The field 'value' on form 'form' in context 0 contains no errors")424 self.assertTrue("The field 'value' on form 'form' in context 0 contains no errors" in str(e)) 425 425 try: 426 426 self.assertFormError(response, 'form', 'value', 'Some error.', msg_prefix='abc') 427 427 except AssertionError, e: 428 self.assert Equal(str(e), "abc: The field 'value' on form 'form' in context 0 contains no errors")428 self.assertTrue("abc: The field 'value' on form 'form' in context 0 contains no errors" in str(e)) 429 429 430 430 def test_unknown_error(self): 431 431 "An assertion is raised if the field doesn't contain the provided error" … … 443 443 try: 444 444 self.assertFormError(response, 'form', 'email', 'Some error.') 445 445 except AssertionError, e: 446 self.assert Equal(str(e), "The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])")446 self.assertTrue("The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])" in str(e)) 447 447 try: 448 448 self.assertFormError(response, 'form', 'email', 'Some error.', msg_prefix='abc') 449 449 except AssertionError, e: 450 self.assert Equal(str(e), "abc: The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])")450 self.assertTrue("abc: The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])" in str(e)) 451 451 452 452 def test_unknown_nonfield_error(self): 453 453 """ … … 468 468 try: 469 469 self.assertFormError(response, 'form', None, 'Some error.') 470 470 except AssertionError, e: 471 self.assert Equal(str(e), "The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )")471 self.assertTrue("The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )" in str(e)) 472 472 try: 473 473 self.assertFormError(response, 'form', None, 'Some error.', msg_prefix='abc') 474 474 except AssertionError, e: 475 self.assert Equal(str(e), "abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )")475 self.assertTrue("abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )" in str(e)) 476 476 477 477 class LoginTests(TestCase): 478 478 fixtures = ['testdata']