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

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

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

📖 目录


项目简介

背景

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

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

技术栈

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

效果展示

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

系统架构

架构图

复制代码
┌─────────────────┐
│  JMeter 脚本    │
│   (.jmx 文件)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Python 调度器  │
│  批量执行测试   │
└────────┬────────┘
         │
         ├──► 1. 执行 JMeter 命令
         ├──► 2. 收集 CSV 结果
         ├──► 3. 分析测试数据
         └──► 4. 生成飞书报告
                      │
                      ▼
              ┌──────────────┐
              │  飞书机器人  │
              │  推送通知    │
              └──────────────┘

工作流程

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

环境准备

硬件要求

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

软件依赖

软件 版本要求 说明
Python 3.7+ 运行调度脚本
JMeter 5.6.2+ 执行性能测试
Java 8+ JMeter 运行依赖

配置参数说明

1. 飞书机器人配置

1.1 创建飞书自定义机器人

步骤:

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

获取到的配置:

python 复制代码
# Webhook URL(示例,实际请替换为你的)
webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

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

注意事项:

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

2. JMeter 配置

2.1 JMeter 安装路径

Linux 安装步骤:

bash 复制代码
# 1. 下载 JMeter(使用国内镜像加速)
cd /home/your-user
wget https://mirrors.tuna.tsinghua.edu.cn/apache/jmeter/binaries/apache-jmeter-5.6.3.tgz

# 2. 解压
tar -xzf apache-jmeter-5.6.3.tgz

# 3. 验证安装
/home/your-user/apache-jmeter-5.6.3/bin/jmeter -v

配置参数:

python 复制代码
# JMeter 可执行文件的完整路径
JMETER_BIN = "/home/your-user/apache-jmeter-5.6.3/bin/jmeter"
2.2 如何获取 JMeter 路径
bash 复制代码
# 方法1:使用 which 命令(如果已加入 PATH)
which jmeter

# 方法2:使用 find 命令查找
find /home -name "jmeter" -type f 2>/dev/null

# 方法3:查看安装目录
ls -la /home/your-user/apache-jmeter-*/bin/jmeter

3. 目录结构配置

3.1 推荐的目录结构
复制代码
/home/your-user/cicd/
├── test/
│   ├── testscript/          # 存放 .jmx 测试脚本
│   │   ├── test_api1.jmx
│   │   ├── test_api2.jmx
│   │   └── logs/            # JMeter 执行日志
│   └── logs/                # CSV 测试结果
├── jmeter_automation.py        # Python 主程序
└── clean_jmx.py             # JMX 文件清理工具
3.2 目录配置参数
python 复制代码
# 测试脚本存放目录
TEST_SCRIPT_DIR = "/home/your-user/cicd/test/testscript"

# CSV 结果文件输出目录
CSV_LOG_DIR = "/home/your-user/cicd/test/logs"

# JMeter 执行日志目录
JMETER_LOG_DIR = "/home/your-user/cicd/test/testscript/logs"
3.3 创建目录结构
bash 复制代码
# 创建所需目录
mkdir -p /home/your-user/cicd/test/testscript
mkdir -p /home/your-user/cicd/test/logs
mkdir -p /home/your-user/cicd/test/testscript/logs

# 设置权限
chmod -R 755 /home/your-user/cicd

4. 完整配置清单

创建配置文件 config.py:

python 复制代码
# -*- coding: utf-8 -*-
"""
JMeter 自动化测试配置文件
请根据实际环境修改以下配置
"""

# ==================== 飞书机器人配置 ====================
# 获取方式:飞书群聊 → 设置 → 群机器人 → 添加自定义机器人
FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_WEBHOOK_ID"
FEISHU_SECRET = "YOUR_SECRET_KEY"

# ==================== JMeter 配置 ====================
# JMeter 可执行文件路径
# 获取方式:执行 'which jmeter' 或 'find /home -name jmeter'
JMETER_BIN = "/home/your-user/apache-jmeter-5.6.3/bin/jmeter"

# ==================== 目录配置 ====================
# 测试脚本目录(存放 .jmx 文件)
TEST_SCRIPT_DIR = "/home/your-user/cicd/test/testscript"

# CSV 结果输出目录
CSV_LOG_DIR = "/home/your-user/cicd/test/logs"

# JMeter 日志目录
JMETER_LOG_DIR = "/home/your-user/cicd/test/testscript/logs"

# ==================== 执行配置 ====================
# 单个测试超时时间(秒)
TEST_TIMEOUT = 600  # 10分钟

# 是否使用飞书卡片样式
USE_CARD_STYLE = True

配置验证检查清单:

bash 复制代码
# 检查 JMeter 是否可用
/home/your-user/apache-jmeter-5.6.3/bin/jmeter -v

# 检查目录是否存在
ls -la /home/your-user/cicd/test/testscript

# 检查 Python 依赖
python3 -c "import pandas, requests; print('依赖检查通过')"

# 测试飞书 Webhook(可选)
curl -X POST "$FEISHU_WEBHOOK" \
  -H 'Content-Type: application/json' \
  -d '{"msg_type":"text","content":{"text":"测试消息"}}'

实施步骤

第一步:环境安装

1.1 安装 Python 依赖
bash 复制代码
# 安装 pandas 和 requests
pip3 install pandas requests

# 或使用 requirements.txt
cat > requirements.txt <<EOF
pandas>=1.3.0
requests>=2.25.0
EOF

pip3 install -r requirements.txt
1.2 安装 JMeter
bash 复制代码
# 使用清华镜像下载(速度快)
cd /home/your-user
wget https://mirrors.tuna.tsinghua.edu.cn/apache/jmeter/binaries/apache-jmeter-5.6.3.tgz

# 解压
tar -xzf apache-jmeter-5.6.3.tgz

# 验证
./apache-jmeter-5.6.3/bin/jmeter -v

第二步:创建飞书机器人

2.1 操作步骤
  1. 打开飞书客户端
  2. 进入要接收通知的群聊
  3. 点击群设置 → 群机器人 → 添加机器人
  4. 选择"自定义机器人"
  5. 配置:
    • 名称:JMeter 自动化测试报告
    • 启用签名校验:✅
  6. 保存 Webhook URL 和 Secret
2.2 验证机器人
bash 复制代码
# 发送测试消息
WEBHOOK="你的webhook地址"
SECRET="你的secret"
TIMESTAMP=$(date +%s)

# 生成签名
SIGN=$(echo -ne "${TIMESTAMP}\n${SECRET}" | openssl dgst -sha256 -hmac "" -binary | base64)

# 发送消息
curl -X POST "$WEBHOOK" \
  -H 'Content-Type: application/json' \
  -d "{
    \"timestamp\": $TIMESTAMP,
    \"sign\": \"$SIGN\",
    \"msg_type\": \"text\",
    \"content\": {\"text\": \"✅ 飞书机器人配置成功!\"}
  }"

第三步:准备测试脚本

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

问题说明:

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

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

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

bash 复制代码
# 方法1:使用 sed 命令清理
cd /home/your-user/cicd/test/testscript
cp your-test.jmx your-test.jmx.bak  # 备份

sed -i '/<kg\.apc\.jmeter\.vizualizers/,/<\/kg\.apc\.jmeter\.vizualizers/d' your-test.jmx

# 方法2:使用 Python 清理脚本(推荐)
python3 clean_jmx.py your-test.jmx

验证清理效果:

bash 复制代码
# 检查是否还有第三方插件引用
grep "kg.apc.jmeter" your-test.jmx

# 如果无输出,说明清理成功

# 测试运行
/home/your-user/apache-jmeter-5.6.3/bin/jmeter \
  -n -t your-test.jmx -l test.csv -j test.log

第四步:部署 Python 脚本

4.1 上传脚本
bash 复制代码
# 上传主程序
scp jmeter_automation.py user@server:/home/your-user/cicd/

# 上传配置文件
scp config.py user@server:/home/your-user/cicd/
4.2 修改配置
bash 复制代码
# 编辑配置文件
vim /home/your-user/cicd/config.py

# 修改以下配置:
# 1. FEISHU_WEBHOOK - 改为你的 webhook 地址
# 2. FEISHU_SECRET - 改为你的 secret
# 3. JMETER_BIN - 改为你的 JMeter 路径
# 4. TEST_SCRIPT_DIR - 改为你的脚本目录

第五步:运行测试

5.1 手动执行
bash 复制代码
cd /home/your-user/cicd
python3 jmeter_automation.py

预期输出示例:

复制代码
🚀 JMeter 自动化测试开始
==================================================
📋 找到 3 个测试脚本,开始批量执行...

[1/3] 正在处理:test_api_login.jmx
🚀 开始执行:test_api_login.jmx
✅ 完成执行:test_api_login.jmx,耗时:1分23秒

[2/3] 正在处理:test_api_search.jmx
🚀 开始执行:test_api_search.jmx
✅ 完成执行:test_api_search.jmx,耗时:2分15秒

==================================================
📊 所有测试执行完成,生成报告...
📤 正在发送报告到飞书...
✅ 飞书报告发送成功!

🎉 所有任务完成!

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

什么是 Crontab?

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

操作步骤:

bash 复制代码
# 1. 编辑定时任务
crontab -e

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

复制代码
Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- 最简单,推荐新手
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny

Choose 1-3 [1]: 1  # 输入 1 选择 nano 编辑器

添加定时任务:

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

bash 复制代码
# ==================== 定时任务示例 ====================

# 每天上午 9 点执行测试
0 9 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1

# 每天凌晨 2 点执行测试
0 2 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1

# 每周一上午 9 点执行
0 9 * * 1 /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1

# 每小时执行一次
0 * * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1

# 工作日(周一到周五)上午 10 点执行
0 10 * * 1-5 /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/cron.log 2>&1

Crontab 时间格式说明:

复制代码
 ┌───────────── 分钟 (0 - 59)
 │ ┌───────────── 小时 (0 - 23)
 │ │ ┌───────────── 日期 (1 - 31)
 │ │ │ ┌───────────── 月份 (1 - 12)
 │ │ │ │ ┌───────────── 星期 (0 - 7, 0 和 7 都表示周日)
 │ │ │ │ │
 * * * * * 要执行的命令

常用时间表达式:

表达式 说明 示例
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 编辑器(推荐新手)

复制代码
1. 添加完定时任务后
2. 按 Ctrl + X(退出)
3. 提示 "Save modified buffer?" 时,按 Y(保存)
4. 提示 "File Name to Write" 时,直接按 Enter(确认)
5. 看到 "crontab: installing new crontab" 表示成功

方式二:使用 vim 编辑器

复制代码
1. 添加完定时任务后
2. 按 Esc 键(进入命令模式)
3. 输入 :wq 然后按 Enter(保存并退出)

# 不保存退出
Esc → :q! → Enter

快捷键总结:

编辑器 保存并退出 不保存退出
nano Ctrl + X → Y → Enter Ctrl + X → N
vim Esc → :wq → Enter Esc → :q! → Enter

验证定时任务:

bash 复制代码
# 查看当前用户的定时任务
crontab -l

# 查看 crontab 服务状态
systemctl status cron       # Ubuntu/Debian
systemctl status crond      # CentOS/RHEL

# 查看 crontab 执行日志
tail -f /var/log/cron        # CentOS/RHEL
tail -f /var/log/syslog      # Ubuntu/Debian

# 查看自定义的执行日志
tail -f /home/your-user/cicd/cron.log

常用 crontab 命令:

bash 复制代码
crontab -e      # 编辑定时任务
crontab -l      # 列出所有定时任务
crontab -r      # 删除所有定时任务(谨慎使用!)
crontab -u user -e   # 编辑指定用户的定时任务(需要 root 权限)

测试定时任务(可选):

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

bash 复制代码
# 1. 查看当前时间
date

# 假设现在是 14:30,那么设置 14:31 执行
crontab -e

# 添加(1分钟后执行)
31 14 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py >> /home/your-user/cicd/test.log 2>&1

# 2. 等待 1 分钟后查看日志
tail -f /home/your-user/cicd/test.log

# 3. 测试成功后,删除测试任务
crontab -e  # 删除刚才添加的测试行

注意事项:

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

bash 复制代码
# ✅ 正确
0 9 * * * /usr/bin/python3 /home/your-user/cicd/jmeter_automation.py

# ❌ 错误(相对路径在 crontab 中不工作)
0 9 * * * python3 jmeter_automation.py

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

bash 复制代码
# 查找 Python3 的完整路径
which python3
# 输出:/usr/bin/python3

# 在 crontab 中使用完整路径
/usr/bin/python3 /path/to/script.py

⚠️ 重定向日志输出

bash 复制代码
# >> cron.log 2>&1 的含义:
# >> cron.log        - 将标准输出追加到 cron.log
# 2>&1              - 将错误输出也重定向到标准输出(即同一个文件)

# 这样可以在日志文件中看到所有输出和错误信息

⚠️ 时区问题

bash 复制代码
# 检查服务器时区
date
timedatectl

# 如果时区不对,修改时区(以中国为例)
sudo timedatectl set-timezone Asia/Shanghai

代码实现

核心代码结构

python 复制代码
# -*- coding: utf-8 -*-
import hashlib, base64, hmac, requests
import pandas as pd
import time, os, subprocess, json
from datetime import datetime

# ==================== 配置部分 ====================
# 从配置文件导入或直接定义
from config import (
    FEISHU_WEBHOOK,
    FEISHU_SECRET,
    JMETER_BIN,
    TEST_SCRIPT_DIR,
    CSV_LOG_DIR,
    JMETER_LOG_DIR,
    TEST_TIMEOUT,
    USE_CARD_STYLE
)

# ==================== 飞书签名生成 ====================
def gen_sign(timestamp, secret):
    """生成飞书机器人签名"""
    string_to_sign = f'{timestamp}\n{secret}'
    hmac_code = hmac.new(
        string_to_sign.encode(),
        digestmod=hashlib.sha256
    ).digest()
    return base64.b64encode(hmac_code).decode()

# ==================== 发送飞书消息 ====================
def send_message(timestamp, sign_id, content_blocks, use_card_style=False):
    """发送消息到飞书"""
    url = webhook
    headers = {'Content-Type': 'application/json'}

    if use_card_style:
        # 使用卡片样式
        # 将content_blocks转换为markdown文本
        markdown_content = ""
        for block in content_blocks:
            if block and len(block) > 0 and "text" in block[0]:
                text = block[0]["text"]
                if text.strip():  # 只添加非空文本
                    markdown_content += text + "\n\n"

        data = {
            "timestamp": timestamp,
            "sign": sign_id,
            "msg_type": "interactive",
            "card": {
                "schema": "2.0",
                "config": {
                    "update_multi": True,
                    "style": {
                        "text_size": {
                            "normal_v2": {
                                "default": "normal",
                                "pc": "normal",
                                "mobile": "heading"
                            }
                        }
                    }
                },
                "body": {
                    "direction": "vertical",
                    "padding": "16px 16px 16px 16px",
                    "elements": [
                        {
                            "tag": "markdown",
                            "content": markdown_content,
                            "text_align": "left",
                            "text_size": "normal_v2",
                            "margin": "0px 0px 0px 0px"
                        }
                    ]
                },
                "header": {
                    "title": {
                        "tag": "plain_text",
                        "content": "🧪 JMeter 自动化测试报告"
                    },
                    "subtitle": {
                        "tag": "plain_text",
                        "content": f"执行时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
                    },
                    "template": "blue",
                    "padding": "12px 12px 12px 12px"
                }
            }
        }
    else:
        # 使用原来的post样式
        data = {
            "timestamp": timestamp,
            "sign": sign_id,
            "msg_type": "post",
            "content": {
                "post": {
                    "zh_cn": {
                        "title": "🧪 JMeter 自动化测试报告",
                        "content": content_blocks
                    }
                }
            }
        }

    # 打印调试信息
    print("发送的数据结构:")
    print(json.dumps(data, ensure_ascii=False, indent=2))

    response = requests.post(url, headers=headers, json=data)
    return response.json()

# ==================== 执行 JMeter 测试 ====================
def run_jmeter_script(jmx_file):
    """运行 JMeter 脚本"""
    start_time = time.time()
    current_time = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
    name = os.path.basename(jmx_file)

    result_csv = f"{CSV_LOG_DIR}/{name}_{current_time}.csv"
    result_log = f"{JMETER_LOG_DIR}/{name}_{current_time}.log"

    # 创建日志目录
    os.makedirs(os.path.dirname(result_csv), exist_ok=True)
    os.makedirs(os.path.dirname(result_log), exist_ok=True)

    cmd = [
        JMETER_BIN,
        "-n", "-t", jmx_file,
        "-l", result_csv,
        "-j", result_log
    ]

    print(f"🚀 开始执行:{name}")
    try:
        subprocess.run(cmd, check=True, timeout=TEST_TIMEOUT)
        duration = time.time() - start_time
        print(f"✅ 完成执行:{name},耗时:{format_duration(duration)}")
        return result_csv, duration
    except subprocess.TimeoutExpired:
        print(f"⏰ 执行超时:{name}")
        return None, None
    except subprocess.CalledProcessError as e:
        print(f"❌ 执行失败:{name},错误:{e}")
        return None, None

# ==================== 分析测试结果 ====================
def analyze_csv_results(csv_file):
    """分析 CSV 结果文件"""
    try:
        df = pd.read_csv(csv_file)

        total_requests = len(df)
        success_requests = len(df[df['success'] == True])
        failed_requests = len(df[df['success'] == False])
        success_rate = (success_requests / total_requests * 100) if total_requests > 0 else 0
        avg_response_time = df['elapsed'].mean() if 'elapsed' in df.columns else 0

        # 获取失败详情
        failed_details = []
        if failed_requests > 0:
            failed = df[df["success"] == False]
            for _, row in failed.iterrows():
                failed_details.append({
                    'label': str(row.get("label")),
                    'responseCode': str(row.get("responseCode")),
                    'failureMessage': str(row.get("failureMessage")),
                    'url': str(row.get("URL"))
                })

        return {
            'total': total_requests,
            'success': success_requests,
            'failed': failed_requests,
            'success_rate': success_rate,
            'avg_response_time': avg_response_time,
            'failed_details': failed_details
        }
    except Exception as e:
        print(f"分析 CSV 文件失败:{str(e)}")
        return None

# ==================== 主函数 ====================
def main():
    """主函数"""
    print("🚀 JMeter 自动化测试开始")
    start_time = time.time()

    # 获取所有 JMX 文件
    jmx_files = sorted([
        os.path.join(TEST_SCRIPT_DIR, f)
        for f in os.listdir(TEST_SCRIPT_DIR)
        if f.endswith(".jmx")
    ])

    if not jmx_files:
        print(f"⚠️ 警告:在 {TEST_SCRIPT_DIR} 中没有找到任何 .jmx 文件")
        return

    print(f"📋 找到 {len(jmx_files)} 个测试脚本")

    # 执行所有测试
    results = []
    for jmx in jmx_files:
        result_csv, duration = run_jmeter_script(jmx)
        analysis = analyze_csv_results(result_csv) if result_csv else None

        results.append({
            'name': os.path.basename(jmx),
            'duration': duration or 0,
            'analysis': analysis,
            'status': 'success' if analysis else 'failed'
        })

    # 生成并发送报告
    # ... 详见完整代码

    print("🎉 所有任务完成!")

if __name__ == "__main__":
    main()

常见问题

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

错误信息:

复制代码
CannotResolveClassException: kg.apc.jmeter.vizualizers.CorrectedResultCollector

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

解决方案:

bash 复制代码
# 清理 JMX 文件中的可视化组件
sed -i '/<kg\.apc\.jmeter\.vizualizers/,/<\/kg\.apc\.jmeter\.vizualizers/d' your-test.jmx

2. 飞书消息发送失败

错误代码: code: 19021

原因: 签名验证失败

解决方案:

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

3. CSV 文件无法解析

错误信息: KeyError: 'success'

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

解决方案:

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

xml 复制代码
<ResultCollector guiclass="SimpleDataWriter" testclass="ResultCollector">
  <objProp>
    <value class="SampleSaveConfiguration">
      <time>true</time>
      <latency>true</latency>
      <success>true</success>
      <label>true</label>
      <code>true</code>
      <message>true</message>
      <responseData>false</responseData>
    </value>
  </objProp>
</ResultCollector>

4. 权限问题

错误信息: Permission denied

解决方案:

bash 复制代码
# 给脚本执行权限
chmod +x jmeter_automation.py

# 给目录写权限
chmod -R 755 /home/your-user/cicd

最佳实践

1. 安全性建议

1.1 敏感信息管理

不推荐:硬编码

python 复制代码
webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/xxx"  # ❌
secret = "my-secret-key"  # ❌

推荐:使用环境变量

python 复制代码
import os

webhook = os.getenv('FEISHU_WEBHOOK')
secret = os.getenv('FEISHU_SECRET')
bash 复制代码
# 设置环境变量
export FEISHU_WEBHOOK="https://open.feishu.cn/..."
export FEISHU_SECRET="your-secret"

# 或写入 .env 文件
echo 'FEISHU_WEBHOOK="https://..."' >> .env
echo 'FEISHU_SECRET="xxx"' >> .env

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

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

2. 性能优化

2.1 并行执行测试(可选)
python 复制代码
from concurrent.futures import ThreadPoolExecutor

def main():
    jmx_files = [...]

    # 使用线程池并行执行(谨慎使用,可能导致资源竞争)
    with ThreadPoolExecutor(max_workers=3) as executor:
        futures = [executor.submit(run_jmeter_script, jmx) for jmx in jmx_files]
        results = [f.result() for f in futures]
2.2 日志清理
bash 复制代码
# 定期清理旧日志(保留最近30天)
find /home/your-user/cicd/test/logs -name "*.csv" -mtime +30 -delete
find /home/your-user/cicd/test/testscript/logs -name "*.log" -mtime +30 -delete

3. 监控与告警

3.1 添加失败重试机制
python 复制代码
def run_jmeter_script_with_retry(jmx_file, max_retries=3):
    """带重试的 JMeter 执行"""
    for attempt in range(max_retries):
        result_csv, duration = run_jmeter_script(jmx_file)
        if result_csv:
            return result_csv, duration

        if attempt < max_retries - 1:
            print(f"重试 {attempt + 1}/{max_retries}...")
            time.sleep(5)

    return None, None
3.2 添加失败率告警
python 复制代码
def check_alert(results):
    """检查是否需要告警"""
    total_failed = sum([r['analysis']['failed'] for r in results if r['analysis']])
    total_requests = sum([r['analysis']['total'] for r in results if r['analysis']])

    fail_rate = total_failed / total_requests if total_requests > 0 else 0

    # 失败率超过10%时特殊提醒
    if fail_rate > 0.1:
        send_alert_message(f"⚠️ 测试失败率过高:{fail_rate*100:.1f}%")

4. 目录规范

复制代码
project/
├── config.py              # 配置文件(加入 .gitignore)
├── config.example.py      # 配置模板(提交到 git)
├── jmeter_automation.py      # 主程序
├── clean_jmx.py           # 工具脚本
├── requirements.txt       # Python 依赖
├── README.md              # 说明文档
├── test/
│   ├── testscript/        # 测试脚本
│   └── logs/              # 测试结果
└── docs/                  # 文档目录
    └── 使用指南.md

5. JMX 文件管理

5.1 命名规范
复制代码
建议格式:{项目名}_{模块}_{测试类型}.jmx

示例:
- ProjectA_Login_API.jmx
- ProjectA_Payment_Performance.jmx
- ProjectB_Search_Stress.jmx
5.2 版本控制
bash 复制代码
# 将 JMX 文件纳入 Git 管理
git add test/testscript/*.jmx
git commit -m "feat: 新增支付接口测试脚本"

总结

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

✅ 搭建 JMeter 自动化测试环境

✅ 配置飞书机器人实现消息通知

✅ 编写 Python 脚本批量执行测试

✅ 分析测试结果并生成报告

✅ 处理常见问题和故障排查

下一步建议

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

参考资料


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

相关推荐
mudtools2 天前
在飞书 SDK 上用 Microsoft Agent Framework 搭一个能干活的工作搭子
人工智能·ai·.net·飞书·agent
极致了3 天前
飞书插件、RPA、API三条路的真实分界线
飞书·rpa
玩泥巴的4 天前
在飞书 SDK 上用 Microsoft Agent Framework 搭一个能干活的工作搭子
ai·.net·飞书·agent
玩泥巴的5 天前
一份声明,多份产物:飞书 SDK 的 AI 工具面是怎么生成的
ai·.net·飞书·agent
OpenPortal认证计费系统7 天前
基于 飞书认证 通过 华为、H3C 结合 OpenPortal认证计费系统 实现 网络准入 飞书授权 实名认证
华为·飞书·h3c·portal认证·openportal
banyoyo8 天前
jmeter测试使用方法
jmeter
前进的李工8 天前
飞书企业知识库设计+后端高频八股
数据库·redis·后端·mysql·性能优化·飞书·rag
汪汪8888888 天前
jmeter压测下载功能影响本地内存的方案
jmeter
长弓三石8 天前
钉钉与飞书机器人接入企业级智能体过程及排障实录
人工智能·机器人·钉钉·飞书·企业级harness