1#!/usr/bin/env python
2#
3# Copyright 2006, Google Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met:
9#
10#     * Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12#     * Redistributions in binary form must reproduce the above
13# copyright notice, this list of conditions and the following disclaimer
14# in the documentation and/or other materials provided with the
15# distribution.
16#     * Neither the name of Google Inc. nor the names of its
17# contributors may be used to endorse or promote products derived from
18# this software without specific prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31"""Unit test for Google Test's --gtest_list_tests flag.
32
33A user can ask Google Test to list all tests by specifying the
34--gtest_list_tests flag. If output is requested, via --gtest_output=xml
35or --gtest_output=json, the tests are listed, with extra information in the
36output file.
37This script tests such functionality by invoking gtest_list_output_unittest_
38 (a program written with Google Test) the command line flags.
39"""
40
41import os
42import re
43from googletest.test import gtest_test_utils
44
45GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
46GTEST_OUTPUT_FLAG = '--gtest_output'
47
48EXPECTED_XML = """<\?xml version="1.0" encoding="UTF-8"\?>
49<testsuites tests="16" name="AllTests">
50  <testsuite name="FooTest" tests="2">
51    <testcase name="Test1" file=".*gtest_list_output_unittest_.cc" line="43" />
52    <testcase name="Test2" file=".*gtest_list_output_unittest_.cc" line="45" />
53  </testsuite>
54  <testsuite name="FooTestFixture" tests="2">
55    <testcase name="Test3" file=".*gtest_list_output_unittest_.cc" line="48" />
56    <testcase name="Test4" file=".*gtest_list_output_unittest_.cc" line="49" />
57  </testsuite>
58  <testsuite name="TypedTest/0" tests="2">
59    <testcase name="Test7" type_param="int" file=".*gtest_list_output_unittest_.cc" line="60" />
60    <testcase name="Test8" type_param="int" file=".*gtest_list_output_unittest_.cc" line="61" />
61  </testsuite>
62  <testsuite name="TypedTest/1" tests="2">
63    <testcase name="Test7" type_param="bool" file=".*gtest_list_output_unittest_.cc" line="60" />
64    <testcase name="Test8" type_param="bool" file=".*gtest_list_output_unittest_.cc" line="61" />
65  </testsuite>
66  <testsuite name="Single/TypeParameterizedTestSuite/0" tests="2">
67    <testcase name="Test9" type_param="int" file=".*gtest_list_output_unittest_.cc" line="66" />
68    <testcase name="Test10" type_param="int" file=".*gtest_list_output_unittest_.cc" line="67" />
69  </testsuite>
70  <testsuite name="Single/TypeParameterizedTestSuite/1" tests="2">
71    <testcase name="Test9" type_param="bool" file=".*gtest_list_output_unittest_.cc" line="66" />
72    <testcase name="Test10" type_param="bool" file=".*gtest_list_output_unittest_.cc" line="67" />
73  </testsuite>
74  <testsuite name="ValueParam/ValueParamTest" tests="4">
75    <testcase name="Test5/0" value_param="33" file=".*gtest_list_output_unittest_.cc" line="52" />
76    <testcase name="Test5/1" value_param="42" file=".*gtest_list_output_unittest_.cc" line="52" />
77    <testcase name="Test6/0" value_param="33" file=".*gtest_list_output_unittest_.cc" line="53" />
78    <testcase name="Test6/1" value_param="42" file=".*gtest_list_output_unittest_.cc" line="53" />
79  </testsuite>
80</testsuites>
81"""
82
83EXPECTED_JSON = """{
84  "tests": 16,
85  "name": "AllTests",
86  "testsuites": \[
87    {
88      "name": "FooTest",
89      "tests": 2,
90      "testsuite": \[
91        {
92          "name": "Test1",
93          "file": ".*gtest_list_output_unittest_.cc",
94          "line": 43
95        },
96        {
97          "name": "Test2",
98          "file": ".*gtest_list_output_unittest_.cc",
99          "line": 45
100        }
101      \]
102    },
103    {
104      "name": "FooTestFixture",
105      "tests": 2,
106      "testsuite": \[
107        {
108          "name": "Test3",
109          "file": ".*gtest_list_output_unittest_.cc",
110          "line": 48
111        },
112        {
113          "name": "Test4",
114          "file": ".*gtest_list_output_unittest_.cc",
115          "line": 49
116        }
117      \]
118    },
119    {
120      "name": "TypedTest\\\\/0",
121      "tests": 2,
122      "testsuite": \[
123        {
124          "name": "Test7",
125          "type_param": "int",
126          "file": ".*gtest_list_output_unittest_.cc",
127          "line": 60
128        },
129        {
130          "name": "Test8",
131          "type_param": "int",
132          "file": ".*gtest_list_output_unittest_.cc",
133          "line": 61
134        }
135      \]
136    },
137    {
138      "name": "TypedTest\\\\/1",
139      "tests": 2,
140      "testsuite": \[
141        {
142          "name": "Test7",
143          "type_param": "bool",
144          "file": ".*gtest_list_output_unittest_.cc",
145          "line": 60
146        },
147        {
148          "name": "Test8",
149          "type_param": "bool",
150          "file": ".*gtest_list_output_unittest_.cc",
151          "line": 61
152        }
153      \]
154    },
155    {
156      "name": "Single\\\\/TypeParameterizedTestSuite\\\\/0",
157      "tests": 2,
158      "testsuite": \[
159        {
160          "name": "Test9",
161          "type_param": "int",
162          "file": ".*gtest_list_output_unittest_.cc",
163          "line": 66
164        },
165        {
166          "name": "Test10",
167          "type_param": "int",
168          "file": ".*gtest_list_output_unittest_.cc",
169          "line": 67
170        }
171      \]
172    },
173    {
174      "name": "Single\\\\/TypeParameterizedTestSuite\\\\/1",
175      "tests": 2,
176      "testsuite": \[
177        {
178          "name": "Test9",
179          "type_param": "bool",
180          "file": ".*gtest_list_output_unittest_.cc",
181          "line": 66
182        },
183        {
184          "name": "Test10",
185          "type_param": "bool",
186          "file": ".*gtest_list_output_unittest_.cc",
187          "line": 67
188        }
189      \]
190    },
191    {
192      "name": "ValueParam\\\\/ValueParamTest",
193      "tests": 4,
194      "testsuite": \[
195        {
196          "name": "Test5\\\\/0",
197          "value_param": "33",
198          "file": ".*gtest_list_output_unittest_.cc",
199          "line": 52
200        },
201        {
202          "name": "Test5\\\\/1",
203          "value_param": "42",
204          "file": ".*gtest_list_output_unittest_.cc",
205          "line": 52
206        },
207        {
208          "name": "Test6\\\\/0",
209          "value_param": "33",
210          "file": ".*gtest_list_output_unittest_.cc",
211          "line": 53
212        },
213        {
214          "name": "Test6\\\\/1",
215          "value_param": "42",
216          "file": ".*gtest_list_output_unittest_.cc",
217          "line": 53
218        }
219      \]
220    }
221  \]
222}
223"""
224
225
226class GTestListTestsOutputUnitTest(gtest_test_utils.TestCase):
227  """Unit test for Google Test's list tests with output to file functionality."""
228
229  def testXml(self):
230    """Verifies XML output for listing tests in a Google Test binary.
231
232    Runs a test program that generates an empty XML output, and
233    tests that the XML output is expected.
234    """
235    self._TestOutput('xml', EXPECTED_XML)
236
237  def testJSON(self):
238    """Verifies XML output for listing tests in a Google Test binary.
239
240    Runs a test program that generates an empty XML output, and
241    tests that the XML output is expected.
242    """
243    self._TestOutput('json', EXPECTED_JSON)
244
245  def _GetOutput(self, out_format):
246    file_path = os.path.join(
247        gtest_test_utils.GetTempDir(), 'test_out.' + out_format
248    )
249    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
250        'gtest_list_output_unittest_'
251    )
252
253    command = [
254        gtest_prog_path,
255        '%s=%s:%s' % (GTEST_OUTPUT_FLAG, out_format, file_path),
256        '--gtest_list_tests',
257    ]
258    environ_copy = os.environ.copy()
259    p = gtest_test_utils.Subprocess(
260        command, env=environ_copy, working_dir=gtest_test_utils.GetTempDir()
261    )
262
263    self.assertTrue(p.exited)
264    self.assertEqual(0, p.exit_code)
265    self.assertTrue(os.path.isfile(file_path))
266    with open(file_path) as f:
267      result = f.read()
268    return result
269
270  def _TestOutput(self, test_format, expected_output):
271    actual = self._GetOutput(test_format)
272    actual_lines = actual.splitlines()
273    expected_lines = expected_output.splitlines()
274    line_count = 0
275    for actual_line in actual_lines:
276      expected_line = expected_lines[line_count]
277      expected_line_re = re.compile(expected_line.strip())
278      self.assertTrue(
279          expected_line_re.match(actual_line.strip()),
280          'actual output of "%s",\n'
281          'which does not match expected regex of "%s"\n'
282          'on line %d' % (actual, expected_output, line_count),
283      )
284      line_count = line_count + 1
285
286
287if __name__ == '__main__':
288  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
289  gtest_test_utils.Main()
290