OLD | NEW |
(Empty) | |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Utilities for dealing with the python unittest module.""" |
| 6 |
| 7 import fnmatch |
| 8 import sys |
| 9 import unittest |
| 10 |
| 11 |
| 12 class _TextTestResult(unittest._TextTestResult): |
| 13 """A test result class that can print formatted text results to a stream. |
| 14 |
| 15 Results printed in conformance with gtest output format, like: |
| 16 [ RUN ] autofill.AutofillTest.testAutofillInvalid: "test desc." |
| 17 [ OK ] autofill.AutofillTest.testAutofillInvalid |
| 18 [ RUN ] autofill.AutofillTest.testFillProfile: "test desc." |
| 19 [ OK ] autofill.AutofillTest.testFillProfile |
| 20 [ RUN ] autofill.AutofillTest.testFillProfileCrazyCharacters: "Test." |
| 21 [ OK ] autofill.AutofillTest.testFillProfileCrazyCharacters |
| 22 """ |
| 23 def __init__(self, stream, descriptions, verbosity): |
| 24 unittest._TextTestResult.__init__(self, stream, descriptions, verbosity) |
| 25 self._fails = set() |
| 26 |
| 27 def _GetTestURI(self, test): |
| 28 return '%s.%s.%s' % (test.__class__.__module__, |
| 29 test.__class__.__name__, |
| 30 test._testMethodName) |
| 31 |
| 32 def getDescription(self, test): |
| 33 return '%s: "%s"' % (self._GetTestURI(test), test.shortDescription()) |
| 34 |
| 35 def startTest(self, test): |
| 36 unittest.TestResult.startTest(self, test) |
| 37 self.stream.writeln('[ RUN ] %s' % self.getDescription(test)) |
| 38 |
| 39 def addSuccess(self, test): |
| 40 unittest.TestResult.addSuccess(self, test) |
| 41 self.stream.writeln('[ OK ] %s' % self._GetTestURI(test)) |
| 42 |
| 43 def addError(self, test, err): |
| 44 unittest.TestResult.addError(self, test, err) |
| 45 self.stream.writeln('[ ERROR ] %s' % self._GetTestURI(test)) |
| 46 self._fails.add(self._GetTestURI(test)) |
| 47 |
| 48 def addFailure(self, test, err): |
| 49 unittest.TestResult.addFailure(self, test, err) |
| 50 self.stream.writeln('[ FAILED ] %s' % self._GetTestURI(test)) |
| 51 self._fails.add(self._GetTestURI(test)) |
| 52 |
| 53 def getRetestFilter(self): |
| 54 return ':'.join(self._fails) |
| 55 |
| 56 |
| 57 class TextTestRunner(unittest.TextTestRunner): |
| 58 """Test Runner for displaying test results in textual format. |
| 59 |
| 60 Results are displayed in conformance with google test output. |
| 61 """ |
| 62 |
| 63 def __init__(self, verbosity=1): |
| 64 unittest.TextTestRunner.__init__(self, stream=sys.stderr, |
| 65 verbosity=verbosity) |
| 66 |
| 67 def _makeResult(self): |
| 68 return _TextTestResult(self.stream, self.descriptions, self.verbosity) |
| 69 |
| 70 |
| 71 def GetTestsFromSuite(suite): |
| 72 """Returns all the tests from a given test suite.""" |
| 73 tests = [] |
| 74 for x in suite: |
| 75 if isinstance(x, unittest.TestSuite): |
| 76 tests += GetTestsFromSuite(x) |
| 77 else: |
| 78 tests += [x] |
| 79 return tests |
| 80 |
| 81 |
| 82 def GetTestNamesFromSuite(suite): |
| 83 """Returns a list of every test name in the given suite.""" |
| 84 return map(lambda x: GetTestName(x), GetTestsFromSuite(suite)) |
| 85 |
| 86 |
| 87 def GetTestName(test): |
| 88 """Gets the test name of the given unittest test.""" |
| 89 return '.'.join([test.__class__.__module__, |
| 90 test.__class__.__name__, |
| 91 test._testMethodName]) |
| 92 |
| 93 |
| 94 def FilterTestSuite(suite, gtest_filter): |
| 95 """Returns a new filtered tests suite based on the given gtest filter. |
| 96 |
| 97 See http://code.google.com/p/googletest/wiki/AdvancedGuide |
| 98 for gtest_filter specification. |
| 99 """ |
| 100 return unittest.TestSuite(FilterTests(GetTestsFromSuite(suite), gtest_filter)) |
| 101 |
| 102 |
| 103 def FilterTests(all_tests, gtest_filter): |
| 104 """Filter a list of tests based on the given gtest filter. |
| 105 |
| 106 Args: |
| 107 all_tests: List of tests (unittest.TestSuite) |
| 108 gtest_filter: Filter to apply. |
| 109 |
| 110 Returns: |
| 111 Filtered subset of the given list of tests. |
| 112 """ |
| 113 test_names = [GetTestName(test) for test in all_tests] |
| 114 filtered_names = FilterTestNames(test_names, gtest_filter) |
| 115 return [test for test in all_tests if GetTestName(test) in filtered_names] |
| 116 |
| 117 |
| 118 def FilterTestNames(all_tests, gtest_filter): |
| 119 """Filter a list of test names based on the given gtest filter. |
| 120 |
| 121 See http://code.google.com/p/googletest/wiki/AdvancedGuide |
| 122 for gtest_filter specification. |
| 123 |
| 124 Args: |
| 125 all_tests: List of test names. |
| 126 gtest_filter: Filter to apply. |
| 127 |
| 128 Returns: |
| 129 Filtered subset of the given list of test names. |
| 130 """ |
| 131 pattern_groups = gtest_filter.split('-') |
| 132 positive_patterns = ['*'] |
| 133 if pattern_groups[0]: |
| 134 positive_patterns = pattern_groups[0].split(':') |
| 135 negative_patterns = None |
| 136 if len(pattern_groups) > 1: |
| 137 negative_patterns = pattern_groups[1].split(':') |
| 138 |
| 139 tests = [] |
| 140 for test in all_tests: |
| 141 # Test name must by matched by one positive pattern. |
| 142 for pattern in positive_patterns: |
| 143 if fnmatch.fnmatch(test, pattern): |
| 144 break |
| 145 else: |
| 146 continue |
| 147 # Test name must not be matched by any negative patterns. |
| 148 for pattern in negative_patterns or []: |
| 149 if fnmatch.fnmatch(test, pattern): |
| 150 break |
| 151 else: |
| 152 tests += [test] |
| 153 return tests |
OLD | NEW |