37
39
from logging import debug, warning, error
43
class EarlyStoppingTestResultAdapter(object):
44
"""An adapter for TestResult to stop at the first first failure or error"""
46
def __init__(self, result):
49
def addError(self, test, err):
50
self._result.addError(test, err)
53
def addFailure(self, test, err):
54
self._result.addFailure(test, err)
57
def __getattr__(self, name):
58
return getattr(self._result, name)
60
def __setattr__(self, name, value):
62
object.__setattr__(self, name, value)
63
return setattr(self._result, name, value)
66
class _MyResult(unittest._TextTestResult):
70
No special behaviour for now.
73
def startTest(self, test):
74
unittest.TestResult.startTest(self, test)
75
# TODO: Maybe show test.shortDescription somewhere?
76
what = test.shortDescription() or test.id()
78
self.stream.write('%-70.70s' % what)
81
def addError(self, test, err):
82
super(_MyResult, self).addError(test, err)
85
def addFailure(self, test, err):
86
super(_MyResult, self).addFailure(test, err)
89
def addSuccess(self, test):
91
self.stream.writeln('OK')
93
self.stream.write('~')
95
unittest.TestResult.addSuccess(self, test)
97
def printErrorList(self, flavour, errors):
98
for test, err in errors:
99
self.stream.writeln(self.separator1)
100
self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
101
if hasattr(test, '_get_log'):
102
self.stream.writeln()
103
self.stream.writeln('log from this test:')
104
print >>self.stream, test._get_log()
105
self.stream.writeln(self.separator2)
106
self.stream.writeln("%s" % err)
109
class TextTestRunner(unittest.TextTestRunner):
111
def _makeResult(self):
112
result = _MyResult(self.stream, self.descriptions, self.verbosity)
113
return EarlyStoppingTestResultAdapter(result)
116
def iter_suite_tests(suite):
117
"""Return all tests in a suite, recursing through nested suites"""
118
for item in suite._tests:
119
if isinstance(item, unittest.TestCase):
121
elif isinstance(item, unittest.TestSuite):
122
for r in iter_suite_tests(item):
125
raise Exception('unknown object %r inside test suite %r'
129
class TestSkipped(Exception):
130
"""Indicates that a test was intentionally skipped, rather than failing."""
39
134
class CommandFailed(Exception):
298
def selftest(verbose=False, pattern=".*"):
299
return testsweet.run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
397
def filter_suite_by_re(suite, pattern):
398
result = TestUtil.TestSuite()
399
filter_re = re.compile(pattern)
400
for test in iter_suite_tests(suite):
401
if filter_re.match(test.id()):
406
def filter_suite_by_names(suite, wanted_names):
407
"""Return a new suite containing only selected tests.
409
Names are considered to match if any name is a substring of the
410
fully-qualified test id (i.e. the class ."""
412
for test in iter_suite_tests(suite):
414
for p in wanted_names:
415
if this_id.find(p) != -1:
420
def run_suite(suite, name='test', verbose=False, pattern=".*", testnames=None):
421
TestCaseInTempDir._TEST_NAME = name
426
runner = TextTestRunner(stream=sys.stdout,
430
suite = filter_suite_by_names(suite, testnames)
432
suite = filter_suite_by_re(suite, pattern)
433
result = runner.run(suite)
434
# This is still a little bogus,
435
# but only a little. Folk not using our testrunner will
436
# have to delete their temp directories themselves.
437
if result.wasSuccessful():
438
if TestCaseInTempDir.TEST_ROOT is not None:
439
shutil.rmtree(TestCaseInTempDir.TEST_ROOT)
441
print "Failed tests working directories are in '%s'\n" % TestCaseInTempDir.TEST_ROOT
442
return result.wasSuccessful()
445
def selftest(verbose=False, pattern=".*", testnames=None):
446
"""Run the whole test suite under the enhanced runner"""
447
return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern,
302
451
def test_suite():
303
from bzrlib.selftest.TestUtil import TestLoader, TestSuite
304
import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
305
import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
452
"""Build and return TestSuite for the whole program."""
453
import bzrlib.store, bzrlib.inventory, bzrlib.branch
454
import bzrlib.osutils, bzrlib.merge3, bzrlib.plugin
306
455
from doctest import DocTestSuite
308
457
global MODULES_TO_TEST, MODULES_TO_DOCTEST
310
459
testmod_names = \
311
460
['bzrlib.selftest.MetaTestLog',
312
'bzrlib.selftest.test_parent',
313
461
'bzrlib.selftest.testinv',
314
'bzrlib.selftest.testfetch',
462
'bzrlib.selftest.test_ancestry',
463
'bzrlib.selftest.test_commit',
464
'bzrlib.selftest.test_commit_merge',
315
465
'bzrlib.selftest.versioning',
316
'bzrlib.selftest.whitebox',
317
466
'bzrlib.selftest.testmerge3',
318
467
'bzrlib.selftest.testmerge',
319
468
'bzrlib.selftest.testhashcache',
320
469
'bzrlib.selftest.teststatus',
321
470
'bzrlib.selftest.testlog',
322
'bzrlib.selftest.blackbox',
323
471
'bzrlib.selftest.testrevisionnamespaces',
324
472
'bzrlib.selftest.testbranch',
325
'bzrlib.selftest.testremotebranch',
326
473
'bzrlib.selftest.testrevision',
327
474
'bzrlib.selftest.test_revision_info',
328
475
'bzrlib.selftest.test_merge_core',
329
476
'bzrlib.selftest.test_smart_add',
330
477
'bzrlib.selftest.test_bad_files',
331
478
'bzrlib.selftest.testdiff',
479
'bzrlib.selftest.test_parent',
332
480
'bzrlib.selftest.test_xml',
481
'bzrlib.selftest.test_weave',
482
'bzrlib.selftest.testfetch',
483
'bzrlib.selftest.whitebox',
334
484
'bzrlib.selftest.teststore',
485
'bzrlib.selftest.blackbox',
486
'bzrlib.selftest.testtransport',
335
487
'bzrlib.selftest.testgraph',
488
'bzrlib.selftest.testworkingtree',
489
'bzrlib.selftest.test_upgrade',
338
492
for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,