~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

'bzr selftest' now shows a progress bar with the number of tests, and 
progress made. 'make check' shows tests in -v mode, to be more useful
for the PQM status window. (Robert Collins).

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
# along with this program; if not, write to the Free Software
14
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
15
 
16
 
"""Tests for the test framework
17
 
"""
 
16
"""Tests for the test framework."""
18
17
 
19
18
import os
20
19
import sys
22
21
import warnings
23
22
 
24
23
import bzrlib
 
24
from bzrlib.progress import _BaseProgressBar
25
25
from bzrlib.tests import (
26
26
                          _load_module_by_name,
27
27
                          ChrootedTestCase,
67
67
        self.failUnlessExists(filename)
68
68
 
69
69
 
70
 
class TestSkippedTest(TestCase):
71
 
    """Try running a test which is skipped, make sure it's reported properly."""
72
 
 
73
 
    def test_skipped_test(self):
74
 
        # must be hidden in here so it's not run as a real test
75
 
        def skipping_test():
76
 
            raise TestSkipped('test intentionally skipped')
77
 
        runner = TextTestRunner(stream=self._log_file)
78
 
        test = unittest.FunctionTestCase(skipping_test)
79
 
        result = runner.run(test)
80
 
        self.assertTrue(result.wasSuccessful())
81
 
 
82
 
 
83
70
class TestTransportProviderAdapter(TestCase):
84
71
    """A group of tests that test the transport implementation adaption core.
85
72
 
385
372
        self.assertEqual(url, t.clone('..').base)
386
373
 
387
374
 
 
375
class MockProgress(_BaseProgressBar):
 
376
    """Progress-bar standin that records calls.
 
377
 
 
378
    Useful for testing pb using code.
 
379
    """
 
380
 
 
381
    def __init__(self):
 
382
        _BaseProgressBar.__init__(self)
 
383
        self.calls = []
 
384
 
 
385
    def tick(self):
 
386
        self.calls.append(('tick',))
 
387
 
 
388
    def update(self, msg=None, current=None, total=None):
 
389
        self.calls.append(('update', msg, current, total))
 
390
 
 
391
    def clear(self):
 
392
        self.calls.append(('clear',))
 
393
 
 
394
 
 
395
class TestResult(TestCase):
 
396
 
 
397
    def test_progress_bar_style_quiet(self):
 
398
        # test using a progress bar.
 
399
        dummy_test = TestResult('test_progress_bar_style_quiet')
 
400
        dummy_error = (Exception, None, [])
 
401
        mypb = MockProgress()
 
402
        mypb.update('Running tests', 0, 4)
 
403
        last_calls = mypb.calls[:]
 
404
        result = bzrlib.tests._MyResult(self._log_file,
 
405
                                        descriptions=0,
 
406
                                        verbosity=1,
 
407
                                        pb=mypb)
 
408
        self.assertEqual(last_calls, mypb.calls)
 
409
 
 
410
        # an error 
 
411
        result.startTest(dummy_test)
 
412
        # starting a test prints the test name
 
413
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 0, None)], mypb.calls)
 
414
        last_calls = mypb.calls[:]
 
415
        result.addError(dummy_test, dummy_error)
 
416
        self.assertEqual(last_calls + [('update', 'ERROR        ', 1, None)], mypb.calls)
 
417
        last_calls = mypb.calls[:]
 
418
 
 
419
        # a failure
 
420
        result.startTest(dummy_test)
 
421
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 1, None)], mypb.calls)
 
422
        last_calls = mypb.calls[:]
 
423
        result.addFailure(dummy_test, dummy_error)
 
424
        self.assertEqual(last_calls + [('update', 'FAIL         ', 2, None)], mypb.calls)
 
425
        last_calls = mypb.calls[:]
 
426
 
 
427
        # a success
 
428
        result.startTest(dummy_test)
 
429
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 2, None)], mypb.calls)
 
430
        last_calls = mypb.calls[:]
 
431
        result.addSuccess(dummy_test)
 
432
        self.assertEqual(last_calls + [('update', 'OK           ', 3, None)], mypb.calls)
 
433
        last_calls = mypb.calls[:]
 
434
 
 
435
        # a skip
 
436
        result.startTest(dummy_test)
 
437
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 3, None)], mypb.calls)
 
438
        last_calls = mypb.calls[:]
 
439
        result.addSkipped(dummy_test, dummy_error)
 
440
        self.assertEqual(last_calls + [('update', 'SKIP         ', 4, None)], mypb.calls)
 
441
        last_calls = mypb.calls[:]
 
442
 
 
443
 
 
444
class TestRunner(TestCase):
 
445
 
 
446
    def dummy_test(self):
 
447
        pass
 
448
 
 
449
    def run_test_runner(self, testrunner, test):
 
450
        """Run suite in testrunner, saving global state and restoring it.
 
451
 
 
452
        This current saves and restores:
 
453
        TestCaseInTempDir.TEST_ROOT
 
454
        
 
455
        There should be no tests in this file that use bzrlib.tests.TextTestRunner
 
456
        without using this convenience method, because of our use of global state.
 
457
        """
 
458
        old_root = TestCaseInTempDir.TEST_ROOT
 
459
        try:
 
460
            TestCaseInTempDir.TEST_ROOT = None
 
461
            return testrunner.run(test)
 
462
        finally:
 
463
            TestCaseInTempDir.TEST_ROOT = old_root
 
464
 
 
465
    def test_accepts_and_uses_pb_parameter(self):
 
466
        test = TestRunner('dummy_test')
 
467
        mypb = MockProgress()
 
468
        self.assertEqual([], mypb.calls)
 
469
        runner = TextTestRunner(stream=self._log_file, pb=mypb)
 
470
        result = self.run_test_runner(runner, test)
 
471
        self.assertEqual(1, result.testsRun)
 
472
        self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
 
473
        self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
 
474
        self.assertEqual(('update', 'OK           ', 1, None), mypb.calls[2])
 
475
        self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
 
476
        self.assertEqual(('clear',), mypb.calls[4])
 
477
        self.assertEqual(5, len(mypb.calls))
 
478
 
 
479
    def test_skipped_test(self):
 
480
        # run a test that is skipped, and check the suite as a whole still
 
481
        # succeeds.
 
482
        # skipping_test must be hidden in here so it's not run as a real test
 
483
        def skipping_test():
 
484
            raise TestSkipped('test intentionally skipped')
 
485
        runner = TextTestRunner(stream=self._log_file, keep_output=True)
 
486
        test = unittest.FunctionTestCase(skipping_test)
 
487
        result = self.run_test_runner(runner, test)
 
488
        self.assertTrue(result.wasSuccessful())
 
489
 
 
490
 
 
491
class TestTestCase(TestCase):
 
492
    """Tests that test the core bzrlib TestCase."""
 
493
 
 
494
    def inner_test(self):
 
495
        # the inner child test
 
496
        note("inner_test")
 
497
 
 
498
    def outer_child(self):
 
499
        # the outer child test
 
500
        note("outer_start")
 
501
        self.inner_test = TestTestCase("inner_child")
 
502
        result = bzrlib.tests._MyResult(self._log_file,
 
503
                                        descriptions=0,
 
504
                                        verbosity=1)
 
505
        self.inner_test.run(result)
 
506
        note("outer finish")
 
507
 
 
508
    def test_trace_nesting(self):
 
509
        # this tests that each test case nests its trace facility correctly.
 
510
        # we do this by running a test case manually. That test case (A)
 
511
        # should setup a new log, log content to it, setup a child case (B),
 
512
        # which should log independently, then case (A) should log a trailer
 
513
        # and return.
 
514
        # we do two nested children so that we can verify the state of the 
 
515
        # logs after the outer child finishes is correct, which a bad clean
 
516
        # up routine in tearDown might trigger a fault in our test with only
 
517
        # one child, we should instead see the bad result inside our test with
 
518
        # the two children.
 
519
        # the outer child test
 
520
        original_trace = bzrlib.trace._trace_file
 
521
        outer_test = TestTestCase("outer_child")
 
522
        result = bzrlib.tests._MyResult(self._log_file,
 
523
                                        descriptions=0,
 
524
                                        verbosity=1)
 
525
        outer_test.run(result)
 
526
        self.assertEqual(original_trace, bzrlib.trace._trace_file)
 
527
        
 
528
 
388
529
class TestExtraAssertions(TestCase):
389
530
    """Tests for new test assertions in bzrlib test suite"""
390
531