OLD | NEW |
| (Empty) |
1 # Copyright (c) 2012 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 """Returns a filtered list of tests based on the given gtest filter. | |
105 | |
106 See http://code.google.com/p/googletest/wiki/AdvancedGuide | |
107 for gtest_filter specification. | |
108 """ | |
109 pattern_groups = gtest_filter.split('-') | |
110 positive_patterns = pattern_groups[0].split(':') | |
111 negative_patterns = None | |
112 if len(pattern_groups) > 1: | |
113 negative_patterns = pattern_groups[1].split(':') | |
114 | |
115 tests = [] | |
116 for test in all_tests: | |
117 test_name = GetTestName(test) | |
118 # Test name must by matched by one positive pattern. | |
119 for pattern in positive_patterns: | |
120 if fnmatch.fnmatch(test_name, pattern): | |
121 break | |
122 else: | |
123 continue | |
124 # Test name must not be matched by any negative patterns. | |
125 for pattern in negative_patterns or []: | |
126 if fnmatch.fnmatch(test_name, pattern): | |
127 break | |
128 else: | |
129 tests += [test] | |
130 return tests | |
OLD | NEW |