~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Robert Collins
  • Date: 2007-03-22 09:04:59 UTC
  • mto: (2378.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 2379.
  • Revision ID: robertc@robertcollins.net-20070322090459-q0gjq21qgrj453hf
Some minor cleanups of test code, and implement KnownFailure support as
per http://bazaar-vcs.org/BzrExtendTestSuite. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
180
180
        self.num_tests = num_tests
181
181
        self.error_count = 0
182
182
        self.failure_count = 0
 
183
        self.known_failure_count = 0
183
184
        self.skip_count = 0
184
185
        self.count = 0
185
186
        self._overall_start_time = time.time()
221
222
        """Record that a test has started."""
222
223
        self._start_time = time.time()
223
224
 
 
225
    def _cleanupLogFile(self, test):
 
226
        # We can only do this if we have one of our TestCases, not if
 
227
        # we have a doctest.
 
228
        setKeepLogfile = getattr(test, 'setKeepLogfile', None)
 
229
        if setKeepLogfile is not None:
 
230
            setKeepLogfile()
 
231
 
224
232
    def addError(self, test, err):
225
233
        if isinstance(err[1], TestSkipped):
226
 
            return self.addSkipped(test, err)    
 
234
            return self.addSkipped(test, err)
227
235
        unittest.TestResult.addError(self, test, err)
228
 
        # We can only do this if we have one of our TestCases, not if
229
 
        # we have a doctest.
230
 
        setKeepLogfile = getattr(test, 'setKeepLogfile', None)
231
 
        if setKeepLogfile is not None:
232
 
            setKeepLogfile()
 
236
        self._cleanupLogFile(test)
233
237
        self.extractBenchmarkTime(test)
 
238
        self.error_count += 1
234
239
        self.report_error(test, err)
235
240
        if self.stop_early:
236
241
            self.stop()
237
242
 
238
243
    def addFailure(self, test, err):
 
244
        self._cleanupLogFile(test)
 
245
        self.extractBenchmarkTime(test)
 
246
        if isinstance(err[1], KnownFailure):
 
247
            return self.addKnownFailure(test, err)
239
248
        unittest.TestResult.addFailure(self, test, err)
240
 
        # We can only do this if we have one of our TestCases, not if
241
 
        # we have a doctest.
242
 
        setKeepLogfile = getattr(test, 'setKeepLogfile', None)
243
 
        if setKeepLogfile is not None:
244
 
            setKeepLogfile()
245
 
        self.extractBenchmarkTime(test)
 
249
        self.failure_count += 1
246
250
        self.report_failure(test, err)
247
251
        if self.stop_early:
248
252
            self.stop()
249
253
 
 
254
    def addKnownFailure(self, test, err):
 
255
        self.known_failure_count += 1
 
256
        self.report_known_failure(test, err)
 
257
 
250
258
    def addSuccess(self, test):
251
259
        self.extractBenchmarkTime(test)
252
260
        if self._bench_history is not None:
301
309
class TextTestResult(ExtendedTestResult):
302
310
    """Displays progress and results of tests in text form"""
303
311
 
304
 
    def __init__(self, *args, **kw):
305
 
        ExtendedTestResult.__init__(self, *args, **kw)
306
 
        self.pb = self.ui.nested_progress_bar()
 
312
    def __init__(self, stream, descriptions, verbosity,
 
313
                 bench_history=None,
 
314
                 num_tests=None,
 
315
                 pb=None,
 
316
                 ):
 
317
        ExtendedTestResult.__init__(self, stream, descriptions, verbosity,
 
318
            bench_history, num_tests)
 
319
        if pb is None:
 
320
            self.pb = ui.ui_factory.nested_progress_bar()
 
321
            self._supplied_pb = False
 
322
        else:
 
323
            self.pb = pb
 
324
            self._supplied_pb = True
307
325
        self.pb.show_pct = False
308
326
        self.pb.show_spinner = False
309
327
        self.pb.show_eta = False, 
322
340
            a += ', %d errors' % self.error_count
323
341
        if self.failure_count:
324
342
            a += ', %d failed' % self.failure_count
 
343
        if self.known_failure_count:
 
344
            a += ', %d known failures' % self.known_failure_count
325
345
        if self.skip_count:
326
346
            a += ', %d skipped' % self.skip_count
327
347
        a += ']'
342
362
            return self._shortened_test_description(test)
343
363
 
344
364
    def report_error(self, test, err):
345
 
        self.error_count += 1
346
365
        self.pb.note('ERROR: %s\n    %s\n', 
347
366
            self._test_description(test),
348
367
            err[1],
349
368
            )
350
369
 
351
370
    def report_failure(self, test, err):
352
 
        self.failure_count += 1
353
371
        self.pb.note('FAIL: %s\n    %s\n', 
354
372
            self._test_description(test),
355
373
            err[1],
356
374
            )
357
375
 
 
376
    def report_known_failure(self, test, err):
 
377
        self.pb.note('XFAIL: %s\n%s\n',
 
378
            self._test_description(test), err[1])
 
379
 
358
380
    def report_skip(self, test, skip_excinfo):
359
381
        self.skip_count += 1
360
382
        if False:
375
397
        self.pb.update('cleaning up...')
376
398
 
377
399
    def finished(self):
378
 
        self.pb.finished()
 
400
        if not self._supplied_pb:
 
401
            self.pb.finished()
379
402
 
380
403
 
381
404
class VerboseTestResult(ExtendedTestResult):
414
437
        return '%s%s' % (indent, err[1])
415
438
 
416
439
    def report_error(self, test, err):
417
 
        self.error_count += 1
418
440
        self.stream.writeln('ERROR %s\n%s'
419
441
                % (self._testTimeString(),
420
442
                   self._error_summary(err)))
421
443
 
422
444
    def report_failure(self, test, err):
423
 
        self.failure_count += 1
424
445
        self.stream.writeln(' FAIL %s\n%s'
425
446
                % (self._testTimeString(),
426
447
                   self._error_summary(err)))
427
448
 
 
449
    def report_known_failure(self, test, err):
 
450
        self.stream.writeln('XFAIL %s\n%s'
 
451
                % (self._testTimeString(),
 
452
                   self._error_summary(err)))
 
453
 
428
454
    def report_success(self, test):
429
455
        self.stream.writeln('   OK %s' % self._testTimeString())
430
456
        for bench_called, stats in getattr(test, '_benchcalls', []):
431
457
            self.stream.writeln('LSProf output for %s(%s, %s)' % bench_called)
432
458
            stats.pprint(file=self.stream)
 
459
        # flush the stream so that we get smooth output. This verbose mode is
 
460
        # used to show the output in PQM.
433
461
        self.stream.flush()
434
462
 
435
463
    def report_skip(self, test, skip_excinfo):
486
514
            if errored:
487
515
                if failed: self.stream.write(", ")
488
516
                self.stream.write("errors=%d" % errored)
 
517
            if result.known_failure_count:
 
518
                if failed or errored: self.stream.write(", ")
 
519
                self.stream.write("known_failure_count=%d" %
 
520
                    result.known_failure_count)
489
521
            self.stream.writeln(")")
490
522
        else:
491
 
            self.stream.writeln("OK")
 
523
            if result.known_failure_count:
 
524
                self.stream.writeln("OK (known_failures=%d)" %
 
525
                    result.known_failure_count)
 
526
            else:
 
527
                self.stream.writeln("OK")
492
528
        if result.skip_count > 0:
493
529
            skipped = result.skip_count
494
530
            self.stream.writeln('%d test%s skipped' %
545
581
    """Indicates that a test was intentionally skipped, rather than failing."""
546
582
 
547
583
 
 
584
class KnownFailure(AssertionError):
 
585
    """Indicates that a test failed in a precisely expected manner.
 
586
 
 
587
    Such failures dont block the whole test suite from passing because they are
 
588
    indicators of partially completed code or of future work. We have an
 
589
    explicit error for them so that we can ensure that they are always visible:
 
590
    KnownFailures are always shown in the output of bzr selftest.
 
591
    """
 
592
 
 
593
 
548
594
class CommandFailed(Exception):
549
595
    pass
550
596
 
970
1016
    def _restoreHooks(self):
971
1017
        bzrlib.branch.Branch.hooks = self._preserved_hooks
972
1018
 
 
1019
    def knownFailure(self, reason):
 
1020
        """This test has failed for some known reason."""
 
1021
        raise KnownFailure(reason)
 
1022
 
973
1023
    def tearDown(self):
974
1024
        self._runCleanups()
975
1025
        unittest.TestCase.tearDown(self)