1289715Sglebius#! python3 2289715Sglebius# ========================================== 3289715Sglebius# Unity Project - A Test Framework for C 4289715Sglebius# Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de 5289715Sglebius# [Released under MIT License. Please refer to license.txt for details] 6289715Sglebius# Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams 7289715Sglebius# ========================================== 8289715Sglebiusimport sys 9289715Sglebiusimport os 10289715Sglebiusimport re 11289715Sglebiusfrom glob import glob 12289715Sglebius 13289715Sglebiusclass UnityTestSummary: 14289715Sglebius def __init__(self): 15289715Sglebius self.report = '' 16289715Sglebius self.total_tests = 0 17289715Sglebius self.failures = 0 18289715Sglebius self.ignored = 0 19289715Sglebius 20289715Sglebius def run(self): 21289715Sglebius # Clean up result file names 22289715Sglebius results = [] 23289715Sglebius for target in self.targets: 24289715Sglebius results.append(target.replace('\\', '/')) 25289715Sglebius 26289715Sglebius # Dig through each result file, looking for details on pass/fail: 27289715Sglebius failure_output = [] 28289715Sglebius ignore_output = [] 29289715Sglebius 30289715Sglebius for result_file in results: 31289715Sglebius lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) 32289715Sglebius if len(lines) == 0: 33289715Sglebius raise Exception("Empty test result file: %s" % result_file) 34289715Sglebius 35289715Sglebius details = self.get_details(result_file, lines) 36289715Sglebius failures = details['failures'] 37289715Sglebius ignores = details['ignores'] 38289715Sglebius if len(failures) > 0: failure_output.append('\n'.join(failures)) 39289715Sglebius if len(ignores) > 0: ignore_output.append('n'.join(ignores)) 40289715Sglebius tests,failures,ignored = self.parse_test_summary('\n'.join(lines)) 41289715Sglebius self.total_tests += tests 42289715Sglebius self.failures += failures 43289715Sglebius self.ignored += ignored 44289715Sglebius 45289715Sglebius if self.ignored > 0: 46289715Sglebius self.report += "\n" 47289715Sglebius self.report += "--------------------------\n" 48289715Sglebius self.report += "UNITY IGNORED TEST SUMMARY\n" 49289715Sglebius self.report += "--------------------------\n" 50289715Sglebius self.report += "\n".join(ignore_output) 51289715Sglebius 52289715Sglebius if self.failures > 0: 53289715Sglebius self.report += "\n" 54289715Sglebius self.report += "--------------------------\n" 55289715Sglebius self.report += "UNITY FAILED TEST SUMMARY\n" 56289715Sglebius self.report += "--------------------------\n" 57289715Sglebius self.report += '\n'.join(failure_output) 58289715Sglebius 59289715Sglebius self.report += "\n" 60289715Sglebius self.report += "--------------------------\n" 61289715Sglebius self.report += "OVERALL UNITY TEST SUMMARY\n" 62289715Sglebius self.report += "--------------------------\n" 63289715Sglebius self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored) 64289715Sglebius self.report += "\n" 65289715Sglebius 66289715Sglebius return self.report 67289715Sglebius 68289715Sglebius def set_targets(self, target_array): 69289715Sglebius self.targets = target_array 70289715Sglebius 71289715Sglebius def set_root_path(self, path): 72289715Sglebius self.root = path 73289715Sglebius 74289715Sglebius def usage(self, err_msg=None): 75289715Sglebius print("\nERROR: ") 76289715Sglebius if err_msg: 77289715Sglebius print(err_msg) 78289715Sglebius print("\nUsage: unity_test_summary.rb result_file_directory/ root_path/") 79289715Sglebius print(" result_file_directory - The location of your results files.") 80289715Sglebius print(" Defaults to current directory if not specified.") 81289715Sglebius print(" Should end in / if specified.") 82289715Sglebius print(" root_path - Helpful for producing more verbose output if using relative paths.") 83289715Sglebius sys.exit(1) 84289715Sglebius 85289715Sglebius def get_details(self, result_file, lines): 86289715Sglebius results = { 'failures': [], 'ignores': [], 'successes': [] } 87289715Sglebius for line in lines: 88289715Sglebius parts = line.split(':') 89289715Sglebius if len(parts) != 5: 90289715Sglebius continue 91289715Sglebius src_file,src_line,test_name,status,msg = parts 92289715Sglebius if len(self.root) > 0: 93289715Sglebius line_out = "%s%s" % (self.root, line) 94289715Sglebius else: 95289715Sglebius line_out = line 96289715Sglebius if status == 'IGNORE': 97289715Sglebius results['ignores'].append(line_out) 98289715Sglebius elif status == 'FAIL': 99289715Sglebius results['failures'].append(line_out) 100289715Sglebius elif status == 'PASS': 101289715Sglebius results['successes'].append(line_out) 102289715Sglebius return results 103289715Sglebius 104289715Sglebius def parse_test_summary(self, summary): 105289715Sglebius m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary) 106289715Sglebius if not m: 107289715Sglebius raise Exception("Couldn't parse test results: %s" % summary) 108289715Sglebius 109289715Sglebius return int(m.group(1)), int(m.group(2)), int(m.group(3)) 110289715Sglebius 111289715Sglebius 112289715Sglebiusif __name__ == '__main__': 113289715Sglebius uts = UnityTestSummary() 114289715Sglebius try: 115289715Sglebius #look in the specified or current directory for result files 116289715Sglebius if len(sys.argv) > 1: 117289715Sglebius targets_dir = sys.argv[1] 118289715Sglebius else: 119289715Sglebius targets_dir = './' 120289715Sglebius targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) 121289715Sglebius if len(targets) == 0: 122289715Sglebius raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) 123289715Sglebius uts.set_targets(targets) 124289715Sglebius 125289715Sglebius #set the root path 126289715Sglebius if len(sys.argv) > 2: 127289715Sglebius root_path = sys.argv[2] 128289715Sglebius else: 129289715Sglebius root_path = os.path.split(__file__)[0] 130289715Sglebius uts.set_root_path(root_path) 131289715Sglebius 132289715Sglebius #run the summarizer 133289715Sglebius print(uts.run()) 134289715Sglebius except Exception as e: 135289715Sglebius uts.usage(e) 136