1290001Sglebius#! python3 2290001Sglebius# ========================================== 3290001Sglebius# Unity Project - A Test Framework for C 4290001Sglebius# Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de 5290001Sglebius# [Released under MIT License. Please refer to license.txt for details] 6290001Sglebius# Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams 7290001Sglebius# ========================================== 8290001Sglebiusimport sys 9290001Sglebiusimport os 10290001Sglebiusimport re 11290001Sglebiusfrom glob import glob 12290001Sglebius 13290001Sglebiusclass UnityTestSummary: 14290001Sglebius def __init__(self): 15290001Sglebius self.report = '' 16290001Sglebius self.total_tests = 0 17290001Sglebius self.failures = 0 18290001Sglebius self.ignored = 0 19290001Sglebius 20290001Sglebius def run(self): 21290001Sglebius # Clean up result file names 22290001Sglebius results = [] 23290001Sglebius for target in self.targets: 24290001Sglebius results.append(target.replace('\\', '/')) 25290001Sglebius 26290001Sglebius # Dig through each result file, looking for details on pass/fail: 27290001Sglebius failure_output = [] 28290001Sglebius ignore_output = [] 29290001Sglebius 30290001Sglebius for result_file in results: 31290001Sglebius lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) 32290001Sglebius if len(lines) == 0: 33290001Sglebius raise Exception("Empty test result file: %s" % result_file) 34290001Sglebius 35290001Sglebius details = self.get_details(result_file, lines) 36290001Sglebius failures = details['failures'] 37290001Sglebius ignores = details['ignores'] 38290001Sglebius if len(failures) > 0: failure_output.append('\n'.join(failures)) 39290001Sglebius if len(ignores) > 0: ignore_output.append('n'.join(ignores)) 40290001Sglebius tests,failures,ignored = self.parse_test_summary('\n'.join(lines)) 41290001Sglebius self.total_tests += tests 42290001Sglebius self.failures += failures 43290001Sglebius self.ignored += ignored 44290001Sglebius 45290001Sglebius if self.ignored > 0: 46290001Sglebius self.report += "\n" 47290001Sglebius self.report += "--------------------------\n" 48290001Sglebius self.report += "UNITY IGNORED TEST SUMMARY\n" 49290001Sglebius self.report += "--------------------------\n" 50290001Sglebius self.report += "\n".join(ignore_output) 51290001Sglebius 52290001Sglebius if self.failures > 0: 53290001Sglebius self.report += "\n" 54290001Sglebius self.report += "--------------------------\n" 55290001Sglebius self.report += "UNITY FAILED TEST SUMMARY\n" 56290001Sglebius self.report += "--------------------------\n" 57290001Sglebius self.report += '\n'.join(failure_output) 58290001Sglebius 59290001Sglebius self.report += "\n" 60290001Sglebius self.report += "--------------------------\n" 61290001Sglebius self.report += "OVERALL UNITY TEST SUMMARY\n" 62290001Sglebius self.report += "--------------------------\n" 63290001Sglebius self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored) 64290001Sglebius self.report += "\n" 65290001Sglebius 66290001Sglebius return self.report 67290001Sglebius 68290001Sglebius def set_targets(self, target_array): 69290001Sglebius self.targets = target_array 70290001Sglebius 71290001Sglebius def set_root_path(self, path): 72290001Sglebius self.root = path 73290001Sglebius 74290001Sglebius def usage(self, err_msg=None): 75290001Sglebius print("\nERROR: ") 76290001Sglebius if err_msg: 77290001Sglebius print(err_msg) 78290001Sglebius print("\nUsage: unity_test_summary.rb result_file_directory/ root_path/") 79290001Sglebius print(" result_file_directory - The location of your results files.") 80290001Sglebius print(" Defaults to current directory if not specified.") 81290001Sglebius print(" Should end in / if specified.") 82290001Sglebius print(" root_path - Helpful for producing more verbose output if using relative paths.") 83290001Sglebius sys.exit(1) 84290001Sglebius 85290001Sglebius def get_details(self, result_file, lines): 86290001Sglebius results = { 'failures': [], 'ignores': [], 'successes': [] } 87290001Sglebius for line in lines: 88290001Sglebius parts = line.split(':') 89290001Sglebius if len(parts) != 5: 90290001Sglebius continue 91290001Sglebius src_file,src_line,test_name,status,msg = parts 92290001Sglebius if len(self.root) > 0: 93290001Sglebius line_out = "%s%s" % (self.root, line) 94290001Sglebius else: 95290001Sglebius line_out = line 96290001Sglebius if status == 'IGNORE': 97290001Sglebius results['ignores'].append(line_out) 98290001Sglebius elif status == 'FAIL': 99290001Sglebius results['failures'].append(line_out) 100290001Sglebius elif status == 'PASS': 101290001Sglebius results['successes'].append(line_out) 102290001Sglebius return results 103290001Sglebius 104290001Sglebius def parse_test_summary(self, summary): 105290001Sglebius m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary) 106290001Sglebius if not m: 107290001Sglebius raise Exception("Couldn't parse test results: %s" % summary) 108290001Sglebius 109290001Sglebius return int(m.group(1)), int(m.group(2)), int(m.group(3)) 110290001Sglebius 111290001Sglebius 112290001Sglebiusif __name__ == '__main__': 113290001Sglebius uts = UnityTestSummary() 114290001Sglebius try: 115290001Sglebius #look in the specified or current directory for result files 116290001Sglebius if len(sys.argv) > 1: 117290001Sglebius targets_dir = sys.argv[1] 118290001Sglebius else: 119290001Sglebius targets_dir = './' 120290001Sglebius targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) 121290001Sglebius if len(targets) == 0: 122290001Sglebius raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) 123290001Sglebius uts.set_targets(targets) 124290001Sglebius 125290001Sglebius #set the root path 126290001Sglebius if len(sys.argv) > 2: 127290001Sglebius root_path = sys.argv[2] 128290001Sglebius else: 129290001Sglebius root_path = os.path.split(__file__)[0] 130290001Sglebius uts.set_root_path(root_path) 131290001Sglebius 132290001Sglebius #run the summarizer 133290001Sglebius print(uts.run()) 134290001Sglebius except Exception as e: 135290001Sglebius uts.usage(e) 136