Skip to content
parseTestResults.py 2.5 KiB
Newer Older
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")

        # 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.robotFile = parts[len(parts) - 1]

        # Tests
        tests = soup.find_all("test")
        for test in tests:
            self.testEntries.append(self.createTestEntry(test))

        # Write tests
        ew = ExcelWriter()
        for entry in self.testEntries:
            ew.writeTestEntry(entry)
        ew.save()
    
    def createTestEntry(self, xmlObj):
        """
        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
        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, self.api, self.robotFile)
    
def display_usage():
    print(usage_str)

if __name__ == "__main__":
    if len(argv) < 2:
        display_usage()
        exit()
    TestOutputParser(argv[1]).run_parser()