├── gtest_prettify_example.gif ├── README.md ├── gtest_parser.py ├── gtest_template.html └── gtest_example_output.html /gtest_prettify_example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeilZhy/gtest-report-prettify/HEAD/gtest_prettify_example.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gtest-report-prettify 2 | Creates a HTML page from a Google Test JSON or XML report. 3 | 4 | To run: 5 | ```python 6 | python -m gtest_parser PATH_TO_GOOGLE_TEST_JSON_OR_XML_FILE.json/xml 7 | ``` 8 | ![](gtest_prettify_example.gif) 9 | -------------------------------------------------------------------------------- /gtest_parser.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | from jinja2 import FileSystemLoader, Environment 4 | import xml.etree.ElementTree as ET 5 | 6 | # Constants 7 | TEMPLATE_FILE = "gtest_template.html" 8 | OUTPUT_FILE = "gtest_output.html" 9 | 10 | def process_input(input_file): 11 | """ Processes the input file. 12 | Will return a JSON object to be used by the HTML parser. 13 | If the file is in XML format it will be turned into a JSON object. 14 | """ 15 | 16 | data = None 17 | 18 | with open(input_file) as gtest_json: 19 | if input_file.endswith('.json'): 20 | data = json.load(gtest_json) 21 | elif input_file.endswith('.xml'): 22 | # Need to turn the XML into the same format as the JSON 23 | data = process_xml(gtest_json) 24 | else: 25 | print("Unknown file type.") 26 | return 27 | 28 | return data 29 | 30 | def process_xml(xml): 31 | """ Processes the XML file. 32 | Will return a JSON object that matches that created by GTEST. 33 | """ 34 | 35 | tree = ET.parse(xml) 36 | root = tree.getroot() 37 | overviewName = root.attrib['name'] 38 | overviewTests = int(root.attrib['tests']) 39 | overviewFailed = int(root.attrib['failures']) 40 | overviewDisabled = int(root.attrib['disabled']) 41 | data = { 42 | 'name': overviewName, 43 | 'tests': overviewTests, 44 | 'failures': overviewFailed, 45 | 'disabled': overviewDisabled, 46 | 'testsuites': [] 47 | } 48 | 49 | for child in root: 50 | testSuitename = child.attrib['name'] 51 | totalTests = int(child.attrib['tests']) 52 | failed = int(child.attrib['failures']) 53 | disabled = int(child.attrib['disabled']) 54 | 55 | tempTest = [] 56 | for test in child: 57 | testName = test.attrib['name'] 58 | testTime = test.attrib['time'] 59 | testStatus = test.attrib['status'].upper() 60 | # Getting all of the failure messages 61 | testFailures = [] 62 | for failure in test: 63 | testFailure = failure.attrib['message'] 64 | testFailures.append({ 65 | 'failure': testFailure 66 | }) 67 | 68 | # If there are no failures dont add it to the JSON 69 | if testFailures: 70 | tempTest.append({ 71 | 'name': testName, 72 | 'time': testTime, 73 | 'status': testStatus, 74 | 'failures': testFailures 75 | }) 76 | else: 77 | tempTest.append({ 78 | 'name': testName, 79 | 'status': testStatus, 80 | 'time': testTime 81 | }) 82 | print(tempTest) 83 | tempTestSuite = { 84 | 'name': testSuitename, 85 | 'tests': totalTests, 86 | 'failures': failed, 87 | 'disabled': disabled, 88 | 'testsuite': tempTest 89 | } 90 | data['testsuites'].append(tempTestSuite) 91 | 92 | return data 93 | 94 | def create_html(data): 95 | """ Turns the JSON object into a HTML file. 96 | Will grab the template and render it with our JSON object. 97 | """ 98 | templateLoader = FileSystemLoader(searchpath="./") 99 | templateEnv = Environment(loader=templateLoader) 100 | template = templateEnv.get_template(TEMPLATE_FILE) 101 | 102 | with open(OUTPUT_FILE, "w") as output_html: 103 | output_html.write(template.render(test_overview=data, test_suites=data['testsuites'])) 104 | 105 | if __name__ == "__main__": 106 | json_data = process_input(sys.argv[1]) 107 | create_html(json_data) 108 | -------------------------------------------------------------------------------- /gtest_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 13 | Google Test Report 14 | 15 | 16 |
17 |
18 |
{{ test_overview.name }}
19 |
20 |
21 |
22 |
23 | 24 |

25 | 26 | Number of tests: {{ test_overview.tests }} 27 | 28 |

29 | 30 |
31 |
32 | 33 |

34 | 35 | Passed: {{ test_overview.tests - test_overview.failures - test_overview.disabled }} 36 | 37 |

38 | 39 |
40 |
41 | 42 |

43 | 44 | Failed: {{ test_overview.failures }} 45 | 46 |

47 | 48 |
49 |
50 | 51 |

52 | 53 | Disabled: {{ test_overview.disabled }} 54 | 55 |

56 | 57 |
58 |
59 |
60 | 61 |
62 | {% for test_suite in test_suites %} 63 | 64 | {{ test_suite.name }} 65 | 66 | {% endfor %} 67 |
68 |
69 |
70 | 71 | {% for test_suite in test_suites %} 72 |
73 |
74 |
75 | {{ test_suite.name }} 76 |
77 | 80 | 83 | 86 | 89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | 97 |

98 | 99 | Number of tests: {{ test_suite.tests }} 100 | 101 |

102 | 103 |
104 |
105 | 106 |

107 | 108 | Passed: {{ test_suite.tests - test_suite.failures - test_suite.disabled }} 109 | 110 |

111 | 112 |
113 |
114 | 115 |

116 | 117 | Failed: {{ test_suite.failures }} 118 | 119 |

120 | 121 |
122 |
123 | 124 |

125 | 126 | Disabled: {{ test_suite.disabled }} 127 | 128 |

129 | 130 |
131 |
132 |
133 | 134 |
135 | {% for test in test_suite.testsuite %} 136 | {% if test.failures %} 137 |
138 |
139 |

140 | 143 |

144 |
145 | 146 |
147 |
148 |
{{ "Time: " + test.time }}
149 | {% for failure in test.failures %} 150 |

{{ "Failure: " + failure.failure }}

151 | {% endfor %} 152 |
153 |
154 |
155 | {% endif %} 156 | {% endfor %} 157 |
158 |
159 | {% for test in test_suite.testsuite %} 160 | {% if test.status == "RUN" and not test.failures %} 161 |
162 |
163 |

164 | 167 |

168 |
169 | 170 |
171 |
172 |
{{ "Time: " + test.time }}
173 |
174 |
175 |
176 | {% endif %} 177 | {% endfor %} 178 |
179 |
180 | {% for test in test_suite.testsuite %} 181 | {% if test.status == "NOTRUN" and not test.failures %} 182 |
183 |
184 |

185 | 188 |

189 |
190 | 191 |
192 |
193 |
Disabled Test
194 |
195 |
196 |
197 | {% endif %} 198 | {% endfor %} 199 |
200 |
201 |
202 | {% endfor %} 203 |
204 | 205 | 206 | 207 | 208 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /gtest_example_output.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 13 | Google Test Report 14 | 15 | 16 |
17 |
18 |
AllTests
19 |
20 |
21 |
22 |
23 | 24 |

25 | 26 | Number of tests: 9 27 | 28 |

29 | 30 |
31 |
32 | 33 |

34 | 35 | Passed: 3 36 | 37 |

38 | 39 |
40 |
41 | 42 |

43 | 44 | Failed: 3 45 | 46 |

47 | 48 |
49 |
50 | 51 |

52 | 53 | Disabled: 3 54 | 55 |

56 | 57 |
58 |
59 |
60 | 61 | 76 |
77 |
78 | 79 | 80 |
81 |
82 |
83 | TestCasesOneUnitTests 84 |
85 | 88 | 91 | 94 | 97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | 105 |

106 | 107 | Number of tests: 3 108 | 109 |

110 | 111 |
112 |
113 | 114 |

115 | 116 | Passed: 1 117 | 118 |

119 | 120 |
121 |
122 | 123 |

124 | 125 | Failed: 1 126 | 127 |

128 | 129 |
130 |
131 | 132 |

133 | 134 | Disabled: 1 135 | 136 |

137 | 138 |
139 |
140 |
141 | 142 |
143 | 144 | 145 | 146 | 147 |
148 |
149 |

150 | 153 |

154 |
155 | 156 |
157 |
158 |
Time: 0.002s
159 | 160 |

Failure: c:\users\spencer.robertson\documents\projects\cid\web services testing\webservicestests\webservicestests\test_cases_one.cpp:535 161 | Value of: FALSE 162 | Actual: false 163 | Expected: true

164 | 165 |
166 |
167 |
168 | 169 | 170 | 171 | 172 |
173 |
174 | 175 | 176 |
177 |
178 |

179 | 182 |

183 |
184 | 185 |
186 |
187 |
Time: 0.002s
188 |
189 |
190 |
191 | 192 | 193 | 194 | 195 | 196 | 197 |
198 |
199 | 200 | 201 | 202 | 203 | 204 | 205 |
206 |
207 |

208 | 211 |

212 |
213 | 214 |
215 |
216 |
Disabled Test
217 |
218 |
219 |
220 | 221 | 222 |
223 |
224 |
225 | 226 |
227 |
228 |
229 | TestCasesTwoUnitTests 230 |
231 | 234 | 237 | 240 | 243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 | 251 |

252 | 253 | Number of tests: 3 254 | 255 |

256 | 257 |
258 |
259 | 260 |

261 | 262 | Passed: 1 263 | 264 |

265 | 266 |
267 |
268 | 269 |

270 | 271 | Failed: 1 272 | 273 |

274 | 275 |
276 |
277 | 278 |

279 | 280 | Disabled: 1 281 | 282 |

283 | 284 |
285 |
286 |
287 | 288 |
289 | 290 | 291 | 292 | 293 |
294 |
295 |

296 | 299 |

300 |
301 | 302 |
303 |
304 |
Time: 0.002s
305 | 306 |

Failure: c:\users\spencer.robertson\documents\projects\cid\web services testing\webservicestests\webservicestests\test_cases_two.cpp:166 307 | Value of: FALSE 308 | Actual: false 309 | Expected: true

310 | 311 |
312 |
313 |
314 | 315 | 316 | 317 | 318 |
319 |
320 | 321 | 322 |
323 |
324 |

325 | 328 |

329 |
330 | 331 |
332 |
333 |
Time: 0.002s
334 |
335 |
336 |
337 | 338 | 339 | 340 | 341 | 342 | 343 |
344 |
345 | 346 | 347 | 348 | 349 | 350 | 351 |
352 |
353 |

354 | 357 |

358 |
359 | 360 |
361 |
362 |
Disabled Test
363 |
364 |
365 |
366 | 367 | 368 |
369 |
370 |
371 | 372 |
373 |
374 |
375 | TestCasesThreeUnitTests 376 |
377 | 380 | 383 | 386 | 389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 | 397 |

398 | 399 | Number of tests: 3 400 | 401 |

402 | 403 |
404 |
405 | 406 |

407 | 408 | Passed: 1 409 | 410 |

411 | 412 |
413 |
414 | 415 |

416 | 417 | Failed: 1 418 | 419 |

420 | 421 |
422 |
423 | 424 |

425 | 426 | Disabled: 1 427 | 428 |

429 | 430 |
431 |
432 |
433 | 434 |
435 | 436 | 437 | 438 | 439 |
440 |
441 |

442 | 445 |

446 |
447 | 448 |
449 |
450 |
Time: 0.002s
451 | 452 |

Failure: c:\users\spencer.robertson\documents\projects\cid\web services testing\webservicestests\webservicestests\test_cases_three.cpp:138 453 | Value of: FALSE 454 | Actual: false 455 | Expected: true

456 | 457 |
458 |
459 |
460 | 461 | 462 | 463 | 464 |
465 |
466 | 467 | 468 |
469 |
470 |

471 | 474 |

475 |
476 | 477 |
478 |
479 |
Time: 0.002s
480 |
481 |
482 |
483 | 484 | 485 | 486 | 487 | 488 | 489 |
490 |
491 | 492 | 493 | 494 | 495 | 496 | 497 |
498 |
499 |

500 | 503 |

504 |
505 | 506 |
507 |
508 |
Disabled Test
509 |
510 |
511 |
512 | 513 | 514 |
515 |
516 |
517 | 518 |
519 | 520 | 521 | 522 | 523 | 574 | 575 | --------------------------------------------------------------------------------