美文网首页
2019-08-19

2019-08-19

作者: 独角戏_5171 | 来源:发表于2019-08-19 11:09 被阅读0次

[cp]如何自己实现一个HTMLRunner

在使用unittest框架时,我们常常需要下载一个HTMLRunnerCN.py用来生成HTML格式的报告,那么我们能不能自己实现一个呢?

HTMLRunner是模仿unittest自带的TextTestRunner()实现的,我们先来看看TextTestRunner()的运行流程。

TextTestRunner使用方法

import unittest

suite = unittest.defaultTestLoader.discover("./")

with open("report.txt", "w") as f:  # 将运行结果保存为txt文件

    unittest.TextTestRunner().run(suite)

运行流程

        1.TextTestRunner 内部实现了一个TextTestResult(继承自unittest.TestResult类)来记录测试结果

        2.TextTestRunner().run()实际调用suite(result)既suite.run(result) (result用来记录结果)

        3.suite.run(result)会遍历suite中的用例,依次调用case(result)既case.run(result)

        4.case.run(result)时,首先会调用result.testRun+=1然后执行用例方法testMethod(), 如果用例失败、出错、跳过则用例会分别调用result.addSuccess(),result.addFailure()等方法,在对应的result.failures,result.errors列表中添加用例信息,默认成功用例result中不处理

        5.运行完返回result(测试结果对象)

unittest.TextTestRunner和网上的HTMLRunner都是基于stream流去写的文件,每执行一条用例,把对应的结果和信息写到流中,最后输出成文件,这种方法需要很多的细节控制,比较复杂。

我们可以采用解析执行完返回result结果,通过Jinjia2模板引擎渲染,将数据渲染到模板里,形成报告文件。

Jinjia2是一个三方包,可以将模板代码中的{{变量名}}等占位符将变量值渲染进去,支持循环和if判断。安装方法pip install jinjia2

实现步骤

1.首先我们要写个模板

TPL = '''

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="UTF-8">

        <title>{{title}}</title>

    </head>

    <body>

        <h2>{{title}}</h2>

        <h3>{{description}}</h3>

        <br/>

        <table border="1">

            {% for case in cases %}

            <tr>

                <td>{{case.name}}</td>

                <td>{{case.status}}</td>

                <td>{{case.exec_info}}</td>

            </tr>

            {% endfor %}

        </table>

    </body>

</html>

'''

            1.{{title}},{{description}}能将传入的数据中的相应的变量值填充进去

            2.{% for case in cases%} ...{% endfor %}遍历cases列表中每一个用例数据,每个生成一个表格行(<tr>...</tr>)

2.自定义一个Result类

由于默认的TestResult()将各种状态的用例分散存的,我们可以自定义一个Result类来处理用例成功、失败、出错执行的操作

class Result(unittest.TestResult):

    def __init__(self):

        super().__init__()

        self.cases = []

    def addSuccess(self, test):

        self.cases.append({"name": test.id(), "status": "pass", "exec_info": ""})

    def addError(self, test, exec_info):

        self.cases.append({"name": test.id(), "status": "error",

                            "exec_info": self._exc_info_to_string(exec_info, test)

                          .replace("\n", "<br/>")})

    def addFailure(self, test, exec_info):

        self.cases.append({"name": test.id(), "status": "fail",

                            "exec_info": self._exc_info_to_string(exec_info, test)

                          .replace("\n", "<br/>")})

    def addSkip(self, test, reason):

        self.cases.append({"name": test.id(), "status": "skip", "exec_info": reason))

          1.addSuccess等方法对应用例成功或其他状态时在result结果中的操作

          2._exec_info_to_string: 默认用例传过来的exec_info是Trackback对象

,需要转换为字符串,replace将\n转为网页的换行<br/>

3.实现我们的HTMLRunner

class HTMLRunner(object):

    def __init__(self, output, title="Test Report", description=""):

        self.file = output

        self.title = title

        self.description = description

    def run(self, suite):

        result = Result()  # 用于保存测试结果

        suite(result)  # 执行测试

        # 渲染数据到模板

        content = Template(TPL).render({"title": self.title,

                                        "description": self.description,

                                        "cases": result.cases})

        with open(self.file, "w") as f:

            f.write(content)  # 写入文件

        return result

使用方法(自己准备几条用例)

suite = unittest.defaultTestLoader.discover("./")

HTMLRunner(output="report.html",

          title="测试报告",

          description="测试报告描述").run(suite)

生成的测试报告(如图

2019-08-19 2019-08-19

)

相关文章

网友评论

      本文标题:2019-08-19

      本文链接:https://www.haomeiwen.com/subject/omcssctx.html