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

Pylint accepts all files....for now.

parent 82bbded9
Loading
Loading
Loading
Loading

.gitignore

0 → 100644
+3 −0
Original line number Diff line number Diff line
*.xlsx
__pycache__/
.vscode/
 No newline at end of file

parseTestResults.py

deleted100644 → 0
+0 −88
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")

        # 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()
 No newline at end of file
+48 −61
Original line number Diff line number Diff line
from bs4 import BeautifulSoup
from sys import argv
from testEntry import TestEntry
from writeExcel import ExcelWriter
"""
Tool entry point
"""

import sys
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
from bs4 import BeautifulSoup
from test_entry import TestEntry
from write_excel import ExcelWriter


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):
    """
    Parser taking a file name (of the XML output from robot),
    and extracts relevant information, eventually creating a list
    of TestEntry objects
    """
    def __init__(self, input_file, output_file):
        self.test_entries = []
        self.load_file(fname)
        self.load_file(input_file)
        self.api = ""
        self.output_file = output_file
        self.robot_file_contents = ""

    def load_file(self, fname):
        self.contents = ""
        """
        Load xml file
        """

        with open(fname, "r", encoding="utf8") as f:
            self.contents = f.read()
        with open(fname, "r", encoding="utf8") as robot_file:
            self.robot_file_contents = robot_file.read()

        if self.contents == "":
        if self.robot_file_contents == "":
            print("Empty file {}".format(fname))
            exit(-1)
            sys.exit(-1)

    def run_parser(self):
        soup = BeautifulSoup(self.contents, "lxml")
        """
        Run parser, extracting all info to create the test entries
        """
        soup = BeautifulSoup(self.robot_file_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]
        self.robot_file_contents = parts[len(parts) - 1]

        # Tests
        tests = soup.find_all("test")
@@ -54,10 +57,10 @@ class TestOutputParser:
            self.test_entries.append(self.create_test_entry(test))

        # Write tests
        ew = ExcelWriter()
        excel_writer = ExcelWriter(self.output_file)
        for entry in self.test_entries:
            ew.write_test_entry(entry)
        ew.save()
            excel_writer.write_test_entry(entry)
        excel_writer.save()

    def create_test_entry(self, xml_obj):
        """
@@ -66,44 +69,28 @@ class TestOutputParser:
        """
        # 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)
        match_group = re.search(r"Test ID: ([0-9\.]*)$", id_raw[0].string, re.MULTILINE)
        test_id = match_group.group(1)
        name = xml_obj["name"]

        #retrieve status and error message (if FAIL)
        statusObj = xml_obj.find("status", recursive=False)
        cts = statusObj.contents
        status_obj = xml_obj.find("status", recursive=False)
        cts = status_obj.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)
        result = status_obj["status"]
        return TestEntry(test_id, name, (result, error_msg), (self.api, self.robot_file_contents))

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',
    parser = argparse.ArgumentParser(description='Robot Test Reporter written in Python.\n'
                                                 'Produces an xlsx file from a robot XML '
                                                 'output file.\n'
                                                 'The command outputs to a new xlslx file if it '
                                                 'does not exist, or appends to an existing one.')
    parser.add_argument('input_file', help='XML file generated by Robot')
    parser.add_argument('-o', dest='output_file', default='testResults.xlsx',
                        help='output file name (default: testResults.xlsx)')

    args = parser.parse_args()

    TestOutputParser(argv[1]).run_parser()
    TestOutputParser(args.input_file, args.output_file).run_parser()

testEntry.py

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

test_entry.py

0 → 100644
+38 −0
Original line number Diff line number Diff line
"""
Contains utility class `TestEntry`
"""

class TestEntry:
    """
    Models a single entry (row) in the resulting xlsx file.

    Contains all the relevant information about a single test:
        id:             Test ID
        name:           Test Name
        result:         PASS/FAIL
        error_message:  In case of FAIL, contains reason
        robot_file:     Robot file containing the test
    """
    def __init__(self, test_id, name, status, test_info):
        self.test_id = test_id
        self.name = name
        self.result = status[0]
        self.error_message = status[1]
        self.api = test_info[0]
        self.robot_file = test_info[1]

    def __str__(self):
        base_str = "[{}] {}:{}".format(self.test_id, self.name, self.result)
        if self.error_message != "":
            return "{}: {} ({}/{})".format(base_str, self.error_message, self.api, self.robot_file)

        return base_str

    def __repr__(self):
        return "{}: {}".format(self.name, self.result)

    def as_list(self):
        """
        Construct a list-representation of the entry
        """
        return [self.test_id, self.name, self.result, self.error_message, self.api, self.robot_file]
Loading