如何在k6 HTML测试报告中展示请求错误信息
问题分析与解决方案
问题根源
k6的虚拟用户(VU)运行在隔离的沙箱环境中,你定义的globalFailedRequests数组是每个VU独立拥有的副本,主进程中的handleSummary函数无法访问到各个VU沙箱里的数组数据。所以即便每个VU都往数组里push了错误记录,最终在handleSummary里拿到的还是初始化时的空数组。
最简可行修改方案
以下是修复后的完整脚本,通过自定义指标+标签的方式收集错误信息,确保handleSummary能获取到所有失败请求的详情并展示在HTML报告中:
import http from "k6/http"; import { sleep, check } from "k6"; import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js"; import { Counter } from "k6/metrics"; export const options = { stages: [ { duration: "1s", target: 100 }, { duration: "3s", target: 200 }, { duration: "5s", target: 500 }, { duration: "2s", target: 100 }, { duration: "1s", target: 0 }, ], thresholds: { http_req_duration: ["p(95)<200"], http_req_failed: ["rate<0.01"], failed_requests: ["rate<0.01"], }, }; // 自定义计数器,用于标记失败请求并携带关键信息标签 const failedRequests = new Counter("failed_requests"); export default () => { const url = "https://test-url/limit=50&langcode=en"; const res = http.get(url); const success = check(res, { "status is 200": (r) => r.status === 200, "response time < 200ms": (r) => r.timings.duration < 200, }); if (!success) { // 为失败请求添加标签,存储URL、状态码、响应时间、错误摘要等关键信息 failedRequests.add(1, { url: url, status: res.status.toString(), response_time: res.timings.duration.toFixed(2), error: res.body ? res.body.substring(0, 100) : "No error message", }); console.log( `Request success: ${success}, Status code: ${res.status}, timing: ${res.timings.duration}` ); } sleep(6); }; export function handleSummary(data) { let failedRequestsHtml = "<li>No failed requests</li>"; // 从自定义指标的标签中提取失败请求详情 if (data.metrics.failed_requests && Object.keys(data.metrics.failed_requests.tags).length > 0) { const failedEntries = Object.entries(data.metrics.failed_requests.tags); failedRequestsHtml = failedEntries.map(([tag, value]) => { // 解析k6序列化后的标签字符串,还原为键值对 const tagObj = tag.split(",").reduce((acc, pair) => { const [key, val] = pair.split(":"); acc[key] = val; return acc; }, {}); return `<li><strong>URL:</strong> ${tagObj.url} | <strong>Status:</strong> ${tagObj.status} | <strong>Response Time:</strong> ${tagObj.response_time}ms | <strong>Error:</strong> ${tagObj.error}</li>`; }).join(""); } // 构造错误详情的HTML模块 const additionalHtml = ` <h3>Failed Requests Details</h3> <ul>${failedRequestsHtml}</ul> `; // 生成最终的HTML报告 const reportWithFailures = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Load Test Summary Report</title> <style> body { font-family: Arial, sans-serif; max-width: 1200px; margin: 20px auto; padding: 0 20px; } h1 { color: #2d3748; border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; } h3 { color: #2b6cb0; margin-top: 30px; } ul { list-style: none; padding-left: 0; } li { padding: 10px; margin: 8px 0; background-color: #f7fafc; border-radius: 4px; } strong { color: #c53030; } </style> </head> <body> <h1>Load Test Summary Report</h1> ${htmlReport(data)} ${additionalHtml} </body> </html> `; return { "getLoad.html": reportWithFailures, }; }
关键修改说明
- 替换全局数组为自定义指标:用
Counter类型的自定义指标failed_requests替代全局数组,每个失败请求都会携带包含关键信息的标签,确保主进程的handleSummary能获取到所有VU的错误数据。 - 解析标签生成错误列表:k6会将标签对象序列化为逗号分隔的字符串,在
handleSummary中解析这些字符串,还原为错误详情后生成HTML列表。 - 优化报告样式:添加基础CSS样式,让错误详情模块更易读。
注意事项
- 如果错误信息过长,建议截取部分内容(如示例中的
substring(0, 100)),避免标签值过大影响性能。 - 若需要完整的错误响应内容,可结合结构化日志输出:运行k6时执行
k6 run script.js > failed_requests.log,再用外部脚本解析日志并插入到生成的HTML报告中。
内容的提问来源于stack exchange,提问作者Sam Dopps
相关产品推荐
相关产品推荐

