Loading parse_test_results.py 0 → 100644 +109 −0 Changes for parse_test_results.py: 109 added lines, 0 removed lines. Original line number Diff line number Diff line from bs4 import BeautifulSoup from sys import argv from testEntry import TestEntry from writeExcel import ExcelWriter import re import argparse usage_str = """ ===================================== Robot Test Reporter written in Python ===================================== Usage python parseTestResults.py output.xml where output.xml is the xml file generated by robot The command outputs to a new xlslx file if it does not exist, or appends to an existing one. """ class TestOutputParser: def __init__(self, fname): self.test_entries = [] self.load_file(fname) def load_file(self, fname): self.contents = "" with open(fname, "r", encoding="utf8") as f: self.contents = f.read() if self.contents == "": print("Empty file {}".format(fname)) exit(-1) def run_parser(self): soup = BeautifulSoup(self.contents, "lxml") # Suite information suite = soup.find("suite") path = suite["source"] # TODO This might be an issue later on. In Unix-style paths the separator is a forward slash parts = path.split("\\") # Extract info for test entries self.api = parts[len(parts) - 2] self.robot_file = parts[len(parts) - 1] # Tests tests = soup.find_all("test") for test in tests: self.test_entries.append(self.create_test_entry(test)) # Write tests ew = ExcelWriter() for entry in self.test_entries: ew.write_test_entry(entry) ew.save() def create_test_entry(self, xml_obj): """ Takes the xml entry corresponding to the test from the output file, and returns a TestEntry object with the relevant information extracted. """ # retrieve ID and name id_raw = xml_obj.find("doc", recursive=False).contents mg = re.search(r"Test ID: ([0-9\.]*)$", id_raw[0].string, re.MULTILINE) test_id = mg.group(1) name = xml_obj["name"] #retrieve status and error message (if FAIL) statusObj = xml_obj.find("status", recursive=False) cts = statusObj.contents error_msg = cts[0] if len(cts) > 0 else "" result = statusObj["status"] return TestEntry(test_id, name, result, error_msg, self.api, self.robot_file) def display_usage(): print(usage_str) if __name__ == "__main__": usage_str = """ ===================================== Robot Test Reporter written in Python ===================================== Usage python parseTestResults.py output.xml where output.xml is the xml file generated by robot The command outputs to a new xlslx file if it does not exist, or appends to an existing one. """ parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') parser.add_argument('-o', dest='fname', action='store_const', default='testResults.xlsx', help='output file name (default: testResults.xlsx)') args = parser.parse_args() TestOutputParser(argv[1]).run_parser() writeExcel.py +12 −11 Changes for writeExcel.py: 12 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ class ExcelWriter: self.wb = getWorkbook() self.ws = self.wb.active def getEntryWithId(self, id): def get_entry_with_id(self, id): """ When inserting an entry, it might be a test being re-run. In that case, the row containing that test needs to be updated, as opposed to appending Loading @@ -32,32 +32,33 @@ class ExcelWriter: return cell.row return -1 def getLastRow(self): def get_last_row(self): for cell in self.ws["A"]: if cell.value is None: return cell.row return cell.row + 1 def writeTestEntry(self, testEntry): existingEntryRow = self.getEntryWithId(testEntry.id) lastRow = self.getLastRow() def writeTestEntry(self, test_entry): existing_entry_row = self.get_entry_with_id(test_entry.id) last_row = self.get_last_row() # Use the above two values to pick a row entryRow = existingEntryRow if existingEntryRow != -1 else lastRow entry_row = existing_entry_row if existing_entry_row != -1 else last_row # Pick a cell color based on test outcome cellCol = ExcelWriter.PASS_COL if testEntry.result == "PASS" else ExcelWriter.FAIL_COL cell_col = ExcelWriter.PASS_COL if test_entry.result == "PASS" else ExcelWriter.FAIL_COL # Test entry as a list entryVals = testEntry.asList() entry_vals = test_entry.asList() for col, cellValue in zip(self.ws.iter_cols(min_row=entryRow, max_col=len(entryVals), max_row=entryRow), entryVals): for col, cell_vale in zip(self.ws.iter_cols(min_row=entry_row, max_col=len(entry_vals), max_row=entry_row), entry_vals): for cell in col: cell.value = cellValue cell.fill = PatternFill("solid", fgColor=cellCol)# cellCol cell.value = cell_vale cell.fill = PatternFill("solid", fgColor=cell_col)# cellCol def save(self): self.wb.save(filename = fname) def initWorkbook(wb): """ Writes column headers to ws Loading Loading
parse_test_results.py 0 → 100644 +109 −0 Changes for parse_test_results.py: 109 added lines, 0 removed lines. Original line number Diff line number Diff line from bs4 import BeautifulSoup from sys import argv from testEntry import TestEntry from writeExcel import ExcelWriter import re import argparse usage_str = """ ===================================== Robot Test Reporter written in Python ===================================== Usage python parseTestResults.py output.xml where output.xml is the xml file generated by robot The command outputs to a new xlslx file if it does not exist, or appends to an existing one. """ class TestOutputParser: def __init__(self, fname): self.test_entries = [] self.load_file(fname) def load_file(self, fname): self.contents = "" with open(fname, "r", encoding="utf8") as f: self.contents = f.read() if self.contents == "": print("Empty file {}".format(fname)) exit(-1) def run_parser(self): soup = BeautifulSoup(self.contents, "lxml") # Suite information suite = soup.find("suite") path = suite["source"] # TODO This might be an issue later on. In Unix-style paths the separator is a forward slash parts = path.split("\\") # Extract info for test entries self.api = parts[len(parts) - 2] self.robot_file = parts[len(parts) - 1] # Tests tests = soup.find_all("test") for test in tests: self.test_entries.append(self.create_test_entry(test)) # Write tests ew = ExcelWriter() for entry in self.test_entries: ew.write_test_entry(entry) ew.save() def create_test_entry(self, xml_obj): """ Takes the xml entry corresponding to the test from the output file, and returns a TestEntry object with the relevant information extracted. """ # retrieve ID and name id_raw = xml_obj.find("doc", recursive=False).contents mg = re.search(r"Test ID: ([0-9\.]*)$", id_raw[0].string, re.MULTILINE) test_id = mg.group(1) name = xml_obj["name"] #retrieve status and error message (if FAIL) statusObj = xml_obj.find("status", recursive=False) cts = statusObj.contents error_msg = cts[0] if len(cts) > 0 else "" result = statusObj["status"] return TestEntry(test_id, name, result, error_msg, self.api, self.robot_file) def display_usage(): print(usage_str) if __name__ == "__main__": usage_str = """ ===================================== Robot Test Reporter written in Python ===================================== Usage python parseTestResults.py output.xml where output.xml is the xml file generated by robot The command outputs to a new xlslx file if it does not exist, or appends to an existing one. """ parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') parser.add_argument('-o', dest='fname', action='store_const', default='testResults.xlsx', help='output file name (default: testResults.xlsx)') args = parser.parse_args() TestOutputParser(argv[1]).run_parser()
writeExcel.py +12 −11 Changes for writeExcel.py: 12 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ class ExcelWriter: self.wb = getWorkbook() self.ws = self.wb.active def getEntryWithId(self, id): def get_entry_with_id(self, id): """ When inserting an entry, it might be a test being re-run. In that case, the row containing that test needs to be updated, as opposed to appending Loading @@ -32,32 +32,33 @@ class ExcelWriter: return cell.row return -1 def getLastRow(self): def get_last_row(self): for cell in self.ws["A"]: if cell.value is None: return cell.row return cell.row + 1 def writeTestEntry(self, testEntry): existingEntryRow = self.getEntryWithId(testEntry.id) lastRow = self.getLastRow() def writeTestEntry(self, test_entry): existing_entry_row = self.get_entry_with_id(test_entry.id) last_row = self.get_last_row() # Use the above two values to pick a row entryRow = existingEntryRow if existingEntryRow != -1 else lastRow entry_row = existing_entry_row if existing_entry_row != -1 else last_row # Pick a cell color based on test outcome cellCol = ExcelWriter.PASS_COL if testEntry.result == "PASS" else ExcelWriter.FAIL_COL cell_col = ExcelWriter.PASS_COL if test_entry.result == "PASS" else ExcelWriter.FAIL_COL # Test entry as a list entryVals = testEntry.asList() entry_vals = test_entry.asList() for col, cellValue in zip(self.ws.iter_cols(min_row=entryRow, max_col=len(entryVals), max_row=entryRow), entryVals): for col, cell_vale in zip(self.ws.iter_cols(min_row=entry_row, max_col=len(entry_vals), max_row=entry_row), entry_vals): for cell in col: cell.value = cellValue cell.fill = PatternFill("solid", fgColor=cellCol)# cellCol cell.value = cell_vale cell.fill = PatternFill("solid", fgColor=cell_col)# cellCol def save(self): self.wb.save(filename = fname) def initWorkbook(wb): """ Writes column headers to ws Loading