Python數據統計之禪道BUG統計且自動發送測試報告


項目參考文獻:https://testerhome.com/topics/6135

 

思路:

  • 1、讀取禪道數據庫數據及狀態,把各維度統計數據通過dic格式返回
  • 2、讀取數據通過pyecharts類,生成不同類型的報表HTML放入image_html文件中
  • 3、讀取image_html文件中本次生成的HTML並生成圖片,放入static文件中
  • 4、把圖片寫入HTML文件中,因為郵件正文是HTML格式
  • 5、文字及圖片HTML文件組合郵件正文,進行發送郵件
  • 6、上述功能對外提供服務接口,接口傳參為產品ID及項目ID,調取接口即可自動發送測試報告

 

主要用到pyecharts,os,flask,pymysql,yagmail等模塊,目前就是初步的小程序,后續再更新一版有界面,可自行選擇產品及項目,查看項目各維度情況報表,另外有些日志和異常處理還沒有完善

 

目錄結構:

 

 

主要代碼:

1、數據庫數據讀取

import pymysql
from  auto_report.o_util import spread,list_dic
from  auto_report.setting import db


#建立數據庫連接及執行
def connect_db(sql):
    conn = pymysql.connect( **db,charset='utf8',
                           autocommit=True)
    cur = conn.cursor()  # 建立游標
    sql = sql
    cur.execute(sql)
    r_result =spread(cur.fetchall())
    cur.close()
    conn.close()
    return r_result


#BUG狀態統計SQL封裝
def sql_pakeage(productid,projectid):

    bug_sql = "select count(*) from zt_bug where product='%d' and project='%d' and deleted='0'"% (
    productid, projectid)

    resolved_bug_sql = "select count(*) from zt_bug where product = '%d' and project='%d' and deleted = '0' and `status` = 'resolved' and resolution <> 'postponed' " % (
        productid, projectid)

    not_resolved_bug_sql = "select count(*) from zt_bug where product = '%d' and project='%d' and deleted = '0' and `status` =  'active' " % (
        productid, projectid)

    postponed_bug_sql = "select count(*) from zt_bug where product = '%d' and project='%d' and deleted = '0' and `status` <> 'closed' and resolution = 'postponed' " % (
        productid, projectid)

    closed_bug_sql = "select count(*) from zt_bug where product='%d'and project='%d' and deleted = '0' and `status` = 'closed' " % (
        productid, projectid)

    return  bug_sql,resolved_bug_sql,not_resolved_bug_sql,postponed_bug_sql,closed_bug_sql



#總的項目BUG情況統計
def  test_project_bug(productid,projectid):

    #總bug數
    all_bug=connect_db(sql_pakeage(productid,projectid)[0])

    #已解決bug數
    resolved_bug = connect_db(sql_pakeage(productid,projectid)[1])

    # 未解決BUG數(當前顯示BUG狀態為未解決的。包含當前還沒被解決的、之前遺留的未解決、以及reopen的BUG(累計數據))
    not_resolved_bug =  connect_db(sql_pakeage(productid,projectid)[2])

    # 延期BUG數
    postponed_bug= connect_db( sql_pakeage(productid,projectid)[3])

    # 已關閉BUG數
    closed_bug = connect_db(sql_pakeage(productid,projectid)[4])

    statistics_bug = { "總BUG數":all_bug[0],"已解決BUG": resolved_bug[0], "未解決BUG": not_resolved_bug[0], "已關閉BUG": closed_bug[0],
                      "延期解決BUG": postponed_bug[0]}

    return  statistics_bug



#未解決及待驗證BUG人均分布
def test_pepole_bug(productid,projectid):

    #未解決BUG分布sql
    not_resolved_sql="select assignedTo,count(*) from zt_bug where product = '%d' and project='%d' and deleted = '0' and `status` =  'active' and assignedTo <> 'closed'  group by assignedTo"%(productid,projectid)

    # 未解決BUG分布
    not_resolved_bug=connect_db(not_resolved_sql)


    return list_dic(not_resolved_bug)



#未解決BUG嚴重程度統計
def test_level_bug(productid,projectid):

     level_bug_sql="select severity,count(*) from zt_bug where product ='%d' and project='%d' and deleted = '0' and `status` =  'active' and assignedTo <> 'closed'  group by severity"%(productid,projectid)

     level_bug=connect_db(level_bug_sql)

     return list_dic(level_bug)


#已解決待驗證BUG分布
def test_verify_bug(productid,projectid):

       #已解決待驗證BUG分布sql
       not_verify_sql="select assignedTo,count(*) from zt_bug where product = '%d' and project='%d' and deleted = '0' and `status` ='resolved'  and resolution='fixed' group by assignedTo"%(productid,projectid)
       # 已解決待驗證BUG分布
       not_verify_bug = connect_db(not_verify_sql)

       return    list_dic(not_verify_bug)



#獲取項目名稱
def test_projectname(projectid):
    projectname="select `name` from zt_project where id='%d'"%(projectid)
    return connect_db(projectname)[0]



#驗證項目名稱及產品名稱是否存在及是對應關系
def test_product_verify(productid,projectid):
    if productid:
        p_sql = "select project from zt_projectproduct where product=%d" % productid
        projectlist=connect_db(p_sql)

        if projectid & projectid in projectlist:

            return True

        else:
            return False

    else:
        return False

2、生成報表,報表基類較簡單就不貼碼了

from auto_report.setting import html_path,ip,report_path
import os
from auto_report.o_table import charts
from  auto_report.o_data import test_level_bug,test_project_bug,test_pepole_bug,test_verify_bug

b_img=charts() #聲明圖表類

class create_report:

    #調取圖表方法,生成項目BUG狀態統計表生成
    def test_project_bug_html(self,productid,projectid,t_time):
        if test_project_bug(productid,projectid):
            b_img.p_render("項目BUG狀態統計情況表", test_project_bug,'test_project_bug',productid,projectid,t_time)
        else:
            return False

    # 調取圖表方法,生成開發人員待解決BUG統計情況表生成
    def test_pepole_bug_html(self,productid,projectid,t_time):
        if test_pepole_bug(productid,projectid):
            b_img.p_render("項目開發人員待解決BUG統計情況表", test_pepole_bug,'test_pepole_bug',productid,projectid,t_time)
        else:
            return False

    # 調取圖表方法,生成測試人員待驗證BUG統計情況表生成
    def test_verify_bug_html(self,productid,projectid,t_time):
        if test_verify_bug(productid,projectid):
            b_img.line_render("項目測試人員待驗證BUG統計情況表", test_verify_bug,'test_verify_bug',productid,projectid,t_time)
        else:
            return False

    # 調取圖表方法,生成未解決BUG嚴重程度統計情況表生成
    def test_level_bug_html(self,productid,projectid,t_time):
        if test_level_bug(productid,projectid):
            b_img.pie_render("項目未解決BUG嚴重程度統計情況表", test_level_bug,'test_level_bug',productid,projectid,t_time)
        else:
            return False

    #獲取HTML文件中文件,且生成圖片
    def html_image(self,html_file_list):

        if html_file_list:
            for filename in html_file_list:
                self.new_filename=filename.replace('.html','')
                b_img.p_image(os.path.join(html_path,filename),self.new_filename)
        else:
            return False

    #獲取圖片文件中的圖片,且生成report文件
    def img_report(self,img_file_list):
        if img_file_list:
            for img in img_file_list:
                self.f=open(report_path,"a+",encoding='utf-8')
                html='''<div><img src="%s/static/%s"></div>'''%(ip,img)
                self.f.write(html)
                self.f.close()
        else:
            return False

3、郵件發送

import yagmail
import traceback
from auto_report.setting import mail_info,to,cc,log
from auto_report.o_data import sql_pakeage,test_projectname,connect_db
from auto_report.o_util import read_file


#發送郵件
def send_mail(productid,projectid):

    bug_sql=sql_pakeage(productid,projectid)

    bug_num=[]

    for sql in bug_sql:
        bug_num.append(int(connect_db(sql)[0]))

    project_name=test_projectname(projectid)

    subject="%s項目測試報告"%project_name

    str='''<div style="color:#000; font-size: 14px;font-family: arial;"> <span style="font-family: 微軟雅黑, Microsoft YaHei; font-size: 16px;">大家好:</span></div><div style="color:#000; font-size: 14px;font-family: arial;">
    <span style="font-family: 微軟雅黑, Microsoft YaHei; font-size: 16px;">
    &nbsp;&nbsp;&nbsp;&nbsp;​&nbsp;&nbsp;&nbsp;&nbsp;​&nbsp;&nbsp;&nbsp;&nbsp;​%s項目,目前存在%s個BUG,已解決狀態%s個BUG,未解決狀態%s個BUG,延期處理狀態%s個BUG,已關閉狀態%s個BUG;請對應開發注意查收及修改自己名下的BUG。</span></div><div style="color:#000; 
    font-size: 14px;font-family: arial;"><br></div><div style="color:#000; font-size: 14px;font-family: arial;">
    <span style="font-family: 微軟雅黑, Microsoft YaHei; font-size: 16px;">​各維度測試情況統計如下圖:</span><div><br></div></div>'''%(project_name,bug_num[0],bug_num[1],bug_num[2],bug_num[3],bug_num[4])


    file_content=read_file("./report.html")

    content=str+file_content


    try:
        mail = yagmail.SMTP(**mail_info)  # 解包方式傳入參數
        mail.send(to=to, cc=cc, subject=subject, contents=content)  # 發送郵件

    except Exception as e:
        log.error("發送郵件出錯了,錯誤信息是:\n%s" % traceback.format_exc())  # 捕獲錯誤信息

    else:
        log.info("發送郵件成功")  # 發送成功日志

4、接口服務文件

from auto_report.o_mail import send_mail
from auto_report.o_report import create_report
from auto_report.setting import html_path,image_path,report_path
import os,time
from auto_report.o_data import test_product_verify
from auto_report.o_util import clear,file_list
import flask
import json

report=create_report()


server=flask.Flask(__name__) #當前Python為一個服務

@server.route("/report") #get請求,且連接帶參數
def table_data():

    productid=int(flask.request.args.get("productid")) #獲取參數產品ID
    projectid = int(flask.request.args.get("projectid")) #獲取參數項目ID

    t_time = str(int(time.time())) #獲取當前時間戳,作為本次文件的唯一標識

    #判斷產品及項目輸入是否正確
    if test_product_verify(productid, projectid):

        report.test_project_bug_html(productid, projectid, t_time) #項目BUG狀態統計表生成
        report.test_level_bug_html(productid, projectid,t_time) #項目BUG待解決BUG嚴重程度統計表生成
        report.test_pepole_bug_html(productid, projectid, t_time) #項目待解決BUG人員分布統計表生成
        report.test_verify_bug_html(productid, projectid, t_time) #項目已解決待驗證BUG人員分布統計表成

        #生成的圖表HTML轉圖片
        html_file_list = file_list(html_path,t_time)
        report.html_image(html_file_list)

        #圖片組成報告
        img_file_list = file_list(image_path,t_time)
        report.img_report(img_file_list)

        #發送報告
        send_mail(productid,projectid)

        data = {"code": 200, "msg": "發送成功"}

        #清除本次報告report.html頁面產生的數據
        clear(report_path)


    else:
        data={"code":-2,"msg":"參數錯誤"} #接口傳參錯誤

    return  json.dumps(data,ensure_ascii=False) #返回JSON格式

server.run(host="0.0.0.0",port=5000,debug=True) #啟動服務命令

運行效果:

 

 

 

 

 備注:忽略內容啊,測試隨意寫的文字,文字可自行修改,哈哈哈哈

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM