Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 """Tests the text output of Google C++ Mocking Framework.
00033
00034 SYNOPSIS
00035 gmock_output_test.py --build_dir=BUILD/DIR --gengolden
00036 # where BUILD/DIR contains the built gmock_output_test_ file.
00037 gmock_output_test.py --gengolden
00038 gmock_output_test.py
00039 """
00040
00041 __author__ = 'wan@google.com (Zhanyong Wan)'
00042
00043 import os
00044 import re
00045 import sys
00046
00047 import gmock_test_utils
00048
00049
00050
00051 GENGOLDEN_FLAG = '--gengolden'
00052
00053 PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_output_test_')
00054 COMMAND = [PROGRAM_PATH, '--gtest_stack_trace_depth=0', '--gtest_print_time=0']
00055 GOLDEN_NAME = 'gmock_output_test_golden.txt'
00056 GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(), GOLDEN_NAME)
00057
00058
00059 def ToUnixLineEnding(s):
00060 """Changes all Windows/Mac line endings in s to UNIX line endings."""
00061
00062 return s.replace('\r\n', '\n').replace('\r', '\n')
00063
00064
00065 def RemoveReportHeaderAndFooter(output):
00066 """Removes Google Test result report's header and footer from the output."""
00067
00068 output = re.sub(r'.*gtest_main.*\n', '', output)
00069 output = re.sub(r'\[.*\d+ tests.*\n', '', output)
00070 output = re.sub(r'\[.* test environment .*\n', '', output)
00071 output = re.sub(r'\[=+\] \d+ tests .* ran.*', '', output)
00072 output = re.sub(r'.* FAILED TESTS\n', '', output)
00073 return output
00074
00075
00076 def RemoveLocations(output):
00077 """Removes all file location info from a Google Test program's output.
00078
00079 Args:
00080 output: the output of a Google Test program.
00081
00082 Returns:
00083 output with all file location info (in the form of
00084 'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or
00085 'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by
00086 'FILE:#: '.
00087 """
00088
00089 return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\:', 'FILE:#:', output)
00090
00091
00092 def NormalizeErrorMarker(output):
00093 """Normalizes the error marker, which is different on Windows vs on Linux."""
00094
00095 return re.sub(r' error: ', ' Failure\n', output)
00096
00097
00098 def RemoveMemoryAddresses(output):
00099 """Removes memory addresses from the test output."""
00100
00101 return re.sub(r'@\w+', '@0x#', output)
00102
00103
00104 def RemoveTestNamesOfLeakedMocks(output):
00105 """Removes the test names of leaked mock objects from the test output."""
00106
00107 return re.sub(r'\(used in test .+\) ', '', output)
00108
00109
00110 def GetLeakyTests(output):
00111 """Returns a list of test names that leak mock objects."""
00112
00113
00114
00115
00116 return re.findall(r'\(used in test (.+)\)', output)
00117
00118
00119 def GetNormalizedOutputAndLeakyTests(output):
00120 """Normalizes the output of gmock_output_test_.
00121
00122 Args:
00123 output: The test output.
00124
00125 Returns:
00126 A tuple (the normalized test output, the list of test names that have
00127 leaked mocks).
00128 """
00129
00130 output = ToUnixLineEnding(output)
00131 output = RemoveReportHeaderAndFooter(output)
00132 output = NormalizeErrorMarker(output)
00133 output = RemoveLocations(output)
00134 output = RemoveMemoryAddresses(output)
00135 return (RemoveTestNamesOfLeakedMocks(output), GetLeakyTests(output))
00136
00137
00138 def GetShellCommandOutput(cmd):
00139 """Runs a command in a sub-process, and returns its STDOUT in a string."""
00140
00141 return gmock_test_utils.Subprocess(cmd, capture_stderr=False).output
00142
00143
00144 def GetNormalizedCommandOutputAndLeakyTests(cmd):
00145 """Runs a command and returns its normalized output and a list of leaky tests.
00146
00147 Args:
00148 cmd: the shell command.
00149 """
00150
00151
00152 os.environ['GTEST_CATCH_EXCEPTIONS'] = '1'
00153 return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd))
00154
00155
00156 class GMockOutputTest(gmock_test_utils.TestCase):
00157 def testOutput(self):
00158 (output, leaky_tests) = GetNormalizedCommandOutputAndLeakyTests(COMMAND)
00159 golden_file = open(GOLDEN_PATH, 'rb')
00160 golden = golden_file.read()
00161 golden_file.close()
00162
00163
00164 self.assertEquals(golden, output)
00165
00166
00167
00168 self.assertEquals(['GMockOutputTest.CatchesLeakedMocks',
00169 'GMockOutputTest.CatchesLeakedMocks'],
00170 leaky_tests)
00171
00172
00173 if __name__ == '__main__':
00174 if sys.argv[1:] == [GENGOLDEN_FLAG]:
00175 (output, _) = GetNormalizedCommandOutputAndLeakyTests(COMMAND)
00176 golden_file = open(GOLDEN_PATH, 'wb')
00177 golden_file.write(output)
00178 golden_file.close()
00179 else:
00180 gmock_test_utils.Main()