JMeter 自动化测试 + 飞书通知完整指南

作者:兔子蟹子日期:2025/11/20

JMeter 自动化测试 + 飞书通知完整指南

从零开始搭建 JMeter 自动化测试系统,并通过飞书机器人实时推送测试报告

📖 目录

  • 项目简介
  • 系统架构
  • 环境准备
  • 配置参数说明
  • 实施步骤
  • 代码实现
  • 常见问题
  • 最佳实践

项目简介

背景

在持续集成/持续部署(CI/CD)流程中,自动化测试是保证代码质量的重要环节。本项目实现了:

  • 自动化执行:批量运行 JMeter 测试脚本
  • 智能分析:自动统计成功率、响应时间、失败详情
  • 实时通知:测试完成后立即推送飞书消息
  • 可视化报告:美观的飞书卡片样式报告

技术栈

  • 测试工具:Apache JMeter 5.6.3
  • 开发语言:Python 3.7+
  • 依赖库:pandas、requests
  • 通知渠道:飞书自定义机器人

效果展示

1📊 测试执行总览
2🎉 执行状态:全部通过
3📈 测试脚本:3  (成功执行: 3个, 执行失败: 0个)
4🎯 接口统计:总计 150个, 成功 148个, 失败 2个
5📊 整体成功率:98.7%
6⏱️ 总耗时:5分32秒
7

系统架构

架构图

1┌─────────────────┐
2  JMeter 脚本    
3   (.jmx 文件)   
4└────────┬────────┘
5         
6         
7┌─────────────────┐
8  Python 调度器  
9  批量执行测试   
10└────────┬────────┘
11         
12         ├──► 1. 执行 JMeter 命令
13         ├──► 2. 收集 CSV 结果
14         ├──► 3. 分析测试数据
15         └──► 4. 生成飞书报告
16                      
17                      
18              ┌──────────────┐
19                飞书机器人  
20                推送通知    
21              └──────────────┘
22

工作流程

  1. 扫描测试脚本:自动发现指定目录下的所有 .jmx 文件
  2. 顺序执行测试:调用 JMeter 命令行逐个执行测试
  3. 结果收集分析:读取 CSV 结果文件,统计成功率、响应时间等
  4. 生成测试报告:汇总所有测试结果,格式化为 Markdown
  5. 发送飞书通知:通过 Webhook 推送卡片样式的报告

环境准备

硬件要求

  • 操作系统:Linux(推荐 CentOS 7+ / Ubuntu 18.04+)
  • 内存:至少 2GB
  • 磁盘:至少 5GB 可用空间

软件依赖

软件版本要求说明
Python3.7+运行调度脚本
JMeter5.6.2+执行性能测试
Java8+JMeter 运行依赖

配置参数说明

1. 飞书机器人配置

1.1 创建飞书自定义机器人

步骤:

  1. 打开飞书,进入目标群聊
  2. 点击右上角 「设置」「群机器人」
  3. 选择 「添加机器人」「自定义机器人」
  4. 填写机器人信息:
    • 名称JMeter 测试报告
    • 描述自动推送接口测试结果
  5. 安全设置:勾选 「签名校验」
  6. 点击 「完成」,获取以下信息:

获取到的配置:

1# Webhook URL(示例,实际请替换为你的)
2webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3
4# 签名密钥 Secret(示例,实际请替换为你的)
5secret = "YourSecretKeyHere123456"
6
1.2 参数获取位置
参数获取方式示例值
webhook创建机器人后显示的 Webhook 地址https://open.feishu.cn/open-apis/bot/v2/hook/xxx...
secret启用签名校验后显示的密钥YourSecretKeyHere123456

注意事项:

  • ⚠️ 请妥善保管 webhooksecret,避免泄露
  • ⚠️ 建议使用环境变量或配置文件存储,不要硬编码在代码中
  • ⚠️ 每个机器人的配置是唯一的,不同群需要创建不同的机器人

2. JMeter 配置

2.1 JMeter 安装路径

Linux 安装步骤:

1# 1. 下载 JMeter(使用国内镜像加速)
2cd /home/your-user
3wget https://mirrors.tuna.tsinghua.edu.cn/apache/jmeter/binaries/apache-jmeter-5.6.3.tgz
4
5# 2. 解压
6tar -xzf apache-jmeter-5.6.3.tgz
7
8# 3. 验证安装
9/home/your-user/apache-jmeter-5.6.3/bin/jmeter -v
10

配置参数:

1# JMeter 可执行文件的完整路径
2JMETER_BIN = "/home/your-user/apache-jmeter-5.6.3/bin/jmeter"
3
2.2 如何获取 JMeter 路径
1# 方法1:使用 which 命令(如果已加入 PATH)
2which jmeter
3
4# 方法2:使用 find 命令查找
5find /home -name "jmeter" -type f 2>/dev/null
6
7# 方法3:查看安装目录
8ls -la /home/your-user/apache-jmeter-*/bin/jmeter
9

3. 目录结构配置

3.1 推荐的目录结构
1/home/your-user/cicd/
2├── test/
3   ├── testscript/          # 存放 .jmx 测试脚本
4      ├── test_api1.jmx
5      ├── test_api2.jmx
6      └── logs/            # JMeter 执行日志
7   └── logs/                # CSV 测试结果
8├── jmeter_automation.py        # Python 主程序
9└── clean_jmx.py             # JMX 文件清理工具
10
3.2 目录配置参数
1# 测试脚本存放目录
2TEST_SCRIPT_DIR = "/home/your-user/cicd/test/testscript"
3
4# CSV 结果文件输出目录
5CSV_LOG_DIR = "/home/your-user/cicd/test/logs"
6
7# JMeter 执行日志目录
8JMETER_LOG_DIR = "/home/your-user/cicd/test/testscript/logs"
9
3.3 创建目录结构
1# 创建所需目录
2mkdir -p /home/your-user/cicd/test/testscript
3mkdir -p /home/your-user/cicd/test/logs
4mkdir -p /home/your-user/cicd/test/testscript/logs
5
6# 设置权限
7chmod -R 755 /home/your-user/cicd
8

4. 完整配置清单

创建配置文件 config.py

1# -*- coding: utf-8 -*-
2"""
3JMeter 自动化测试配置文件
4请根据实际环境修改以下配置
5"""
6
7# ==================== 飞书机器人配置 ====================
8# 获取方式:飞书群聊  设置  群机器人  添加自定义机器人
9FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_WEBHOOK_ID"
10FEISHU_SECRET = "YOUR_SECRET_KEY"
11
12# ==================== JMeter 配置 ====================
13# JMeter 可执行文件路径
14# 获取方式:执行 'which jmeter'  'find /home -name jmeter'
15JMETER_BIN = "/home/your-user/apache-jmeter-5.6.3/bin/jmeter"
16
17# ==================== 目录配置 ====================
18# 测试脚本目录(存放 .jmx 文件)
19TEST_SCRIPT_DIR = "/home/your-user/cicd/test/testscript"
20
21# CSV 结果输出目录
22CSV_LOG_DIR = "/home/your-user/cicd/test/logs"
23
24# JMeter 日志目录
25JMETER_LOG_DIR = "/home/your-user/cicd/test/testscript/logs"
26
27# ==================== 执行配置 ====================
28# 单个测试超时时间(秒)
29TEST_TIMEOUT = 600  # 10分钟
30
31# 是否使用飞书卡片样式
32USE_CARD_STYLE = True
33

配置验证检查清单:

1# 检查 JMeter 是否可用
2/home/your-user/apache-jmeter-5.6.3/bin/jmeter -v
3
4# 检查目录是否存在
5ls -la /home/your-user/cicd/test/testscript
6
7# 检查 Python 依赖
8python3 -c "import pandas, requests; print('依赖检查通过')"
9
10# 测试飞书 Webhook(可选)
11curl -X POST "$FEISHU_WEBHOOK" \
12  -H 'Content-Type: application/json' \
13  -d '{"msg_type":"text","content":{"text":"测试消息"}}'
14

实施步骤

第一步:环境安装

1.1 安装 Python 依赖
1# 安装 pandas  requests
2pip3 install pandas requests
3
4# 或使用 requirements.txt
5cat > requirements.txt <<EOF
6pandas>=1.3.0
7requests>=2.25.0
8EOF
9
10pip3 install -r requirements.txt
11
1.2 安装 JMeter
1# 使用清华镜像下载(速度快)
2cd /home/your-user
3wget https://mirrors.tuna.tsinghua.edu.cn/apache/jmeter/binaries/apache-jmeter-5.6.3.tgz
4
5# 解压
6tar -xzf apache-jmeter-5.6.3.tgz
7
8# 验证
9./apache-jmeter-5.6.3/bin/jmeter -v
10

第二步:创建飞书机器人

2.1 操作步骤
  1. 打开飞书客户端
  2. 进入要接收通知的群聊
  3. 点击群设置 → 群机器人 → 添加机器人
  4. 选择"自定义机器人"
  5. 配置:
    • 名称:JMeter 自动化测试报告
    • 启用签名校验:✅
  6. 保存 Webhook URL 和 Secret
2.2 验证机器人
1# 发送测试消息
2WEBHOOK="你的webhook地址"
3SECRET="你的secret"
4TIMESTAMP=$(date +%s)
5
6# 生成签名
7SIGN=$(echo -ne "${TIMESTAMP}\n${SECRET}" | openssl dgst -sha256 -hmac "" -binary | base64)
8
9# 发送消息
10curl -X POST "$WEBHOOK" \
11  -H 'Content-Type: application/json' \
12  -d "{
13    \"timestamp\": $TIMESTAMP,
14    \"sign\": \"$SIGN\",
15    \"msg_type\": \"text\",
16    \"content\": {\"text\": \" 飞书机器人配置成功!\"}
17  }"
18

第三步:准备测试脚本

3.1 创建目录结构
1mkdir -p /home/your-user/cicd/test/testscript
2mkdir -p /home/your-user/cicd/test/logs
3mkdir -p /home/your-user/cicd/test/testscript/logs
4
3.2 上传 JMX 文件
1# 从本地上传(在 Windows 执行)
2scp your-test.jmx user@server:/home/your-user/cicd/test/testscript/
3
3.3 清理 JMX 文件中的第三方插件(重要!)

问题说明:

JMeter 脚本可能包含第三方可视化插件(如 kg.apc.jmeter.vizualizers.*),这些插件:

  • 只在 GUI 模式下有用
  • 命令行模式不需要
  • 如果缺少插件会导致执行失败

解决方案:清理可视化组件

1# 方法1:使用 sed 命令清理
2cd /home/your-user/cicd/test/testscript
3cp your-test.jmx your-test.jmx.bak  # 备份
4
5sed -i '/<kg\.apc\.jmeter\.vizualizers/,/<\/kg\.apc\.jmeter\.vizualizers/d' your-test.jmx
6
7# 方法2:使用 Python 清理脚本(推荐)
8python3 clean_jmx.py your-test.jmx
9

验证清理效果:

1# 检查是否还有第三方插件引用
2grep "kg.apc.jmeter" your-test.jmx
3
4# 如果无输出,说明清理成功
5
6# 测试运行
7/home/your-user/apache-jmeter-5.6.3/bin/jmeter \
8  -n -t your-test.jmx -l test.csv -j test.log
9

第四步:部署 Python 脚本

4.1 上传脚本
1# 上传主程序
2scp jmeter_automation.py user@server:/home/your-user/cicd/
3
4# 上传配置文件
5scp config.py user@server:/home/your-user/cicd/
6
4.2 修改配置
1# 编辑配置文件
2vim /home/your-user/cicd/config.py
3
4# 修改以下配置:
5# 1. FEISHU_WEBHOOK - 改为你的 webhook 地址
6# 2. FEISHU_SECRET - 改为你的 secret
7# 3. JMETER_BIN - 改为你的 JMeter 路径
8# 4. TEST_SCRIPT_DIR - 改为你的脚本目录
9

第五步:运行测试

5.1 手动执行
1cd /home/your-user/cicd
2python3 jmeter_automation.py
3

预期输出示例:

1🚀 JMeter 自动化测试开始
2==================================================
3📋 找到 3 个测试脚本,开始批量执行...
4
5[1/3] 正在处理:test_api_login.jmx
6🚀 开始执行:test_api_login.jmx
7 完成执行:test_api_login.jmx,耗时:1分23秒
8
9[2/3] 正在处理:test_api_search.jmx
10🚀 开始执行:test_api_search.jmx
11 完成执行:test_api_search.jmx,耗时:2分15秒
12
13==================================================
14📊 所有测试执行完成,生成报告...
15📤 正在发送报告到飞书...
16 飞书报告发送成功!
17
18🎉 所有任务完成!
19

5.2 设置定时任务(使用 crontab)

什么是 Crontab?

Crontab 是 Linux 系统的定时任务工具,可以让脚本在指定时间自动运行。

操作步骤:

1# 1. 编辑定时任务
2crontab -e
3

首次使用会让你选择编辑器:

1Select an editor.  To change later, run 'select-editor'.
2  1. /bin/nano        <---- 最简单,推荐新手
3  2. /usr/bin/vim.basic
4  3. /usr/bin/vim.tiny
5
6Choose 1-3 [1]: 1  # 输入 1 选择 nano 编辑器
7

添加定时任务:

在打开的编辑器中,添加以下内容(根据需求选择):

1# ==================== 定时任务示例 ====================
2
3# 每天上午 9 点执行测试
40 9 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1
5
6# 每天凌晨 2 点执行测试
70 2 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1
8
9# 每周一上午 9 点执行
100 9 * * 1 /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1
11
12# 每小时执行一次
130 * * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1
14
15# 工作日(周一到周五)上午 10 点执行
160 10 * * 1-5 /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1
17

Crontab 时间格式说明:

1 ┌───────────── 分钟 (0 - 59)
2  ┌───────────── 小时 (0 - 23)
3   ┌───────────── 日期 (1 - 31)
4    ┌───────────── 月份 (1 - 12)
5     ┌───────────── 星期 (0 - 7, 0  7 都表示周日)
6     
7 * * * * * 要执行的命令
8

常用时间表达式:

表达式说明示例
0 9 * * *每天 9:00上午 9 点整
30 14 * * *每天 14:30下午 2:30
0 */2 * * *每 2 小时0:00, 2:00, 4:00…
0 9 * * 1每周一 9:00周一上午 9 点
0 9 1 * *每月 1 号 9:00每月第一天
0 9 * * 1-5工作日 9:00周一到周五

保存并退出编辑器:

方式一:使用 nano 编辑器(推荐新手)

11. 添加完定时任务后
22.  Ctrl + X(退出)
33. 提示 "Save modified buffer?" 时,按 Y(保存)
44. 提示 "File Name to Write" 时,直接按 Enter(确认)
55. 看到 "crontab: installing new crontab" 表示成功
6

方式二:使用 vim 编辑器

11. 添加完定时任务后
22.  Esc 键(进入命令模式)
33. 输入 :wq 然后按 Enter(保存并退出)
4
5# 不保存退出
6Esc  :q!  Enter
7

快捷键总结:

编辑器保存并退出不保存退出
nanoCtrl + X → Y → EnterCtrl + X → N
vimEsc → :wq → EnterEsc → :q! → Enter

验证定时任务:

1# 查看当前用户的定时任务
2crontab -l
3
4# 查看 crontab 服务状态
5systemctl status cron       # Ubuntu/Debian
6systemctl status crond      # CentOS/RHEL
7
8# 查看 crontab 执行日志
9tail -f /var/log/cron        # CentOS/RHEL
10tail -f /var/log/syslog      # Ubuntu/Debian
11
12# 查看自定义的执行日志
13tail -f /home/your-user/cicd/cron.log
14

常用 crontab 命令:

1crontab -e      # 编辑定时任务
2crontab -l      # 列出所有定时任务
3crontab -r      # 删除所有定时任务(谨慎使用!)
4crontab -u user -e   # 编辑指定用户的定时任务(需要 root 权限)
5

测试定时任务(可选):

如果想立即测试定时任务是否正常工作,可以临时设置一个1分钟后执行的任务:

1# 1. 查看当前时间
2date
3
4# 假设现在是 14:30,那么设置 14:31 执行
5crontab -e
6
7# 添加(1分钟后执行)
831 14 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/test.log 2>&1
9
10# 2. 等待 1 分钟后查看日志
11tail -f /home/your-user/cicd/test.log
12
13# 3. 测试成功后,删除测试任务
14crontab -e  # 删除刚才添加的测试行
15

注意事项:

⚠️ 路径必须使用绝对路径

1#  正确
20 9 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py
3
4#  错误(相对路径在 crontab 中不工作)
50 9 * * * python3 jmeter_automation.py
6

⚠️ 指定完整的 Python 解释器路径

1# 查找 Python3 的完整路径
2which python3
3# 输出:/usr/bin/python3
4
5#  crontab 中使用完整路径
6/usr/bin/python3 /path/to/script.py
7

⚠️ 重定向日志输出

1# >> cron.log 2>&1 的含义:
2# >> cron.log        - 将标准输出追加到 cron.log
3# 2>&1              - 将错误输出也重定向到标准输出(即同一个文件)
4
5# 这样可以在日志文件中看到所有输出和错误信息
6

⚠️ 时区问题

1# 检查服务器时区
2date
3timedatectl
4
5# 如果时区不对,修改时区(以中国为例)
6sudo timedatectl set-timezone Asia/Shanghai
7

代码实现

核心代码结构

1# -*- coding: utf-8 -*-
2import hashlib, base64, hmac, requests
3import pandas as pd
4import time, os, subprocess, json
5from datetime import datetime
6
7# ==================== 配置部分 ====================
8# 从配置文件导入或直接定义
9from config import (
10    FEISHU_WEBHOOK,
11    FEISHU_SECRET,
12    JMETER_BIN,
13    TEST_SCRIPT_DIR,
14    CSV_LOG_DIR,
15    JMETER_LOG_DIR,
16    TEST_TIMEOUT,
17    USE_CARD_STYLE
18)
19
20# ==================== 飞书签名生成 ====================
21def gen_sign(timestamp, secret):
22    """生成飞书机器人签名"""
23    string_to_sign = f'{timestamp}\n{secret}'
24    hmac_code = hmac.new(
25        string_to_sign.encode(),
26        digestmod=hashlib.sha256
27    ).digest()
28    return base64.b64encode(hmac_code).decode()
29
30# ==================== 发送飞书消息 ====================
31def send_message(timestamp, sign_id, content_blocks, use_card_style=False):
32    """发送消息到飞书"""
33    url = webhook
34    headers = {'Content-Type': 'application/json'}
35
36    if use_card_style:
37        # 使用卡片样式
38        # 将content_blocks转换为markdown文本
39        markdown_content = ""
40        for block in content_blocks:
41            if block and len(block) > 0 and "text" in block[0]:
42                text = block[0]["text"]
43                if text.strip():  # 只添加非空文本
44                    markdown_content += text + "\n\n"
45
46        data = {
47            "timestamp": timestamp,
48            "sign": sign_id,
49            "msg_type": "interactive",
50            "card": {
51                "schema": "2.0",
52                "config": {
53                    "update_multi": True,
54                    "style": {
55                        "text_size": {
56                            "normal_v2": {
57                                "default": "normal",
58                                "pc": "normal",
59                                "mobile": "heading"
60                            }
61                        }
62                    }
63                },
64                "body": {
65                    "direction": "vertical",
66                    "padding": "16px 16px 16px 16px",
67                    "elements": [
68                        {
69                            "tag": "markdown",
70                            "content": markdown_content,
71                            "text_align": "left",
72                            "text_size": "normal_v2",
73                            "margin": "0px 0px 0px 0px"
74                        }
75                    ]
76                },
77                "header": {
78                    "title": {
79                        "tag": "plain_text",
80                        "content": "🧪 JMeter 自动化测试报告"
81                    },
82                    "subtitle": {
83                        "tag": "plain_text",
84                        "content": f"执行时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
85                    },
86                    "template": "blue",
87                    "padding": "12px 12px 12px 12px"
88                }
89            }
90        }
91    else:
92        # 使用原来的post样式
93        data = {
94            "timestamp": timestamp,
95            "sign": sign_id,
96            "msg_type": "post",
97            "content": {
98                "post": {
99                    "zh_cn": {
100                        "title": "🧪 JMeter 自动化测试报告",
101                        "content": content_blocks
102                    }
103                }
104            }
105        }
106
107    # 打印调试信息
108    print("发送的数据结构:")
109    print(json.dumps(data, ensure_ascii=False, indent=2))
110
111    response = requests.post(url, headers=headers, json=data)
112    return response.json()
113
114# ==================== 执行 JMeter 测试 ====================
115def run_jmeter_script(jmx_file):
116    """运行 JMeter 脚本"""
117    start_time = time.time()
118    current_time = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
119    name = os.path.basename(jmx_file)
120
121    result_csv = f"{CSV_LOG_DIR}/{name}_{current_time}.csv"
122    result_log = f"{JMETER_LOG_DIR}/{name}_{current_time}.log"
123
124    # 创建日志目录
125    os.makedirs(os.path.dirname(result_csv), exist_ok=True)
126    os.makedirs(os.path.dirname(result_log), exist_ok=True)
127
128    cmd = [
129        JMETER_BIN,
130        "-n", "-t", jmx_file,
131        "-l", result_csv,
132        "-j", result_log
133    ]
134
135    print(f"🚀 开始执行:{name}")
136    try:
137        subprocess.run(cmd, check=True, timeout=TEST_TIMEOUT)
138        duration = time.time() - start_time
139        print(f"✅ 完成执行:{name},耗时:{format_duration(duration)}")
140        return result_csv, duration
141    except subprocess.TimeoutExpired:
142        print(f"⏰ 执行超时:{name}")
143        return None, None
144    except subprocess.CalledProcessError as e:
145        print(f"❌ 执行失败:{name},错误:{e}")
146        return None, None
147
148# ==================== 分析测试结果 ====================
149def analyze_csv_results(csv_file):
150    """分析 CSV 结果文件"""
151    try:
152        df = pd.read_csv(csv_file)
153
154        total_requests = len(df)
155        success_requests = len(df[df['success'] == True])
156        failed_requests = len(df[df['success'] == False])
157        success_rate = (success_requests / total_requests * 100) if total_requests > 0 else 0
158        avg_response_time = df['elapsed'].mean() if 'elapsed' in df.columns else 0
159
160        # 获取失败详情
161        failed_details = []
162        if failed_requests > 0:
163            failed = df[df["success"] == False]
164            for _, row in failed.iterrows():
165                failed_details.append({
166                    'label': str(row.get("label")),
167                    'responseCode': str(row.get("responseCode")),
168                    'failureMessage': str(row.get("failureMessage")),
169                    'url': str(row.get("URL"))
170                })
171
172        return {
173            'total': total_requests,
174            'success': success_requests,
175            'failed': failed_requests,
176            'success_rate': success_rate,
177            'avg_response_time': avg_response_time,
178            'failed_details': failed_details
179        }
180    except Exception as e:
181        print(f"分析 CSV 文件失败:{str(e)}")
182        return None
183
184# ==================== 主函数 ====================
185def main():
186    """主函数"""
187    print("🚀 JMeter 自动化测试开始")
188    start_time = time.time()
189
190    # 获取所有 JMX 文件
191    jmx_files = sorted([
192        os.path.join(TEST_SCRIPT_DIR, f)
193        for f in os.listdir(TEST_SCRIPT_DIR)
194        if f.endswith(".jmx")
195    ])
196
197    if not jmx_files:
198        print(f"⚠️ 警告:在 {TEST_SCRIPT_DIR} 中没有找到任何 .jmx 文件")
199        return
200
201    print(f"📋 找到 {len(jmx_files)} 个测试脚本")
202
203    # 执行所有测试
204    results = []
205    for jmx in jmx_files:
206        result_csv, duration = run_jmeter_script(jmx)
207        analysis = analyze_csv_results(result_csv) if result_csv else None
208
209        results.append({
210            'name': os.path.basename(jmx),
211            'duration': duration or 0,
212            'analysis': analysis,
213            'status': 'success' if analysis else 'failed'
214        })
215
216    # 生成并发送报告
217    # ... 详见完整代码
218
219    print("🎉 所有任务完成!")
220
221if __name__ == "__main__":
222    main()
223

常见问题

1. JMeter 执行失败:找不到插件

错误信息:

1CannotResolveClassException: kg.apc.jmeter.vizualizers.CorrectedResultCollector
2

原因: JMX 文件中包含第三方可视化插件

解决方案:

1# 清理 JMX 文件中的可视化组件
2sed -i '/<kg\.apc\.jmeter\.vizualizers/,/<\/kg\.apc\.jmeter\.vizualizers/d' your-test.jmx
3

2. 飞书消息发送失败

错误代码: code: 19021

原因: 签名验证失败

解决方案:

  1. 检查 secret 是否正确
  2. 检查时间戳是否为当前时间(秒级)
  3. 检查签名生成算法是否正确
1# 正确的签名生成
2timestamp = int(time.time())  # 必须是整数秒
3string_to_sign = f'{timestamp}\n{secret}'
4hmac_code = hmac.new(string_to_sign.encode(), digestmod=hashlib.sha256).digest()
5sign = base64.b64encode(hmac_code).decode()
6

3. CSV 文件无法解析

错误信息: KeyError: 'success'

原因: JMeter 配置未正确输出结果

解决方案:

确保 JMeter 脚本中包含"简单数据写入器"或正确的监听器配置:

1<ResultCollector guiclass="SimpleDataWriter" testclass="ResultCollector">
2  <objProp>
3    <value class="SampleSaveConfiguration">
4      <time>true</time>
5      <latency>true</latency>
6      <success>true</success>
7      <label>true</label>
8      <code>true</code>
9      <message>true</message>
10      <responseData>false</responseData>
11    </value>
12  </objProp>
13</ResultCollector>
14

4. 权限问题

错误信息: Permission denied

解决方案:

1# 给脚本执行权限
2chmod +x jmeter_automation.py
3
4# 给目录写权限
5chmod -R 755 /home/your-user/cicd
6

最佳实践

1. 安全性建议

1.1 敏感信息管理

不推荐:硬编码

1webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/xxx"  # 
2secret = "my-secret-key"  # 
3

推荐:使用环境变量

1import os
2
3webhook = os.getenv('FEISHU_WEBHOOK')
4secret = os.getenv('FEISHU_SECRET')
5
1# 设置环境变量
2export FEISHU_WEBHOOK="https://open.feishu.cn/..."
3export FEISHU_SECRET="your-secret"
4
5# 或写入 .env 文件
6echo 'FEISHU_WEBHOOK="https://..."' >> .env
7echo 'FEISHU_SECRET="xxx"' >> .env
8

推荐:使用配置文件 + .gitignore

1# config.py (加入 .gitignore)
2FEISHU_WEBHOOK = "..."
3FEISHU_SECRET = "..."
4
1# .gitignore
2config.py
3*.pyc
4__pycache__/
5
1.2 Webhook 访问控制
  • 仅在受信任的服务器上部署
  • 定期轮换 Secret 密钥
  • 限制机器人权限(只读群聊信息)

2. 性能优化

2.1 并行执行测试(可选)
1from concurrent.futures import ThreadPoolExecutor
2
3def main():
4    jmx_files = [...]
5
6    # 使用线程池并行执行(谨慎使用,可能导致资源竞争)
7    with ThreadPoolExecutor(max_workers=3) as executor:
8        futures = [executor.submit(run_jmeter_script, jmx) for jmx in jmx_files]
9        results = [f.result() for f in futures]
10
2.2 日志清理
1# 定期清理旧日志(保留最近30天)
2find /home/your-user/cicd/test/logs -name "*.csv" -mtime +30 -delete
3find /home/your-user/cicd/test/testscript/logs -name "*.log" -mtime +30 -delete
4

3. 监控与告警

3.1 添加失败重试机制
1def run_jmeter_script_with_retry(jmx_file, max_retries=3):
2    """带重试的 JMeter 执行"""
3    for attempt in range(max_retries):
4        result_csv, duration = run_jmeter_script(jmx_file)
5        if result_csv:
6            return result_csv, duration
7
8        if attempt < max_retries - 1:
9            print(f"重试 {attempt + 1}/{max_retries}...")
10            time.sleep(5)
11
12    return None, None
13
3.2 添加失败率告警
1def check_alert(results):
2    """检查是否需要告警"""
3    total_failed = sum([r['analysis']['failed'] for r in results if r['analysis']])
4    total_requests = sum([r['analysis']['total'] for r in results if r['analysis']])
5
6    fail_rate = total_failed / total_requests if total_requests > 0 else 0
7
8    # 失败率超过10%时特殊提醒
9    if fail_rate > 0.1:
10        send_alert_message(f"⚠️ 测试失败率过高:{fail_rate*100:.1f}%")
11

4. 目录规范

1project/
2├── config.py              # 配置文件(加入 .gitignore)
3├── config.example.py      # 配置模板(提交到 git)
4├── jmeter_automation.py      # 主程序
5├── clean_jmx.py           # 工具脚本
6├── requirements.txt       # Python 依赖
7├── README.md              # 说明文档
8├── test/
9   ├── testscript/        # 测试脚本
10   └── logs/              # 测试结果
11└── docs/                  # 文档目录
12    └── 使用指南.md
13

5. JMX 文件管理

5.1 命名规范
1建议格式:{项目名}_{模块}_{测试类型}.jmx
2
3示例:
4- ProjectA_Login_API.jmx
5- ProjectA_Payment_Performance.jmx
6- ProjectB_Search_Stress.jmx
7
5.2 版本控制
1#  JMX 文件纳入 Git 管理
2git add test/testscript/*.jmx
3git commit -m "feat: 新增支付接口测试脚本"
4

总结

通过本指南,你已经学会了:

✅ 搭建 JMeter 自动化测试环境
✅ 配置飞书机器人实现消息通知
✅ 编写 Python 脚本批量执行测试
✅ 分析测试结果并生成报告
✅ 处理常见问题和故障排查

下一步建议

  1. 集成 CI/CD:将脚本集成到 Jenkins、GitLab CI 等平台
  2. 增强报告:添加趋势分析、图表展示
  3. 多渠道通知:支持钉钉、企业微信、邮件等
  4. Web 界面:开发 Web 控制台,可视化管理测试

参考资料


如果本文对你有帮助,欢迎点赞、收藏、转发!


JMeter 自动化测试 + 飞书通知完整指南》 是转载文章,点击查看原文


相关推荐


Gemini 3深夜来袭:力压GPT 5.1,大模型谷歌时代来了
机器之心2025/11/19

Gemini 3 还没现身,推特先崩为敬。 没有哪家模型的发布比 Gemini 3 更万众瞩目,根据 Gemini 之前 3 个月更新一次的频率,AI 社区自 9 月起便对 Gemini 3 翘首以盼。 今天,谷歌开发者关系负责人、Google AI Studio 负责人一条仅含「Gemini」一词的推文,积蓄了数月的期待终于迎来了爆发点,推特相关话题瞬间沸腾。 有趣的是,临近发布节点,推特竟「应景」地崩了几次。尽管「幕后黑手」是 Cloudflare,但这崩溃的时机简直精准得让人怀疑有人背后


AI 为啥能回答你的问题?大模型 5 步工作流程,看完秒懂!
印刻君2025/11/18

如今,大语言模型(LLM)已成为我们学习和工作中的常用工具。当你在对话框输入问题时,或许会好奇,这些模型为何能精准、迅速地生成回答?本文将用通俗易懂的语言,为你拆解背后的核心工作流程。 简单来说,大模型处理问题主要包含五个关键环节,分别是: 分词(Tokenization) 词嵌入(Word Embedding) 位置编码(Positional Encoding) 自注意力机制(Self-Attention) 自回归生成(Autoregressive Generation) 这些专业名词虽然


整数序列权重排序——基于深度优先搜索(DFS)以及记忆化搜索
w24167178402025/11/16

提示:本文适合对算法设计感兴趣的道友一起互相学习,如有疑问,欢迎评论区或者私信讨论。 文章目录 前言 一、题目介绍 二、前置知识扩展 1.深度优先遍历 1.1递归DFS 1.1非递归DFS 2.@cache装饰器 3.range()函数 4.sorted()函数 三、解题思路及代码解读


前端开发小技巧-【JavaScript】- 获取元素距离 document 顶部的距离
禁止摆烂_才浅2025/11/15

获取元素距离 document 顶部的距离 方案1:使用 offsetTop(最简单) const element = document.getElementById('myDiv') const distance = element.offsetTop console.log(distance) // 500(像素) 方案2:使用 getBoundingClientRect() + scrollY(最准确) const element = document.getElementById(


稳定边界层高度参数化方案的回归建模
mayubins2025/11/14

稳定边界层高度参数化方案的回归建模 为了发展一个适用于CAS-ESM气候系统模式的稳定边界层高度参数化方案,本研究基于湍流尺度分析理论,采用多元线性回归方法,对Zilitinkevich类型公式中的经验系数进行确定性拟合。该公式综合考虑了地表机械强迫、热力强迫以及自由大气静力稳定度的综合影响。 理论框架 我们所采用的参数化公式源于稳定层结下湍流动能的平衡关系,其函数形式如下: 1/h² = C1 * (f² / τ) + C2 * (N |f| / τ) + C3 * (|f β F₊| / τ


Python 的内置函数 isinstance
IMPYLH2025/11/13

Python 内建函数列表 > Python 的内置函数 isinstance Python 的内置函数 isinstance() 用于判断一个对象是否属于某个类或类型,或者是否属于由这些类型组成的元组中的一个。它是 Python 中类型检查的重要工具,相比于 type() 函数具有更灵活的类型检查能力。 其语法为: isinstance(object, classinfo) 其中: object 是要检查的对象classinfo 可以是一个类型对象,或者由类型对象组成的元组 is


[免费]基于Python的农产品可视化系统(Django+echarts)【论文+源码+SQL脚本】
java1234_小锋2025/11/11

大家好,我是java1234_小锋老师,看到一个不错的基于Python的农产品可视化系统(Django+echarts)【论文+源码+SQL脚本】,分享下哈。 项目视频演示 https://www.bilibili.com/video/BV1mYkoBLEju/ 项目介绍 本研究提出了一种基于Python的农产品可视化系统,结合Django框架和ECharts库,旨在为农产品数据的展示和分析提供便捷、高效的解决方案。系统通过Django框架构建后端服务,使用ECharts实现前端数提供数


用 PyQt 开发一个桌面计算器:从零到完整实战指南
Python私教2025/11/9

作者:张大鹏 时间:2025-11-05 标签:Python、PyQt5、GUI、桌面开发、实战教程 一、前言 在桌面应用开发中,计算器 是一个非常适合入门的练手项目。 它涉及到图形界面设计、事件绑定、信号槽机制、布局管理等核心概念。 今天我们将使用 PyQt5(同样适用于 PyQt6)一步步实现一个可用的计算器程序,从 UI 布局到功能逻辑完整讲解。 最终效果如下👇: 支持加减乘除和小数运算;按钮布局整齐;可通过按钮或键盘输入操作;界面美观,可打包为独立应用。 二、项目环境 项目依赖


React+Tailwind CSS+Shadcn UI
再希2025/11/7

推荐常用网址 yhttps://react.dev/learn/describing-the-ui 使用 Vite 安装 Tailwind CSS - Tailwind CSS Introduction - shadcn/ui 下面这个地址记录了前端常用的命令,以及学习教程等,推荐给各位 https://www.houdunren.com/doc/article/21/208 创建react项目首先需要准备好nodeJS环境,我这里使用的是vite脚手架 步骤如下: 使用 Vit


前端新手必看!困扰90%人的10个JavaScript问题,一次性帮你解决
良山有风来2025/11/4

是不是经常被JavaScript的各种“奇怪”行为搞到头大?明明照着教程写代码,结果运行起来却各种报错?别担心,这些问题几乎每个前端新手都会遇到。 今天我就把新手最容易踩坑的10个JavaScript问题整理出来,每个问题都会给出清晰的解释和实用的解决方案。看完这篇文章,你就能彻底理解这些“坑”背后的原理,写出更健壮的代码。 变量提升的陷阱 很多新手都会困惑,为什么变量在声明之前就能使用?这其实是JavaScript的变量提升机制在作怪。 console.log(myName); // 输出:u

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2025 聚合阅读