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.
5 """Utilities for dealing with the python unittest module."""
12 class _TextTestResult(unittest
._TextTestResult
):
13 """A test result class that can print formatted text results to a stream.
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
23 def __init__(self
, stream
, descriptions
, verbosity
):
24 unittest
._TextTestResult
.__init
__(self
, stream
, descriptions
, verbosity
)
27 def _GetTestURI(self
, test
):
28 return '%s.%s.%s' % (test
.__class
__.__module
__,
29 test
.__class
__.__name
__,
32 def getDescription(self
, test
):
33 return '%s: "%s"' % (self
._GetTestURI
(test
), test
.shortDescription())
35 def startTest(self
, test
):
36 unittest
.TestResult
.startTest(self
, test
)
37 self
.stream
.writeln('[ RUN ] %s' % self
.getDescription(test
))
39 def addSuccess(self
, test
):
40 unittest
.TestResult
.addSuccess(self
, test
)
41 self
.stream
.writeln('[ OK ] %s' % self
._GetTestURI
(test
))
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
))
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
))
53 def getRetestFilter(self
):
54 return ':'.join(self
._fails
)
57 class TextTestRunner(unittest
.TextTestRunner
):
58 """Test Runner for displaying test results in textual format.
60 Results are displayed in conformance with google test output.
63 def __init__(self
, verbosity
=1):
64 unittest
.TextTestRunner
.__init
__(self
, stream
=sys
.stderr
,
67 def _makeResult(self
):
68 return _TextTestResult(self
.stream
, self
.descriptions
, self
.verbosity
)
71 def GetTestsFromSuite(suite
):
72 """Returns all the tests from a given test suite."""
75 if isinstance(x
, unittest
.TestSuite
):
76 tests
+= GetTestsFromSuite(x
)
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
))
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
])
94 def FilterTestSuite(suite
, gtest_filter
):
95 """Returns a new filtered tests suite based on the given gtest filter.
97 See http://code.google.com/p/googletest/wiki/AdvancedGuide
98 for gtest_filter specification.
100 return unittest
.TestSuite(FilterTests(GetTestsFromSuite(suite
), gtest_filter
))
103 def FilterTests(all_tests
, gtest_filter
):
104 """Filter a list of tests based on the given gtest filter.
107 all_tests: List of tests (unittest.TestSuite)
108 gtest_filter: Filter to apply.
111 Filtered subset of the given list of tests.
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
]
118 def FilterTestNames(all_tests
, gtest_filter
):
119 """Filter a list of test names based on the given gtest filter.
121 See http://code.google.com/p/googletest/wiki/AdvancedGuide
122 for gtest_filter specification.
125 all_tests: List of test names.
126 gtest_filter: Filter to apply.
129 Filtered subset of the given list of test names.
131 pattern_groups
= gtest_filter
.split('-')
132 positive_patterns
= pattern_groups
[0].split(':')
133 negative_patterns
= None
134 if len(pattern_groups
) > 1:
135 negative_patterns
= pattern_groups
[1].split(':')
138 for test
in all_tests
:
139 # Test name must by matched by one positive pattern.
140 for pattern
in positive_patterns
:
141 if fnmatch
.fnmatch(test
, pattern
):
145 # Test name must not be matched by any negative patterns.
146 for pattern
in negative_patterns
or []:
147 if fnmatch
.fnmatch(test
, pattern
):