RobotFramework测试用例的自行解析

2018-12-08  本文已影响0人  麦卡鲁

RobotFramework框架提供了很多有用的开放API供我们使用,具体可以参考RobotFramework官方网站开放API

其中,下面的类和方法是比较常用的:

下面是一个根据RobotFramework测试运行结果的XML文件解析RobotFramework测试用例数据的示例代码:

from xml.etree import ElementTree as xet
import numpy as np
import pandas as pd
import pylab
import os
from datetime import datetime
import matplotlib
matplotlib.use("Agg")

from matplotlib import pyplot as plt

if os.name == 'posix':
    matplotlib.rcParams['font.sans-serif'] = ['SimHei']
if os.name == 'nt':
    matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
plt.rcParams['savefig.dpi'] = 200
plt.rcParams['figure.dpi'] = 200


def plot_pie(sizes, labels, title, explode, file_name_to_save):

    fig, ax = plt.subplots()
    ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=0)
    ax.axis('equal')
    plt.title(title, fontsize=20, fontweight='bold')
    plt.legend()
    plt.savefig(file_name_to_save, dpi=200)


def plot_bar(cat1, cat2, labels, xlabel, ylabel, title, max_y, filename, width=0.35):
    cat1 = cat1
    cat2 = cat2
    labels = labels
    x = np.arange(len(cat1))
    plt.bar(x, height=cat1, width=width, alpha=0.8, color="green", label="Passed")
    plt.bar(x, height=cat2, width=width, color="red", label="Failed", bottom=cat1)

    plt.ylim(0, max_y)

    plt.ylabel(xlabel)
    plt.xlabel(ylabel)

    plt.xticks(x, labels)
    pylab.xticks(rotation=45)

    plt.title(title)
    plt.legend()
    plt.savefig(filename, dpi=200)


def parse_rfoutput_total(root):
    for sub_child in root:
        if sub_child.text == "Critical Tests":
            labels = "Passed", "Failed"
            sizes = [sub_child.attrib['pass'], sub_child.attrib['fail']]
            explode = (0, 0.2)
            title = "Critical Tests Execute Result"
            filename = "./statistics/Critical_Tests_info.png"
            plot_pie(sizes, labels=labels, title=title, explode=explode, file_name_to_save=filename)

        if sub_child.text == "All Tests":
            labels = "Passed", "Failed"
            sizes = [sub_child.attrib['pass'], sub_child.attrib['fail']]
            explode = (0, 0.2)
            title = "All Tests Execute Result"
            filename = "./statistics/All_Tests_info.png"
            plot_pie(sizes, labels=labels, title=title, explode=explode, file_name_to_save=filename)


def parse_statistics_by_suite(root):
    labels = list()
    passed = list()
    failed = list()
    max_num = list()
    for sub_child in root:
        labels.append(sub_child.text)
        passed.append(int(sub_child.attrib['pass']))
        failed.append(int(sub_child.attrib['fail']))
        max_num.append(int(sub_child.attrib['pass']) + int(sub_child.attrib['fail']))
    print(max_num)
    plot_bar(cat1=passed, cat2=failed,
             labels=labels,
             xlabel="测试套件", ylabel="用例数量",
             title="Statistic By Suite", max_y=max(max_num),
             filename="./statistics/Statistic_By_Suite.png"
             )


def parse_statistic_by_casetags(root):
    labels = list()
    passed = list()
    failed = list()
    max_num = list()
    for sub_child in root:
        labels.append(sub_child.text)
        passed.append(int(sub_child.attrib['pass']))
        failed.append(int(sub_child.attrib['fail']))
        max_num.append(int(sub_child.attrib['pass']) + int(sub_child.attrib['fail']))
    print(max_num)
    plot_bar(cat1=passed, cat2=failed,
             labels=labels,
             xlabel="TestCase Tag", ylabel="Case Number",
             title="Statistic By Tag", max_y=max(max_num),
             filename="./statistics/Statistic_By_Tag.png"
             )


def parse_statistics_info(root):
    for child in root:
        if child.tag == "total":
            parse_rfoutput_total(child)

        if child.tag == "tag":
            parse_statistic_by_casetags(child)

        if child.tag == "suite":
            parse_statistics_by_suite(child)


def parse_testcase_tree(root):
    case_info = {
        'CaseId': root.attrib['id'],
        'CaseName': root.attrib['name'],
        'CaseTags': set(),
        'CaseStatus': None,
        'CaseStartTime': None,
        'CaseEndTime': None,
        'CaseElapsedTime': None
    }

    for child in root:
        if child.tag == "tags":
            for sub in child:
                case_info['CaseTags'].add(sub.text.strip())
        if child.tag == "status":
            case_info['CaseStatus'] = child.attrib['status']
            case_info['CaseStartTime'] = child.attrib['starttime']
            case_info['CaseEndTime'] = child.attrib['endtime']

            case_running_elapsed_time = datetime.strptime(
                case_info['CaseEndTime'], "%Y%m%d %H:%M:%S.%f"
            ) - datetime.strptime(
                case_info['CaseStartTime'], "%Y%m%d %H:%M:%S.%f"
            )
            case_info['CaseElapsedTime'] = case_running_elapsed_time.total_seconds()

    return case_info


def parse_rf_output(root, testcasetable):
    if root.tag == 'test':
        testcasetable.append(parse_testcase_tree(root))
    elif root.tag == "statistics":
        parse_statistics_info(root)
    else:
        for child in root:
            parse_rf_output(child, testcasetable)


def get_latest_test_run_ouput(sourcedir='../TestResult/', sort_by='ctime'):
    if os.path.isdir(sourcedir):
        if len(os.listdir(sourcedir)) == 0:
            raise FileNotFoundError("指定的目录中没有文件。")
        else:
            os.chdir(sourcedir)
            files = [file for file in os.listdir(sourcedir) if \
                     file.startswith('output_') and file.endswith('.xml')]
            if sort_by == 'ctime':
                files.sort(
                    key=lambda f: os.path.getctime(sourcedir + os.sep + f)
                )
            elif sort_by == 'atime':
                files.sort(
                    key=lambda f: os.path.getatime(sourcedir + os.sep + f)
                )
            elif sort_by == 'mtime':
                files.sort(
                    key=lambda f: os.path.getmtime(sourcedir + os.sep + f)
                )
            else:
                raise ValueError("排序方式不正确。")
            return files[-1]
    else:
        raise NotADirectoryError("无此目录。")


if __name__ == '__main__':
    testcasetable = list()
    # file = get_latest_test_run_ouput(sourcedir="../TestResult")
    xmltree = xet.parse("./output_183.xml")
    root = xmltree.getroot()
    parse_rf_output(root, testcasetable)
    dt = pd.DataFrame(testcasetable)
    dt.to_excel("./statistics/testcases.xlsx")
上一篇 下一篇

猜你喜欢

热点阅读