Ram Gandikota
/
ABCD
A metronome using the FRDM K64F board
pal/Test/Unity/auto/unity_test_summary.py@0:a7a43371b306, 2017-05-14 (annotated)
- Committer:
- ram54288
- Date:
- Sun May 14 18:40:18 2017 +0000
- Revision:
- 0:a7a43371b306
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ram54288 | 0:a7a43371b306 | 1 | #! python3 |
ram54288 | 0:a7a43371b306 | 2 | # ========================================== |
ram54288 | 0:a7a43371b306 | 3 | # Unity Project - A Test Framework for C |
ram54288 | 0:a7a43371b306 | 4 | # Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de |
ram54288 | 0:a7a43371b306 | 5 | # [Released under MIT License. Please refer to license.txt for details] |
ram54288 | 0:a7a43371b306 | 6 | # Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams |
ram54288 | 0:a7a43371b306 | 7 | # ========================================== |
ram54288 | 0:a7a43371b306 | 8 | import sys |
ram54288 | 0:a7a43371b306 | 9 | import os |
ram54288 | 0:a7a43371b306 | 10 | import re |
ram54288 | 0:a7a43371b306 | 11 | from glob import glob |
ram54288 | 0:a7a43371b306 | 12 | |
ram54288 | 0:a7a43371b306 | 13 | class UnityTestSummary: |
ram54288 | 0:a7a43371b306 | 14 | def __init__(self): |
ram54288 | 0:a7a43371b306 | 15 | self.report = '' |
ram54288 | 0:a7a43371b306 | 16 | self.total_tests = 0 |
ram54288 | 0:a7a43371b306 | 17 | self.failures = 0 |
ram54288 | 0:a7a43371b306 | 18 | self.ignored = 0 |
ram54288 | 0:a7a43371b306 | 19 | |
ram54288 | 0:a7a43371b306 | 20 | def run(self): |
ram54288 | 0:a7a43371b306 | 21 | # Clean up result file names |
ram54288 | 0:a7a43371b306 | 22 | results = [] |
ram54288 | 0:a7a43371b306 | 23 | for target in self.targets: |
ram54288 | 0:a7a43371b306 | 24 | results.append(target.replace('\\', '/')) |
ram54288 | 0:a7a43371b306 | 25 | |
ram54288 | 0:a7a43371b306 | 26 | # Dig through each result file, looking for details on pass/fail: |
ram54288 | 0:a7a43371b306 | 27 | failure_output = [] |
ram54288 | 0:a7a43371b306 | 28 | ignore_output = [] |
ram54288 | 0:a7a43371b306 | 29 | |
ram54288 | 0:a7a43371b306 | 30 | for result_file in results: |
ram54288 | 0:a7a43371b306 | 31 | lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) |
ram54288 | 0:a7a43371b306 | 32 | if len(lines) == 0: |
ram54288 | 0:a7a43371b306 | 33 | raise Exception("Empty test result file: %s" % result_file) |
ram54288 | 0:a7a43371b306 | 34 | |
ram54288 | 0:a7a43371b306 | 35 | details = self.get_details(result_file, lines) |
ram54288 | 0:a7a43371b306 | 36 | failures = details['failures'] |
ram54288 | 0:a7a43371b306 | 37 | ignores = details['ignores'] |
ram54288 | 0:a7a43371b306 | 38 | if len(failures) > 0: failure_output.append('\n'.join(failures)) |
ram54288 | 0:a7a43371b306 | 39 | if len(ignores) > 0: ignore_output.append('n'.join(ignores)) |
ram54288 | 0:a7a43371b306 | 40 | tests,failures,ignored = self.parse_test_summary('\n'.join(lines)) |
ram54288 | 0:a7a43371b306 | 41 | self.total_tests += tests |
ram54288 | 0:a7a43371b306 | 42 | self.failures += failures |
ram54288 | 0:a7a43371b306 | 43 | self.ignored += ignored |
ram54288 | 0:a7a43371b306 | 44 | |
ram54288 | 0:a7a43371b306 | 45 | if self.ignored > 0: |
ram54288 | 0:a7a43371b306 | 46 | self.report += "\n" |
ram54288 | 0:a7a43371b306 | 47 | self.report += "--------------------------\n" |
ram54288 | 0:a7a43371b306 | 48 | self.report += "UNITY IGNORED TEST SUMMARY\n" |
ram54288 | 0:a7a43371b306 | 49 | self.report += "--------------------------\n" |
ram54288 | 0:a7a43371b306 | 50 | self.report += "\n".join(ignore_output) |
ram54288 | 0:a7a43371b306 | 51 | |
ram54288 | 0:a7a43371b306 | 52 | if self.failures > 0: |
ram54288 | 0:a7a43371b306 | 53 | self.report += "\n" |
ram54288 | 0:a7a43371b306 | 54 | self.report += "--------------------------\n" |
ram54288 | 0:a7a43371b306 | 55 | self.report += "UNITY FAILED TEST SUMMARY\n" |
ram54288 | 0:a7a43371b306 | 56 | self.report += "--------------------------\n" |
ram54288 | 0:a7a43371b306 | 57 | self.report += '\n'.join(failure_output) |
ram54288 | 0:a7a43371b306 | 58 | |
ram54288 | 0:a7a43371b306 | 59 | self.report += "\n" |
ram54288 | 0:a7a43371b306 | 60 | self.report += "--------------------------\n" |
ram54288 | 0:a7a43371b306 | 61 | self.report += "OVERALL UNITY TEST SUMMARY\n" |
ram54288 | 0:a7a43371b306 | 62 | self.report += "--------------------------\n" |
ram54288 | 0:a7a43371b306 | 63 | self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored) |
ram54288 | 0:a7a43371b306 | 64 | self.report += "\n" |
ram54288 | 0:a7a43371b306 | 65 | |
ram54288 | 0:a7a43371b306 | 66 | return self.report |
ram54288 | 0:a7a43371b306 | 67 | |
ram54288 | 0:a7a43371b306 | 68 | def set_targets(self, target_array): |
ram54288 | 0:a7a43371b306 | 69 | self.targets = target_array |
ram54288 | 0:a7a43371b306 | 70 | |
ram54288 | 0:a7a43371b306 | 71 | def set_root_path(self, path): |
ram54288 | 0:a7a43371b306 | 72 | self.root = path |
ram54288 | 0:a7a43371b306 | 73 | |
ram54288 | 0:a7a43371b306 | 74 | def usage(self, err_msg=None): |
ram54288 | 0:a7a43371b306 | 75 | print("\nERROR: ") |
ram54288 | 0:a7a43371b306 | 76 | if err_msg: |
ram54288 | 0:a7a43371b306 | 77 | print(err_msg) |
ram54288 | 0:a7a43371b306 | 78 | print("\nUsage: unity_test_summary.py result_file_directory/ root_path/") |
ram54288 | 0:a7a43371b306 | 79 | print(" result_file_directory - The location of your results files.") |
ram54288 | 0:a7a43371b306 | 80 | print(" Defaults to current directory if not specified.") |
ram54288 | 0:a7a43371b306 | 81 | print(" Should end in / if specified.") |
ram54288 | 0:a7a43371b306 | 82 | print(" root_path - Helpful for producing more verbose output if using relative paths.") |
ram54288 | 0:a7a43371b306 | 83 | sys.exit(1) |
ram54288 | 0:a7a43371b306 | 84 | |
ram54288 | 0:a7a43371b306 | 85 | def get_details(self, result_file, lines): |
ram54288 | 0:a7a43371b306 | 86 | results = { 'failures': [], 'ignores': [], 'successes': [] } |
ram54288 | 0:a7a43371b306 | 87 | for line in lines: |
ram54288 | 0:a7a43371b306 | 88 | parts = line.split(':') |
ram54288 | 0:a7a43371b306 | 89 | if len(parts) != 5: |
ram54288 | 0:a7a43371b306 | 90 | continue |
ram54288 | 0:a7a43371b306 | 91 | src_file,src_line,test_name,status,msg = parts |
ram54288 | 0:a7a43371b306 | 92 | if len(self.root) > 0: |
ram54288 | 0:a7a43371b306 | 93 | line_out = "%s%s" % (self.root, line) |
ram54288 | 0:a7a43371b306 | 94 | else: |
ram54288 | 0:a7a43371b306 | 95 | line_out = line |
ram54288 | 0:a7a43371b306 | 96 | if status == 'IGNORE': |
ram54288 | 0:a7a43371b306 | 97 | results['ignores'].append(line_out) |
ram54288 | 0:a7a43371b306 | 98 | elif status == 'FAIL': |
ram54288 | 0:a7a43371b306 | 99 | results['failures'].append(line_out) |
ram54288 | 0:a7a43371b306 | 100 | elif status == 'PASS': |
ram54288 | 0:a7a43371b306 | 101 | results['successes'].append(line_out) |
ram54288 | 0:a7a43371b306 | 102 | return results |
ram54288 | 0:a7a43371b306 | 103 | |
ram54288 | 0:a7a43371b306 | 104 | def parse_test_summary(self, summary): |
ram54288 | 0:a7a43371b306 | 105 | m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary) |
ram54288 | 0:a7a43371b306 | 106 | if not m: |
ram54288 | 0:a7a43371b306 | 107 | raise Exception("Couldn't parse test results: %s" % summary) |
ram54288 | 0:a7a43371b306 | 108 | |
ram54288 | 0:a7a43371b306 | 109 | return int(m.group(1)), int(m.group(2)), int(m.group(3)) |
ram54288 | 0:a7a43371b306 | 110 | |
ram54288 | 0:a7a43371b306 | 111 | |
ram54288 | 0:a7a43371b306 | 112 | if __name__ == '__main__': |
ram54288 | 0:a7a43371b306 | 113 | uts = UnityTestSummary() |
ram54288 | 0:a7a43371b306 | 114 | try: |
ram54288 | 0:a7a43371b306 | 115 | #look in the specified or current directory for result files |
ram54288 | 0:a7a43371b306 | 116 | if len(sys.argv) > 1: |
ram54288 | 0:a7a43371b306 | 117 | targets_dir = sys.argv[1] |
ram54288 | 0:a7a43371b306 | 118 | else: |
ram54288 | 0:a7a43371b306 | 119 | targets_dir = './' |
ram54288 | 0:a7a43371b306 | 120 | targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) |
ram54288 | 0:a7a43371b306 | 121 | if len(targets) == 0: |
ram54288 | 0:a7a43371b306 | 122 | raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) |
ram54288 | 0:a7a43371b306 | 123 | uts.set_targets(targets) |
ram54288 | 0:a7a43371b306 | 124 | |
ram54288 | 0:a7a43371b306 | 125 | #set the root path |
ram54288 | 0:a7a43371b306 | 126 | if len(sys.argv) > 2: |
ram54288 | 0:a7a43371b306 | 127 | root_path = sys.argv[2] |
ram54288 | 0:a7a43371b306 | 128 | else: |
ram54288 | 0:a7a43371b306 | 129 | root_path = os.path.split(__file__)[0] |
ram54288 | 0:a7a43371b306 | 130 | uts.set_root_path(root_path) |
ram54288 | 0:a7a43371b306 | 131 | |
ram54288 | 0:a7a43371b306 | 132 | #run the summarizer |
ram54288 | 0:a7a43371b306 | 133 | print(uts.run()) |
ram54288 | 0:a7a43371b306 | 134 | except Exception as e: |
ram54288 | 0:a7a43371b306 | 135 | uts.usage(e) |