Commit f96d26c5 authored by Frank Bryden's avatar Frank Bryden
Browse files

Barebones reporter which takes xml file and appends to excel file.

parents
Loading
Loading
Loading
Loading

parseTestResults.py

0 → 100644
+75 −0
Original line number Diff line number Diff line
from bs4 import BeautifulSoup
from sys import argv
from testEntry import TestEntry
from writeExcel import ExcelWriter
from sys import exit
import re

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.testEntries = []
        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")
        tests = soup.find_all("test")
        for test in tests:
            self.testEntries.append(createTestEntry(test))

        # Write tests
        ew = ExcelWriter()
        for entry in self.testEntries:
            ew.writeTestEntry(entry)
        ew.save()


def createTestEntry(xmlObj):
    # retrieve ID and name
    idRaw = xmlObj.find("doc", recursive=False).contents
    mg = re.search(r"Test ID: ([0-9\.]*)$", idRaw[0].string, re.MULTILINE)
    testId = mg.group(1)
    name = xmlObj["name"]

    #retrieve status and error message (if FAIL)
    statusObj = xmlObj.find("status", recursive=False)
    cts = statusObj.contents
    errorMsg = cts[0] if len(cts) > 0 else ""

    result = statusObj["status"]
    return TestEntry(testId, name, result, errorMsg)

def display_usage():
    print(usage_str)

if __name__ == "__main__":
    if len(argv) < 2:
        display_usage()
        exit()
    TestOutputParser(argv[1]).run_parser()
 No newline at end of file

testEntry.py

0 → 100644
+20 −0
Original line number Diff line number Diff line
class TestEntry:
    def __init__(self, id, name, result, errorMsg=""):
        self.id = id
        self.name = name
        self.result = result
        self.errorMsg = errorMsg
    
    def __str__(self):
        baseStr = "[{}] {}:{}".format(self.id, self.name, self.result)
        if self.errorMsg != "":
            return "{}: {}".format(baseStr, self.errorMsg)
        else:
            return baseStr
    
    def __repr__(self):
        return "{}: {}".format(self.name, self.result)
    
    def asList(self):
        return [self.id, self.name, self.result, self.errorMsg]
 No newline at end of file

writeExcel.py

0 → 100644
+60 −0
Original line number Diff line number Diff line
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font
from openpyxl.styles.fills import Stop, PatternFill

fname = 'testResults.xlsx'

class ExcelWriter:
    """
    Utility class which writes `TestEntry` objects to an excel file.
    Creates file if it does not exist.
    """
    PASS_COL = "00FF00"
    FAIL_COL = "FF0000"
    def __init__(self):
        self.wb = getWorkbook()
        self.ws = self.wb.active
    
    def getLastRow(self):
        for cell in self.ws["A"]:
            if cell.value is None:
                return cell.row
        return cell.row + 1
    
    def writeTestEntry(self, testEntry):
        lastRow = self.getLastRow()
        cellCol = ExcelWriter.PASS_COL if testEntry.result == "PASS" else ExcelWriter.FAIL_COL
        for col, cellValue in zip(self.ws.iter_cols(min_row=lastRow, max_col=4, max_row=lastRow), testEntry.asList()):
            for cell in col:
                cell.value = cellValue
                cell.fill = PatternFill("solid", fgColor=cellCol)# cellCol
        
    
    def save(self):
        self.wb.save(filename = fname)
def initWorkbook(wb):
    """
    Writes column headers to ws
    """
    headers = [("Test ID", 10), ("Test name", 80), ("Result", 6), ("Error Message", 100)]
    headerFont = Font(bold=True)
    ws = wb.active
    for col, header in zip(ws.iter_cols(min_row=1, max_col=4, max_row=1), headers):
        for cell in col:
            headerName = header[0]
            colsize = header[1]
            ws.column_dimensions[get_column_letter(cell.column)].width = colsize
            cell.value = headerName
            cell.font = headerFont


def getWorkbook():
    try:
        wb = load_workbook(filename = fname)
        return wb
    except FileNotFoundError:
        wb = Workbook()
        initWorkbook(wb)
        return wb
 No newline at end of file