通过 jenkins 去触发自动化测试,然后邮件发送测试结果。
看了一些教程,都是用 allure 命令生成的一个 html+js 之类的文件,然后打包,通过邮件发送附件。
这样太麻烦了,收到邮件的人想看结果每次都得下载压缩包,解压,再打开查看结果。
我想实现的是,发送邮件时在邮件正文里写一些简单的数据,比如成功多少,失败多少,然后再附上一个压缩包,里面有详细的结果。。。这样如果不想看详细结果的人就不用每次都下载附件再解压。活着说生成一个简单的 html,让人可以在附件里直接打开。
allure report 可以直接启动一个 web 服务而不是静态的 html 文件。 测试用例的执行情况都在 http 的接口里。 可以直接抓。 我们之前的做法是在 jenkins 的 share lib 里写了抓取 allure report 结果的脚本。 然后在 pipeline 里直接调用即可。代码如下:
import groovy.grape.Grape
/**
* Created by sungaofei on 19/3/1.
*/
@Grab(group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.7')
@Grab(group = 'org.jsoup', module = 'jsoup', version = '1.10.3')
import org.jsoup.Jsoup
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
import groovy.transform.Field
//可以指定maven仓库
//@GrabResolver(name = 'aliyun', root = 'http://maven.aliyun.com/nexus/content/groups/public/')
//加载数据库连接驱动包
//@Grab('mysql:mysql-connector-java:5.1.25')
//@GrabConfig(systemClassLoader=true)
//global variable
@Field jenkinsURL = "http://k8s.testing-studio.com:5003"
@Field int passed
@Field int failed
@Field int skipped
@Field int broken
@Field int unknown
@Field int total
@Field Map<String, Map<String, Integer>> map = new HashMap<>()
@NonCPS
def getResultFromAllure() {
def reportURL = "/job/DailyBuild/${BUILD_NUMBER}/allure/"
// if (env.BRANCH_NAME != "" && env.BRANCH_NAME != null) {
// reportURL = "http://k8s.testing-studio.com:5003/job/Daily%20Build/allure/"
// } else {
// reportURL = "/view/API/job/${JOB_NAME}/${BUILD_NUMBER}/allure/"
// }
// reportURL = "/view/API/job/sage-sdk-test/185/allure/"
println(jenkinsURL+"${reportURL}widgets/summary.json")
HTTPBuilder http = new HTTPBuilder("http://k8s.testing-studio.com:5003")
//根据responsedata中的Content-Type header,调用json解析器处理responsedata
http.get(path: "${reportURL}widgets/summary.json") { resp, json ->
println resp.status
passed = Integer.parseInt((String) json.statistic.passed)
failed = Integer.parseInt((String) json.statistic.failed)
skipped = Integer.parseInt((String) json.statistic.skipped)
broken = Integer.parseInt((String) json.statistic.broken)
unknown = Integer.parseInt((String) json.statistic.unknown)
total = Integer.parseInt((String) json.statistic.total)
}
}
def call() {
getResultFromAllure()
getDatabaseConnection(type: 'GLOBAL') {
// map.each { feature, valueMap ->
// def sqlString = "INSERT INTO func_test (name, build_id, feature, version, total, passed, unknown, skipped, failed, broken, create_time) VALUES ('${JOB_NAME}', '${BUILD_ID}', '${feature}', '${version}', " +
// "${valueMap['total']}, ${valueMap['passed']}, ${valueMap['unknown']}, ${valueMap['skipped']}, ${valueMap['failed']}, ${valueMap['broken']}, NOW())"
// println(sqlString)
//
// sql sql: sqlString
// }
// def lineCov = 0
// def branchCov = 0
// if (coverage != null && coverage != ""){
// lineCov = getLineCov()
// branchCov = getBranchCov() * 100
//
// }
def sqlString = "INSERT INTO func_test_summary (name, build_id, total, passed, unknown, skipped, failed, broken, create_time) VALUES ('${JOB_NAME}', '${BUILD_ID}', " +
"${total}, ${passed}, ${unknown}, ${skipped}, ${failed}, ${broken}, NOW())"
sql sql: sqlString
}
}
我以前用 jenkins-allure 插件 + 钉钉推送做的
jenkin 开启匿名模式,邮件附上 Jenkins 生成的 allure 报告地址?
在执行完用例之后,解析 allure 生成的 json 文件
def get_allure_result(self, path=f'{REPORT_PATH}/allure_results'):
"""
:param path: 存放allure运行json结果的文件夹
:return:
"""
result_list = [i for i in os.listdir(path) if '-result.json' in i]
allure_results = []
allure_dict = {}
for i in result_list:
json_data = self.read_json(os.path.join(path, i))
full_name = json_data.get("fullName")
labels = '_'.join([i.get('value', '') for i in json_data.get("labels") if
i.get('name', '') in ['feature', 'story']]) + "_" + json_data.get("name")
parameters = json_data.get("parameters", '') and '_'.join([i.get('value', '') for i in
json_data.get("parameters", '')])
statusDetails = json_data.get('statusDetails', '')
statusDetails1 = {
"message": "",
"trace": ""
}
if statusDetails:
try:
statusDetails1["message"] = statusDetails.get("message", "")
statusDetails1["trace"] = statusDetails.get("trace", "")
except Exception:
pass
data = {
"fullName": full_name,
"status": json_data.get("status"),
"labels": labels,
"duration": json_data.get("stop", 0) - json_data.get("start", 0),
"parameters": parameters,
"statusDetails": statusDetails1
}
if f'{full_name}_{parameters}' not in allure_dict:
allure_dict[f'{full_name}_{parameters}'] = [data]
else:
allure_dict[f'{full_name}_{parameters}'].append(data)
for v in allure_dict.values():
if len(v) == 1:
allure_results.append(v[0])
else:
for v1 in v:
if 'pass' in v1.get("status"):
allure_results.append(v1)
break
else:
allure_results.append(v[0])
return allure_results
我们 devops 的大佬的处理方法:在 pipeline 里面加一步,把生成的 allure report 截一个图放到邮件里,这样就能看到个大概了,满足了看邮件知道 pipeline 结果的需要;但是具体的信息,还是要通过链接去访问真正的 report
allure 本身就支持生成报告,最后的结果是 html 格式的。 一般生成报告都是集中存放,然后启动一个 httpserver,然后其他人只要拿到测试报告的地址,可以通过浏览器直接访问测试报告。
报告的地址可以在消息通知的时候推送出去,比如钉钉,企业微信,邮件等。 我们目前就是这么干的,很方便。
无需解析 allure 报告,我是这么做的
1、自动化框架执行完成,都会收集测试结果的,可以把这些结果作为测试结果推送的概览项;
2、使用 nginx、Tomcat 等代理 allure 报告,将 url 附到推送的结果中。
2、使用 nginx、Tomcat 等代理 allure 报告,将 url 附到推送的结果中。
这不是还得一台服务器吗?
去研究研究 pytest 的官方文档,conftest 里 pytest_runtest_makereport 这个方法不仅可以修改成失败截图,还能获取每个用例的测试结果,测试结果写入 mysql 或者 redis,所用用例执行完毕后再写个单个的 shell 去执行一个方法,从 mysql 或 redis 里取测试结果,并发送测试报告。