当前位置: 首页 > news >正文

自动化测试报告优化:jenkins+jmeter定制化HTML报告生成

为什么需要定制化报告?

JMeter生成的HTML报告虽然功能完善,但关键信息不突出、展示不直观

如何实现

编写一个符合预期的shell脚本,在jenkins中通过shell步骤执行shell脚本来生成定制化html报告,后续可以通过归档至主节点,来进行展示等

shell脚本逻辑流程图:

在这里插入图片描述

shell脚本:

#!/bin/bash# 【配置区】与 Jenkins HTML Publisher 配置对齐
# 工作空间根路径
WORKSPACE="/work/jenkins/workspace/Automated-testing/AgentJmeter-PublicAgent-release"  # JMeter 相关路径
JMETER_JMX="$WORKSPACE/PublicAgent-release.jmx"       # 测试计划文件
JTL_FILE="$WORKSPACE/PublicAgent-release.jtl"  # JMeter 结果文件
HTML_REPORT_DIR="$WORKSPACE/html_report"  # JMeter 默认 HTML 报告输出目录  # 自定义报告路径(与 HTML Publisher 配置一致)
CUSTOM_REPORT_DIR="$WORKSPACE/result_html"  
CUSTOM_HTML="$CUSTOM_REPORT_DIR/resultTotal.html"  # 索引页:resultTotal.html  # JTL 文件字段列号(从 1 开始,与实际 JTL 表头严格对齐)
SUCCESS_COL=8        # success 字段所在列(第 8 列)
AGENT_NAME_COL=6     # 智能体名称所在列(threadName 列,第 6 列)
RESPONSE_MSG_COL=5   # responseMessage 字段所在列(第 5 列)
FAILURE_MSG_COL=9    # failureMessage 字段所在列(第 9 列)  # 成功/失败标识值
SUCCESS_VALUE="true"
FAILURE_VALUE="false"  # 【函数区】模块化封装核心逻辑
# 1. 日志打印函数(带时间戳,便于调试)
log() {echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}# 2. 清理旧文件/目录(健壮性处理:rm -rf 避免目录不存在报错)
clean_old_resources() {log "开始清理旧文件/目录..."rm -rf "$HTML_REPORT_DIR"/*   # 清理 JMeter 默认报告rm -rf "$JTL_FILE"            # 清理旧 JTL 文件rm -rf "$CUSTOM_REPORT_DIR"   # 强制删除自定义报告目录(无则忽略)mkdir -p "$CUSTOM_REPORT_DIR" # 重建自定义报告目录(确保父目录存在)log "旧文件/目录清理完成"
}# 3. 运行 JMeter 生成测试结果 + 默认 HTML 报告
run_jmeter_test() {log "开始运行 JMeter 测试..."jmeter -n -t "$JMETER_JMX" \-l "$JTL_FILE" \-e \-o "$HTML_REPORT_DIR"# 检查 JMeter 执行返回码(非 0 则失败)if [ $? -ne 0 ]; thenlog "× JMeter 执行失败,脚本终止"exit 1filog "JMeter 测试执行完成,JTL 和默认报告已生成"
}# 4. 解析 JTL 统计成功/失败数(处理多行字段)
parse_jtl_summary() {log "开始解析 JTL 统计成功/失败数..."# 使用 awk 解析 JTL,注意分隔符和引号处理local result=$(awk -v FPAT='([^,]*)|("[^"]*")' -v s_col="$SUCCESS_COL" -v s_val="$SUCCESS_VALUE" -v f_val="$FAILURE_VALUE" 'NR > 1 {gsub(/^"|"$/, "", $s_col);  # 移除字段前后引号(JTL 带引号时保留)if ($s_col == s_val) count_success++else if ($s_col == f_val) count_failure++}END {print count_success+0, count_failure+0  # 强制转数字,避免空值}' "$JTL_FILE")# 新增调试日志,查看 awk 输出log "DEBUG: awk 返回的 success/failure 数: [$result]"  # 按空格分割 awk 输出(awk 用 print 输出时默认空格分隔)IFS=' ' read -r SUCCESS_COUNT FAILURE_COUNT <<< "$result"  # 计算总数(此时 SUCCESS_COUNT/FAILURE_COUNT 应为纯数字)TOTAL_COUNT=$((SUCCESS_COUNT + FAILURE_COUNT))log "成功数: $SUCCESS_COUNT, 失败数: $FAILURE_COUNT, 总数: $TOTAL_COUNT"
}# 5. 计算成功率
calculate_success_rate() {log "计算成功率..."if [ "$TOTAL_COUNT" -eq 0 ]; thenSUCCESS_RATE="0.00"elseSUCCESS_RATE=$(awk -v s="$SUCCESS_COUNT" -v t="$TOTAL_COUNT" 'BEGIN { printf "%.2f", (s/t)*100 }')filog "成功率: $SUCCESS_RATE%"
}# 6. 提取失败详情
parse_failure_details() {awk -v FPAT='([^,]*)|("[^"]*")' -v s_col="$SUCCESS_COL" -v f_val="$FAILURE_VALUE" -v agent_col="$AGENT_NAME_COL" -v msg_col="$FAILURE_MSG_COL" 'NR == 1 { next }  # 跳过表头行{success_val = $s_col;gsub(/^"|"$/, "", success_val);if (success_val == f_val) {agent_name = $agent_col;gsub(/^"|"$/, "", agent_name);split(agent_name, parts, "^");failure_msg = $msg_col;gsub(/^"|"$/, "", failure_msg);gsub(/\n/, "<br>", failure_msg);gsub(/&/, "&amp;", failure_msg);gsub(/</, "&lt;", failure_msg);gsub(/>/, "&gt;", failure_msg);printf "<tr class=\"failure-row\"><td>%s</td><td>%s</td><td>%s</td></tr>\n", parts[1], parts[2], failure_msg;}}' "$JTL_FILE"
}# 7. 提取成功详情
parse_success_details() {awk -v FPAT='([^,]*)|("[^"]*")' -v s_col="$SUCCESS_COL" -v s_val="$SUCCESS_VALUE" -v agent_col="$AGENT_NAME_COL" -v msg_col="$RESPONSE_MSG_COL" 'NR == 1 { next }  # 跳过表头行{success_val = $s_col;gsub(/^"|"$/, "", success_val);if (success_val == s_val) {agent_name = $agent_col;gsub(/^"|"$/, "", agent_name);split(agent_name, parts, "^");response_msg = $msg_col;gsub(/^"|"$/, "", response_msg);gsub(/\n/, "<br>", response_msg);gsub(/&/, "&amp;", response_msg);gsub(/</, "&lt;", response_msg);gsub(/>/, "&gt;", response_msg);printf "<tr class=\"success-row\"><td>%s</td><td>%s</td><td>%s</td></tr>\n", parts[1], parts[2], response_msg;}}' "$JTL_FILE"
}# 8. 生成自定义 HTML 报告
generate_custom_report() {log "开始生成自定义报告: $CUSTOM_HTML"# 使用 HEREDOC 生成 HTML 内容,嵌入统计变量和详情cat <<EOF > "$CUSTOM_HTML"
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>执行结果统计</title><style># css样式body { font-family: Arial, sans-serif; padding: 20px; background-color: #f9f9f9; }h2 { color: #333; border-bottom: 2px solid #ddd; padding-bottom: 10px; }table { border-collapse: collapse; width: 90%; margin: 20px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1); background-color: white; }th, td { padding: 12px; text-align: left; border: 1px solid #ddd; }th { background-color: #f2f2f2; color: #333; font-weight: bold; }.success-row { background-color: #d4f4dd; color: green; }.failure-row { background-color: #f8cccc; color: red; }.total-row { background-color: #e6e6fa; font-weight: bold; }.rate-row { background-color: #fffacd; }.details-table { width: 100%; }.details-table td, .details-table th { vertical-align: top; }pre { white-space: pre-wrap; word-wrap: break-word; background-color: #f0f0f0; padding: 10px; border: 1px solid #ccc; border-radius: 4px; }</style>
</head>
<body>
<h2>执行结果统计</h2>
<table><tr class="success-row"><th>统计项</th><th>统计值</th></tr><tr class="success-row"><td>成功数</td><td>$SUCCESS_COUNT</td></tr><tr class="failure-row"><td>失败数</td><td>$FAILURE_COUNT</td></tr><tr class="total-row"><td>总数</td><td>$TOTAL_COUNT</td></tr><tr class="rate-row"><td>成功率</td><td>$SUCCESS_RATE%</td></tr>
</table><h2>执行结果数据</h2>
<table class="details-table"><tr><th>智能体名称</th> <th>Query</th><th style="width:60%">详细信息</th> </tr>
$(parse_failure_details)$(parse_success_details)
</table>
</body>
</html>
EOF# 确保报告文件权限(Jenkins 可访问)chmod 644 "$CUSTOM_HTML"log "自定义报告生成完成:$CUSTOM_HTML"
}# 9. 检验报告文件是否生成
verify_report() {if [ -f "$CUSTOM_HTML" ]; thenlog "报告验证通过:$CUSTOM_HTML 存在"elselog "错误:$CUSTOM_HTML 生成失败"exit 1fi
}# 【主流程】按顺序执行函数
main() {clean_old_resourcesrun_jmeter_testparse_jtl_summarycalculate_success_rategenerate_custom_reportverify_report
}# 启动主流程
main

定制化html页面总览:

在这里插入图片描述

http://www.lryc.cn/news/583366.html

相关文章:

  • skywalking-agent-docker镜像
  • 方差、协方差和协方差矩阵
  • Windows 10/11新系统跳过强制联网激活和注册微软账户
  • JavaScript数组键值去重方法
  • 【C++】容器适配器 + stack/queue/deque详解
  • EFK9.0.3 windows搭建
  • Ubuntu连接不上网络问题(Network is unreachable)
  • ubuntu环境下调试 RT-Thread
  • windows部署多实例filebeat监控相同路径下文件
  • 【Kafka】登录日志处理的三次阶梯式优化实践:从同步写入到Kafka多分区批处理
  • SAP-ABAP:SAP中DELECT语句用法详解实例总结
  • Go语言Gin框架实战:开发技巧
  • 2024 睿抗编程技能赛——省赛真题解析(含C++源码)
  • 【Python】遇到 “non-integer arg 1 for randrange() ” 问题的解决方法
  • 技术开发栈中 URL地址末尾加不加 “/“ 有什么区别?
  • 闲庭信步使用图像验证平台加速FPGA的开发:第六课——测试图案的FPGA实现
  • 解决IDEA缺少Add Framework Support选项的可行性方案
  • java中list.remove(item); // 直接移除会导致ConcurrentModificationException
  • 图像自动化处理初探:从拖拽上传到参数设置
  • 基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(5)失败用例截图与重试
  • 制作MikTex本地包可用于离线安装包
  • Synology Cloud Sync构建的企业级跨域数据中台
  • 前端性能优化:从之理论到实践的破局道
  • 【PTA数据结构 | C语言版】一元多项式求导
  • 使用 Docker 搭建 Rust Web 应用开发环境——AI教你学Docker
  • 图像处理中的凸包检测:原理与实现
  • 前端开发自动化设计详解
  • 两种方式清除已经保存的git账号密码
  • AI在垂直领域的深度应用:医疗、金融与自动驾驶的革新之路
  • 分治算法---快排