Donald Meyers / Mbed OS evan
Committer:
djmeyers
Date:
Sat Mar 18 22:37:16 2017 +0000
Revision:
0:06ee5f8a484a
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
djmeyers 0:06ee5f8a484a 1 import sys
djmeyers 0:06ee5f8a484a 2 import os
djmeyers 0:06ee5f8a484a 3 from glob import glob
djmeyers 0:06ee5f8a484a 4
djmeyers 0:06ee5f8a484a 5 from pyparsing import *
djmeyers 0:06ee5f8a484a 6 from junit_xml import TestSuite, TestCase
djmeyers 0:06ee5f8a484a 7
djmeyers 0:06ee5f8a484a 8
djmeyers 0:06ee5f8a484a 9 class UnityTestSummary:
djmeyers 0:06ee5f8a484a 10 def __init__(self):
djmeyers 0:06ee5f8a484a 11 self.report = ''
djmeyers 0:06ee5f8a484a 12 self.total_tests = 0
djmeyers 0:06ee5f8a484a 13 self.failures = 0
djmeyers 0:06ee5f8a484a 14 self.ignored = 0
djmeyers 0:06ee5f8a484a 15 self.targets = 0
djmeyers 0:06ee5f8a484a 16 self.root = None
djmeyers 0:06ee5f8a484a 17 self.test_suites = dict()
djmeyers 0:06ee5f8a484a 18
djmeyers 0:06ee5f8a484a 19 def run(self):
djmeyers 0:06ee5f8a484a 20 # Clean up result file names
djmeyers 0:06ee5f8a484a 21 results = []
djmeyers 0:06ee5f8a484a 22 for target in self.targets:
djmeyers 0:06ee5f8a484a 23 results.append(target.replace('\\', '/'))
djmeyers 0:06ee5f8a484a 24
djmeyers 0:06ee5f8a484a 25 # Dig through each result file, looking for details on pass/fail:
djmeyers 0:06ee5f8a484a 26 for result_file in results:
djmeyers 0:06ee5f8a484a 27 lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n')))
djmeyers 0:06ee5f8a484a 28 if len(lines) == 0:
djmeyers 0:06ee5f8a484a 29 raise Exception("Empty test result file: %s" % result_file)
djmeyers 0:06ee5f8a484a 30
djmeyers 0:06ee5f8a484a 31 # define an expression for your file reference
djmeyers 0:06ee5f8a484a 32 entry_one = Combine(
djmeyers 0:06ee5f8a484a 33 oneOf(list(alphas)) + ':/' +
djmeyers 0:06ee5f8a484a 34 Word(alphanums + '_-./'))
djmeyers 0:06ee5f8a484a 35
djmeyers 0:06ee5f8a484a 36 entry_two = Word(printables + ' ', excludeChars=':')
djmeyers 0:06ee5f8a484a 37 entry = entry_one | entry_two
djmeyers 0:06ee5f8a484a 38
djmeyers 0:06ee5f8a484a 39 delimiter = Literal(':').suppress()
djmeyers 0:06ee5f8a484a 40 tc_result_line = Group(entry.setResultsName('tc_file_name') + delimiter + entry.setResultsName(
djmeyers 0:06ee5f8a484a 41 'tc_line_nr') + delimiter + entry.setResultsName('tc_name') + delimiter + entry.setResultsName(
djmeyers 0:06ee5f8a484a 42 'tc_status') + Optional(
djmeyers 0:06ee5f8a484a 43 delimiter + entry.setResultsName('tc_msg'))).setResultsName("tc_line")
djmeyers 0:06ee5f8a484a 44
djmeyers 0:06ee5f8a484a 45 eol = LineEnd().suppress()
djmeyers 0:06ee5f8a484a 46 sol = LineStart().suppress()
djmeyers 0:06ee5f8a484a 47 blank_line = sol + eol
djmeyers 0:06ee5f8a484a 48
djmeyers 0:06ee5f8a484a 49 tc_summary_line = Group(Word(nums).setResultsName("num_of_tests") + "Tests" + Word(nums).setResultsName(
djmeyers 0:06ee5f8a484a 50 "num_of_fail") + "Failures" + Word(nums).setResultsName("num_of_ignore") + "Ignored").setResultsName(
djmeyers 0:06ee5f8a484a 51 "tc_summary")
djmeyers 0:06ee5f8a484a 52 tc_end_line = Or(Literal("FAIL"), Literal('Ok')).setResultsName("tc_result")
djmeyers 0:06ee5f8a484a 53
djmeyers 0:06ee5f8a484a 54 # run it and see...
djmeyers 0:06ee5f8a484a 55 pp1 = tc_result_line | Optional(tc_summary_line | tc_end_line)
djmeyers 0:06ee5f8a484a 56 pp1.ignore(blank_line | OneOrMore("-"))
djmeyers 0:06ee5f8a484a 57
djmeyers 0:06ee5f8a484a 58 result = list()
djmeyers 0:06ee5f8a484a 59 for l in lines:
djmeyers 0:06ee5f8a484a 60 result.append((pp1.parseString(l)).asDict())
djmeyers 0:06ee5f8a484a 61 # delete empty results
djmeyers 0:06ee5f8a484a 62 result = filter(None, result)
djmeyers 0:06ee5f8a484a 63
djmeyers 0:06ee5f8a484a 64 tc_list = list()
djmeyers 0:06ee5f8a484a 65 for r in result:
djmeyers 0:06ee5f8a484a 66 if 'tc_line' in r:
djmeyers 0:06ee5f8a484a 67 tmp_tc_line = r['tc_line']
djmeyers 0:06ee5f8a484a 68
djmeyers 0:06ee5f8a484a 69 # get only the file name which will be used as the classname
djmeyers 0:06ee5f8a484a 70 file_name = tmp_tc_line['tc_file_name'].split('\\').pop().split('/').pop().rsplit('.', 1)[0]
djmeyers 0:06ee5f8a484a 71 tmp_tc = TestCase(name=tmp_tc_line['tc_name'], classname=file_name)
djmeyers 0:06ee5f8a484a 72 if 'tc_status' in tmp_tc_line:
djmeyers 0:06ee5f8a484a 73 if str(tmp_tc_line['tc_status']) == 'IGNORE':
djmeyers 0:06ee5f8a484a 74 if 'tc_msg' in tmp_tc_line:
djmeyers 0:06ee5f8a484a 75 tmp_tc.add_skipped_info(message=tmp_tc_line['tc_msg'],
djmeyers 0:06ee5f8a484a 76 output=r'[File]={0}, [Line]={1}'.format(
djmeyers 0:06ee5f8a484a 77 tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr']))
djmeyers 0:06ee5f8a484a 78 else:
djmeyers 0:06ee5f8a484a 79 tmp_tc.add_skipped_info(message=" ")
djmeyers 0:06ee5f8a484a 80 elif str(tmp_tc_line['tc_status']) == 'FAIL':
djmeyers 0:06ee5f8a484a 81 if 'tc_msg' in tmp_tc_line:
djmeyers 0:06ee5f8a484a 82 tmp_tc.add_failure_info(message=tmp_tc_line['tc_msg'],
djmeyers 0:06ee5f8a484a 83 output=r'[File]={0}, [Line]={1}'.format(
djmeyers 0:06ee5f8a484a 84 tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr']))
djmeyers 0:06ee5f8a484a 85 else:
djmeyers 0:06ee5f8a484a 86 tmp_tc.add_failure_info(message=" ")
djmeyers 0:06ee5f8a484a 87
djmeyers 0:06ee5f8a484a 88 tc_list.append((str(result_file), tmp_tc))
djmeyers 0:06ee5f8a484a 89
djmeyers 0:06ee5f8a484a 90 for k, v in tc_list:
djmeyers 0:06ee5f8a484a 91 try:
djmeyers 0:06ee5f8a484a 92 self.test_suites[k].append(v)
djmeyers 0:06ee5f8a484a 93 except KeyError:
djmeyers 0:06ee5f8a484a 94 self.test_suites[k] = [v]
djmeyers 0:06ee5f8a484a 95 ts = []
djmeyers 0:06ee5f8a484a 96 for suite_name in self.test_suites:
djmeyers 0:06ee5f8a484a 97 ts.append(TestSuite(suite_name, self.test_suites[suite_name]))
djmeyers 0:06ee5f8a484a 98
djmeyers 0:06ee5f8a484a 99 with open('result.xml', 'w') as f:
djmeyers 0:06ee5f8a484a 100 TestSuite.to_file(f, ts, prettyprint='True', encoding='utf-8')
djmeyers 0:06ee5f8a484a 101
djmeyers 0:06ee5f8a484a 102 return self.report
djmeyers 0:06ee5f8a484a 103
djmeyers 0:06ee5f8a484a 104 def set_targets(self, target_array):
djmeyers 0:06ee5f8a484a 105 self.targets = target_array
djmeyers 0:06ee5f8a484a 106
djmeyers 0:06ee5f8a484a 107 def set_root_path(self, path):
djmeyers 0:06ee5f8a484a 108 self.root = path
djmeyers 0:06ee5f8a484a 109
djmeyers 0:06ee5f8a484a 110 @staticmethod
djmeyers 0:06ee5f8a484a 111 def usage(err_msg=None):
djmeyers 0:06ee5f8a484a 112 print("\nERROR: ")
djmeyers 0:06ee5f8a484a 113 if err_msg:
djmeyers 0:06ee5f8a484a 114 print(err_msg)
djmeyers 0:06ee5f8a484a 115 print("\nUsage: unity_test_summary.py result_file_directory/ root_path/")
djmeyers 0:06ee5f8a484a 116 print(" result_file_directory - The location of your results files.")
djmeyers 0:06ee5f8a484a 117 print(" Defaults to current directory if not specified.")
djmeyers 0:06ee5f8a484a 118 print(" Should end in / if specified.")
djmeyers 0:06ee5f8a484a 119 print(" root_path - Helpful for producing more verbose output if using relative paths.")
djmeyers 0:06ee5f8a484a 120 sys.exit(1)
djmeyers 0:06ee5f8a484a 121
djmeyers 0:06ee5f8a484a 122
djmeyers 0:06ee5f8a484a 123 if __name__ == '__main__':
djmeyers 0:06ee5f8a484a 124 uts = UnityTestSummary()
djmeyers 0:06ee5f8a484a 125 try:
djmeyers 0:06ee5f8a484a 126 # look in the specified or current directory for result files
djmeyers 0:06ee5f8a484a 127 if len(sys.argv) > 1:
djmeyers 0:06ee5f8a484a 128 targets_dir = sys.argv[1]
djmeyers 0:06ee5f8a484a 129 else:
djmeyers 0:06ee5f8a484a 130 targets_dir = './'
djmeyers 0:06ee5f8a484a 131 targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*')))
djmeyers 0:06ee5f8a484a 132 if len(targets) == 0:
djmeyers 0:06ee5f8a484a 133 raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir)
djmeyers 0:06ee5f8a484a 134 uts.set_targets(targets)
djmeyers 0:06ee5f8a484a 135
djmeyers 0:06ee5f8a484a 136 # set the root path
djmeyers 0:06ee5f8a484a 137 if len(sys.argv) > 2:
djmeyers 0:06ee5f8a484a 138 root_path = sys.argv[2]
djmeyers 0:06ee5f8a484a 139 else:
djmeyers 0:06ee5f8a484a 140 root_path = os.path.split(__file__)[0]
djmeyers 0:06ee5f8a484a 141 uts.set_root_path(root_path)
djmeyers 0:06ee5f8a484a 142
djmeyers 0:06ee5f8a484a 143 # run the summarizer
djmeyers 0:06ee5f8a484a 144 print(uts.run())
djmeyers 0:06ee5f8a484a 145 except Exception as e:
djmeyers 0:06ee5f8a484a 146 UnityTestSummary.usage(e)