栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

基于jacoco插件,使用python脚本分析java项目测试覆盖率。

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于jacoco插件,使用python脚本分析java项目测试覆盖率。

1. 需求分析: 1.1 功能描述
  1. 在java项目中要得出测试的覆盖率,使用jacoco插件,利用其生成的html文件进行解析。在脚本中生成一个以字符串形式构成的html格式的文件。
  2. 覆盖率以模块为单位进行表示,并且每一个模块中需要分析到包的覆盖率。
  3. 覆盖率的内容可以有全部,也可以用一部分,我这里选用了行,类,方法,并且对表示形式做了一些优化。
  4. 需要有邮件发送的功能,以及对邮箱格式检查的功能。
  5. 需要以参数的形式传入阈值,并且在脚本中分析每一模块是否达到标准。
2. 项目说明 2.1 前期准备 2.1.1 java依赖

因为是SpringBoot项目,并且使用了jacoco的插件,代码仓库顶层pom.xml里面加入如下maven依赖,子模块只需继承(parent)父pom即可。(1. 又学了maven一遍,层次结构,groupid,等)


    org.jacoco
    jacoco-maven-plugin
    0.8.7



    org.jacoco
    jacoco-maven-plugin
    0.8.6
    
        
            prepare-agent
            
                prepare-agent
            
        
        
            report
            test
            
                report
            
        
    



    org.apache.maven.plugins
    maven-surefire-plugin
    2.16
    
        false
        true
    

这里稍作解释:

  1. 加入了jacoco的依赖。
  2. 加了jacoco的运行插件。
  3. 加了org.apache.maven.plugins插件(我也不确定加不加)
    org.apache.maven.plugins的功能解释

顶层pom中需要使用标签管理同个项目中的各个模块。因为是根据项目中的来获取模块名称的。所以必须添加。
示例:

    
        modulename1
        modulename2
    
2.2 python执行准备

因为我们需要给脚本传入三个参数,所以需要运行脚本时显式的传入参数:

python Soup.py https://code.hwwt2.com/enterprise__helloworld/Test.git 1253324157@qq.com 65%
3.代码说明
import json
import sys
import random
import requests
import shutil
import re
import os
from bs4 import BeautifulSoup
#python接收命令行参数

#接收GITURL和邮箱地址
gitUrl = sys.argv[1]
email = sys.argv[2]
flag = sys.argv[3]
flag = float(flag.strip("%"))
codeDir = ""
ti = True
#生成随机的15字符目录
for i in range(15):
    num = random.randint(0,9)
    letter = chr(random.randint(97, 122))  # 取小写字母
    s = str(random.choice([num,letter]))
    codeDir += s

if('/' in codeDir):
    print("目录中有非法字符")
    sys.exit()

#验证邮箱格式
emails = email.split(";")
print(emails)
def check_email_url(email_address):
    # check '@'
    at_count = 0
    for element in email_address:
        if element == '@':
            at_count = at_count + 1

    if at_count != 1:
        return 0

    # check ' '
    for element in email_address:
        if element == ' ':
            return 0

    # check '.com'
    postfix = email_address[-4:]
    if postfix != '.com':
        return 0

    # check char
    for element in email_address:
        if element.isalpha() == False and element.isdigit() == False:
            if element != '.' and element != '@' and element != '_':
                return 0
    return 1

for e in emails:
    print(e)
    if(check_email_url(e) == 0):
        print("邮箱格式出错")
        sys.exit()

#拉取代码
os.system("git clone " + gitUrl + " " + codeDir)
os.system("cd " + codeDir + " && mvn test -Dmaven.test.failure.ignore=true && cd ../")
try:

    #先解析pom,拿到moduleList
    pom = open(codeDir + '/pom.xml').read()
    pomsoup = BeautifulSoup(pom,"xml")
    ps = pomsoup.find_all('module')
    moduleList = []
    for i in ps:
        moduleList.append(i.string)
    print(len(moduleList))
    number = len(moduleList)

    result = "

本次单元测试报告如下所示,请查阅。本报告以模块为单位展示单元测试覆盖率及报告,覆盖率阈值为 : "+ str(flag) + "%

" #对每一个模块的文件进行导入解析 for r in range(number): add = codeDir + '/' +moduleList[r] + "/target/site/jacoco/index.html" #add = i + "\target\site\jacoco\index.html" f = open(add).read() soup = BeautifulSoup(f, "html.parser") #解析模块名 moduleName = soup.find('h1').string result += '' +"模块名称:" + moduleName + '' #result += '
' result += '' #解析thead result += '' result += '' heads = soup.find('thead') #因为不需要前面几个元素,所以从第一个后进行一个截断 result += str(heads.find('td')) headTd = heads.find_all('td')[7:14] for td in range(3): result += '' result += '' result += '' #解析tbody result += '' body = soup.find('tbody') bodyTr = body.find_all('tr') for tds in bodyTr: result += '' result += str(tds.find('td')) tds = tds.find_all('td')[7:14] # for td1 in tds: # result += str(td1) for i in range(3): bodyNumber = tds[i*2].string bodyNumber1 = tds[i*2+1].string bodyResult = "{:.2%}".format((int(bodyNumber1) - int(bodyNumber)) / int(bodyNumber1)) result += '" result += '' result += '' #解析tfoot result += '' result += '' foot = soup.find('tfoot') result += str(foot.find('td')) footTd = foot.find_all('td')[7:14] #计算行覆盖率,并且判断是否达到标准 line = footTd[1].string missed = footTd[0].string fin = "{:.2%}".format((int(line) - int(missed)) / int(line)) res = float(fin.strip("%")) for td in range(3): tfootNumber = footTd[td*2].string tfootNumber1 = footTd[td*2+1].string tfootResult = "{:.2%}".format((int(tfootNumber1) - int(tfootNumber)) / int(tfootNumber1)) result += '" result += '' result += '' if(res < flag): result += '

' + "模块的行覆盖率:" + fin + " 未通过" +'' ti = False else: result += '' + "模块的行覆盖率:" + fin + " 通过" +'' result += '

' + headTd[td*2+1].string + ", %"+ '
' + str(bodyResult) + ' (' + str(int(bodyNumber1) - int(bodyNumber)) +'/' + bodyNumber1 + ")"+ "
' + str(tfootResult) + ' (' + str(int(tfootNumber1) - int(tfootNumber)) + '/' + tfootNumber1 + ")" + "
' result += '' #加入txt文件的内容 for root, dirs, files in os.walk(codeDir + '/' +moduleList[r] + "/target/surefire-reports/"): for f in files: if (os.path.join(root, f).__contains__(".txt") == True): file = os.path.join(root, f) for res in open(file,encoding='utf-8').readlines(): if (res.__contains__("Test set") or res.__contains__("<<< ERROR!") or res.__contains__("Tests run")): result += '' result += '
' + res + '
' result += '
' result += "" except Exception: shutil.rmtree(codeDir) print("已经删除了测试覆盖率报告相应的内容") #使用qq发送邮件 sent=smtplib.SMTP() sent.connect('smtp.qq.com',25) mail_name="" # 发送人邮箱地址 mail_password = "cqydsoobovdahghj" # 注意:这里不是密码,而应该填写授权码 sent.login(mail_name, mail_password) # 登陆 # 编辑邮件内容 #不知道为什么只有当MIMEText的第二个参数是plain的时候才有正文 to = [''] # 收件人邮箱地址 content = MIMEText(result, 'html', 'utf-8') # 正文内容 content['Subject'] = '代码测试覆盖率报告' # 邮件标题 content['From'] = mail_name # 发件人 content['To'] =','.join(to) #收件人,用逗号连接多个邮件,实现群发 try: sent.sendmail(mail_name, to, content.as_string()) #3个参数 发送人,收件人,邮件内容 print('Success') sent.close() except smtplib.SMTPException: print("Error:Fail") #邮件发送 url = "http://172.20.233.14:32433/mmpinterface/message/send_timely" print(len(result.encode())) result = json.dumps(result) title = "" if(ti == True): title = "【通过】 "+gitUrl+" 单元测试报告" else: title = "【未通过】 "+gitUrl+" 单元测试报告" ebody = { "appId":87, "channelCode":"callback", "msgContent":"{"target":"+json.dumps(email)+","title":"+json.dumps(title)+","lang":"cn","templateId":"","cc":"","content":"+result+"}", "msgType":1, "target": email, "templateCode":"" } r = requests.post(url=url, json=ebody, headers={'Content-Type':'application/json','Host':'msgservice.vip.tp.local'}) print(r.text) #删除目录 shutil.rmtree(codeDir) print("已经删除了测试覆盖率报告相应的内容")
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/973232.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号