~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-08-28 07:52:00 UTC
  • mfrom: (2729.1.6 test-scenarios)
  • Revision ID: pqm@pqm.ubuntu.com-20070828075200-y6ww43ym8xt0fv21
(mbp) add TestNotApplicable and multiply_tests_from_modules

Show diffs side-by-side

added added

removed removed

Lines of Context:
107
107
 
108
108
MODULES_TO_TEST = []
109
109
MODULES_TO_DOCTEST = [
110
 
                      bzrlib.timestamp,
111
 
                      bzrlib.errors,
112
 
                      bzrlib.export,
113
 
                      bzrlib.inventory,
114
 
                      bzrlib.iterablefile,
115
 
                      bzrlib.lockdir,
116
 
                      bzrlib.merge3,
117
 
                      bzrlib.option,
118
 
                      bzrlib.store,
119
 
                      ]
 
110
        bzrlib.timestamp,
 
111
        bzrlib.errors,
 
112
        bzrlib.export,
 
113
        bzrlib.inventory,
 
114
        bzrlib.iterablefile,
 
115
        bzrlib.lockdir,
 
116
        bzrlib.merge3,
 
117
        bzrlib.option,
 
118
        bzrlib.store,
 
119
        # quoted to avoid module-loading circularity
 
120
        'bzrlib.tests',
 
121
        ]
120
122
 
121
123
 
122
124
def packages_to_test():
204
206
        self.failure_count = 0
205
207
        self.known_failure_count = 0
206
208
        self.skip_count = 0
 
209
        self.not_applicable_count = 0
207
210
        self.unsupported = {}
208
211
        self.count = 0
209
212
        self._overall_start_time = time.time()
327
330
        self.report_unsupported(test, feature)
328
331
 
329
332
    def _addSkipped(self, test, skip_excinfo):
330
 
        self.report_skip(test, skip_excinfo)
331
 
        # seems best to treat this as success from point-of-view of
332
 
        # unittest -- it actually does nothing so it barely matters :)
 
333
        if isinstance(skip_excinfo[1], TestNotApplicable):
 
334
            self.not_applicable_count += 1
 
335
            self.report_not_applicable(test, skip_excinfo)
 
336
        else:
 
337
            self.skip_count += 1
 
338
            self.report_skip(test, skip_excinfo)
333
339
        try:
334
340
            test.tearDown()
335
341
        except KeyboardInterrupt:
337
343
        except:
338
344
            self.addError(test, test.__exc_info())
339
345
        else:
 
346
            # seems best to treat this as success from point-of-view of unittest
 
347
            # -- it actually does nothing so it barely matters :)
340
348
            unittest.TestResult.addSuccess(self, test)
341
349
 
342
350
    def printErrorList(self, flavour, errors):
370
378
        return self.wasSuccessful()
371
379
 
372
380
 
373
 
 
374
381
class TextTestResult(ExtendedTestResult):
375
382
    """Displays progress and results of tests in text form"""
376
383
 
441
448
            self._test_description(test), err[1])
442
449
 
443
450
    def report_skip(self, test, skip_excinfo):
444
 
        self.skip_count += 1
445
 
        if False:
446
 
            # at the moment these are mostly not things we can fix
447
 
            # and so they just produce stipple; use the verbose reporter
448
 
            # to see them.
449
 
            if False:
450
 
                # show test and reason for skip
451
 
                self.pb.note('SKIP: %s\n    %s\n', 
452
 
                    self._shortened_test_description(test),
453
 
                    skip_excinfo[1])
454
 
            else:
455
 
                # since the class name was left behind in the still-visible
456
 
                # progress bar...
457
 
                self.pb.note('SKIP: %s', skip_excinfo[1])
 
451
        pass
 
452
 
 
453
    def report_not_applicable(self, test, skip_excinfo):
 
454
        pass
458
455
 
459
456
    def report_unsupported(self, test, feature):
460
457
        """test cannot be run because feature is missing."""
520
517
        self.stream.flush()
521
518
 
522
519
    def report_skip(self, test, skip_excinfo):
523
 
        self.skip_count += 1
524
520
        self.stream.writeln(' SKIP %s\n%s'
525
521
                % (self._testTimeString(test),
526
522
                   self._error_summary(skip_excinfo)))
527
523
 
 
524
    def report_not_applicable(self, test, skip_excinfo):
 
525
        self.stream.writeln('  N/A %s\n%s'
 
526
                % (self._testTimeString(test),
 
527
                   self._error_summary(skip_excinfo)))
 
528
 
528
529
    def report_unsupported(self, test, feature):
529
530
        """test cannot be run because feature is missing."""
530
531
        self.stream.writeln("NODEP %s\n    The feature '%s' is not available."
629
630
    """Indicates that a test was intentionally skipped, rather than failing."""
630
631
 
631
632
 
 
633
class TestNotApplicable(TestSkipped):
 
634
    """A test is not applicable to the situation where it was run.
 
635
 
 
636
    This is only normally raised by parameterized tests, if they find that 
 
637
    the instance they're constructed upon does not support one aspect 
 
638
    of its interface.
 
639
    """
 
640
 
 
641
 
632
642
class KnownFailure(AssertionError):
633
643
    """Indicates that a test failed in a precisely expected manner.
634
644
 
2505
2515
    return suite
2506
2516
 
2507
2517
 
 
2518
def multiply_tests_from_modules(module_name_list, scenario_iter):
 
2519
    """Adapt all tests in some given modules to given scenarios.
 
2520
 
 
2521
    This is the recommended public interface for test parameterization.
 
2522
    Typically the test_suite() method for a per-implementation test
 
2523
    suite will call multiply_tests_from_modules and return the 
 
2524
    result.
 
2525
 
 
2526
    :param module_name_list: List of fully-qualified names of test
 
2527
        modules.
 
2528
    :param scenario_iter: Iterable of pairs of (scenario_name, 
 
2529
        scenario_param_dict).
 
2530
 
 
2531
    This returns a new TestSuite containing the cross product of
 
2532
    all the tests in all the modules, each repeated for each scenario.
 
2533
    Each test is adapted by adding the scenario name at the end 
 
2534
    of its name, and updating the test object's __dict__ with the
 
2535
    scenario_param_dict.
 
2536
 
 
2537
    >>> r = multiply_tests_from_modules(
 
2538
    ...     ['bzrlib.tests.test_sampler'],
 
2539
    ...     [('one', dict(param=1)), 
 
2540
    ...      ('two', dict(param=2))])
 
2541
    >>> tests = list(iter_suite_tests(r))
 
2542
    >>> len(tests)
 
2543
    2
 
2544
    >>> tests[0].id()
 
2545
    'bzrlib.tests.test_sampler.DemoTest.test_nothing(one)'
 
2546
    >>> tests[0].param
 
2547
    1
 
2548
    >>> tests[1].param
 
2549
    2
 
2550
    """
 
2551
    loader = TestLoader()
 
2552
    suite = TestSuite()
 
2553
    adapter = TestScenarioApplier()
 
2554
    adapter.scenarios = list(scenario_iter)
 
2555
    adapt_modules(module_name_list, adapter, loader, suite)
 
2556
    return suite
 
2557
 
 
2558
 
2508
2559
def adapt_modules(mods_list, adapter, loader, suite):
2509
2560
    """Adapt the modules in mods_list using adapter and add to suite."""
2510
2561
    for test in iter_suite_tests(loader.loadTestsFromModuleNames(mods_list)):