HTMLTestRunner_Chart 包含曆史結果的測試報告

python
Windows
點點 · 2018年09月25日 · 1167 次閱讀 · 5 條評論

HTMLTestRunner_Chart 基于unittest的測試報告,使用詳情見demo

GitHub: # 歡迎star
參考鍊接:
#
#

優化報告内容

  1. 測試報告中文顯示,優化一些斷言失敗正文亂碼問題
  2. 新增錯誤和失敗截圖,展示到html報告裡
  3. 增加餅圖統計
  4. 失敗後重試功能
  5. 保存近10次測試結果,并通過柱狀圖展示
  6. 切換測試日期,展示曆史測試結果
  7. 兼容python2.x 和3.x

注意:

  1. 在是python3.x 中,如果在這裡setUp裡初始化driver ,因為3.x版本 unittest 運行機制不同,會導緻用力失敗時截圖失敗,目前隻有采用捕獲異常來截圖,或者在setUpClass裡初始化driver
  2. driver初始化變量名必須命名為driver

報告首頁:

用例截圖:

失敗餅圖:

曆史走勢:

失敗重試:

  1. 生成報告的參數裡面加了一個參數retry=1,這個表示用例失敗後,會重新跑一次。

    if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(case_01)
    runner = HTMLTestRunner(
    title="帶截圖,餅圖,折線圖,曆史結果查看的測試報告",
    description="",
    stream=open("./demo.html", "wb"),
    verbosity=2,
    retry=0,
    save_last_try=True)
    runner.run(suite)

    保存測試結果到json文件:

    def mkdir_json(self):
    is_exists = os.path.exists(self.path)
    # 判斷結果
    if not is_exists:
    try:
    # 如果不存在則創建目錄
    # 創建目錄操作函數
    with open(self.path, "w+") as f:
    f.write("var data = []")
    return True
    except Exception as e:
    print(e)
    return False
    else:
    return True

    def Write(self, title, heading, desc, data):
    try:
    with open(self.path, "r+") as f:
    all_data = f.read().split(" = ", 1)
    data_json = all_data[1]
    data_json = eval(data_json)
    if len(data_json) >= 10:
    del data_json[0]
    description = dict()
    description["startTime"] = heading[0][1]
    description["duration"] = heading[1][1]
    if PY3K:
    description["title"] = title
    description["status"] = heading[2][1]
    description["desc"] = desc
    description["data"] = data
    status = heading[2][1].split(" ")
    for j in range(0, len(status)):
    if status[j] == "通過":
    description["success"] = str(status[j + 1])
    if status[j] == "失敗":
    description["fail"] = str(status[j + 1])
    if status[j] == "錯誤":
    description["error"] = str(status[j + 1])
    else:
    description["title"] = title.encode("gbk")
    description["status"] = heading[2][1].encode("gbk")
    description["desc"] = desc.encode("gbk")
    description["data"] = data.encode("gbk")
    status = heading[2][1].split(" ")
    for j in range(0, len(status)):
    if status[j] == u"通過":
    description["success"] = str(status[j + 1])
    if status[j] == u"失敗":
    description["fail"] = str(status[j + 1])
    if status[j] == u"錯誤":
    description["error"] = str(status[j + 1])
    data_json.append(description)
    data_json = str(data_json)
    f.seek(0)
    f.truncate()
    f.write(str("var data = " + data_json))
    except IndexError:
    sys.stderr.write("JSON初始化内容有誤! 初始化内容’var data = []‘")

    錯誤/失敗截圖,修改addError和addFail函數:

    def addFailure(self, test, err):
    self.failure_count += 1
    self.status = 1
    TestResult.addFailure(self, test, err)
    _, _exc_str = self.failures[-1]
    output = self.complete_output()
    self.result.append((1, test, output, _exc_str))
    if not getattr(test, "driver",""):
    pass
    else:
    try:
    driver = getattr(test, "driver")
    test.imgs.append(driver.get_screenshot_as_base64())
    except Exception as e:
    pass
    if self.verbosity > 1:
    sys.stderr.write('F ')
    sys.stderr.write(str(test))
    sys.stderr.write('\n')
    else:
    sys.stderr.write('F')

    錯誤重試,修改stopTest函數:

    def stopTest(self, test):
    # Usually one of addSuccess, addError or addFailure would have been called.
    # But there are some path in unittest that would bypass this.
    # We must disconnect stdout in stopTest(), which is guaranteed to be called.
    if self.retry:
    if self.status == 1:
    self.trys += 1
    if self.trys <= self.retry:
    if self.save_last_try:
    t = self.result.pop(-1)
    if t[0]==1:
    self.failure_count-=1
    else:
    self.error_count -= 1
    test=copy.copy(test)
    sys.stderr.write("Retesting... ")
    sys.stderr.write(str(test))
    sys.stderr.write('..%d \n' % self.trys)
    doc = test._testMethodDoc or ''
    if doc.find('_retry')!=-1:
    doc = doc[:doc.find('_retry')]
    desc ="%s_retry:%d" %(doc, self.trys)
    if not PY3K:
    if isinstance(desc, str):
    desc = desc.decode("utf-8")
    test._testMethodDoc = desc
    test(self)
    else:
    self.status = 0
    self.trys = 0
    self.complete_output()

    HTML模闆導入JSON曆史結果,如果JSON出現錯誤,則曆史結果和走勢圖錯誤:

    <head>
    <title>%(title)s</title>
    <meta name="generator" content="%(generator)s"/>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <script type="text/javascript" src="%(jsonpath)s" charset="gbk"></script>
    <link href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/echarts/3.8.5/echarts.common.min.js"></script>
    <!-- <script type="text/javascript" src="js/echarts.common.min.js"></script> -->

    %(stylesheet)s

評論列表
永遠的點點點 發表于 2018年09月25日

路過

PEPSI 發表于 2018年09月27日

不錯~

simple 發表于 2019年06月20日

感謝樓主分享,歡迎大家star

陳子昂 發表于 2019年06月24日

不錯,star了

cloud 發表于 2019年07月10日

感謝分享,必須star一下

http://m.juhua446633.cn|http://wap.juhua446633.cn|http://www.juhua446633.cn||http://juhua446633.cn