如何让k6生成类Locust风格的按路径分组HTML测试报告?
实现k6按路径分组的HTML报告(仿Locust风格)
核心思路
要实现类似Locust的按路径分组报告,关键是给请求指标打路径标签,再通过自定义报告逻辑聚合标签数据并渲染成分组视图。以下是具体实现步骤:
1. 给请求指标添加路径标签
在k6脚本中定义带url_path标签的自定义指标,每个请求完成后将路径作为标签值传入指标:
import http from 'k6/http'; import { Trend, Counter } from 'k6/metrics'; // 定义带路径标签的性能指标 const reqDuration = new Trend('request_duration', { tags: ['url_path'] }); const reqCount = new Counter('request_count', { tags: ['url_path'] }); export const options = { vus: 10, duration: '30s', }; export default function () { // 示例请求1:/public/crocodiles/ let res = http.get('https://test-api.k6.io/public/crocodiles/'); // 给指标绑定当前请求路径 reqDuration.add(res.timings.duration, { url_path: '/public/crocodiles/' }); reqCount.add(1, { url_path: '/public/crocodiles/' }); // 示例请求2:/public/crocodiles/1/ res = http.get('https://test-api.k6.io/public/crocodiles/1/'); reqDuration.add(res.timings.duration, { url_path: '/public/crocodiles/1/' }); reqCount.add(1, { url_path: '/public/crocodiles/1/' }); }
2. 自定义HTML报告渲染逻辑
利用k6的handleSummary钩子,提取按url_path分组的指标数据,编写自定义HTML模板渲染分组视图:
export function handleSummary(data) { // 聚合按路径分组的指标数据 const pathMetrics = {}; // 处理响应时长指标 if (data.metrics.request_duration) { Object.keys(data.metrics.request_duration.tags).forEach(path => { pathMetrics[path] = { ...(pathMetrics[path] || {}), duration: { avg: Math.round(data.metrics.request_duration.tags[path].values.avg), p95: Math.round(data.metrics.request_duration.tags[path].values.p95), min: Math.round(data.metrics.request_duration.tags[path].values.min), max: Math.round(data.metrics.request_duration.tags[path].values.max), } }; }); } // 处理请求计数指标 if (data.metrics.request_count) { Object.keys(data.metrics.request_count.tags).forEach(path => { pathMetrics[path] = { ...(pathMetrics[path] || {}), count: data.metrics.request_count.tags[path].values.count, }; }); } // 自定义HTML模板(仿Locust分组样式) const reportHtml = ` <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>k6 按路径分组性能报告</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; font-family: Arial, sans-serif; } .container { max-width: 1200px; margin: 20px auto; padding: 0 20px; } .group-card { margin: 15px 0; padding: 18px; border: 1px solid #e0e0e0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); } .group-title { font-size: 1.1em; font-weight: 600; color: #2c3e50; margin-bottom: 12px; } .metric-item { margin: 6px 0; color: #34495e; } .metric-label { display: inline-block; width: 120px; } </style> </head> <body> <div class="container"> <h1 style="text-align: center; margin: 20px 0; color: #2c3e50;">k6 按路径分组性能报告</h1> ${Object.keys(pathMetrics).map(path => ` <div class="group-card"> <div class="group-title">请求路径:${path}</div> <div class="metric-item"><span class="metric-label">请求总数:</span>${pathMetrics[path].count || 0}</div> <div class="metric-item"><span class="metric-label">平均响应时长:</span>${pathMetrics[path].duration?.avg || 0}ms</div> <div class="metric-item"><span class="metric-label">P95响应时长:</span>${pathMetrics[path].duration?.p95 || 0}ms</div> <div class="metric-item"><span class="metric-label">最小响应时长:</span>${pathMetrics[path].duration?.min || 0}ms</div> <div class="metric-item"><span class="metric-label">最大响应时长:</span>${pathMetrics[path].duration?.max || 0}ms</div> </div> `).join('')} </div> </body> </html> `; return { 'path-grouped-report.html': reportHtml, // 生成自定义分组报告 'summary.json': JSON.stringify(data), // 可选:保留原始数据文件 }; }
3. 添加图表扩展(可选)
如果需要给分组报告添加图表(比如响应时长对比柱状图),可在自定义HTML中内嵌Chart.js(若要避免外链,可将Chart.js代码本地挂载到Docker容器中引用),示例如下:
在HTML的<head>中添加Chart.js(本地挂载则替换为容器内路径):
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
在<body>末尾添加图表容器和渲染脚本:
<canvas id="durationChart" width="800" height="400" style="margin: 20px auto; display: block;"></canvas> <script> const ctx = document.getElementById('durationChart').getContext('2d'); const paths = ${JSON.stringify(Object.keys(pathMetrics))}; const avgDurations = paths.map(p => pathMetrics[p].duration?.avg || 0); new Chart(ctx, { type: 'bar', data: { labels: paths, datasets: [{ label: '平均响应时长(ms)', data: avgDurations, backgroundColor: 'rgba(30, 136, 229, 0.6)', borderColor: 'rgba(30, 136, 229, 1)', borderWidth: 1 }] }, options: { responsive: true, scales: { y: { beginAtZero: true, title: { display: true, text: '响应时长(ms)' } }, x: { title: { display: true, text: '请求路径' } } } } }); </script>
运行与验证
在Docker中运行k6脚本:
docker run -i loadimpact/k6 run - <your-script.js>
运行完成后,当前目录会生成path-grouped-report.html,打开即可看到按路径分组的报告,逻辑与Locust分组视图一致。
内容的提问来源于stack exchange,提问作者lobafox
相关产品推荐
相关产品推荐

