JMeter 与 Python 容器化自动化测试
要把 JMeter 和 Python 结合到容器(Docker)中,实现接口自动化测试的完整方案,核心是通过容器化统一测试环境,同时发挥 JMeter 压测能力和 Python 灵活的脚本处理能力。
Dockerfile 构建、测试脚本示例、容器运行命令
一、方案设计思路
-
容器基础环境:基于官方 Python 镜像,安装 JMeter 及依赖,保证环境一致性。
-
分工明确:
-
Python:负责测试数据生成、接口前置/后置处理、测试结果解析/入库、报告生成。
-
JMeter:负责接口请求发送、并发压测、基础断言。
- 交互方式:Python 通过调用 JMeter 命令行执行测试计划(.jmx 文件),并读取 JMeter 输出的测试结果(如 .jtl 文件)进行二次处理。
二、完整实现步骤
- 项目目录结构
先按如下结构整理文件,确保容器内路径统一:
bash
api-auto-test/
├── Dockerfile # 构建容器镜像的配置文件
├── jmeter-test/ # JMeter 测试计划目录
│ └── api-test.jmx # JMeter 接口测试脚本
├── python-script/ # Python 脚本目录
│ └── run_test.py # 执行测试、处理结果的 Python 脚本
└── requirements.txt # Python 依赖
2、编写 Dockerfile(构建包含 Python + JMeter 的镜像)
python
# 基础镜像:Python 3.9(兼容大部分场景)
FROM python:3.9-slim
# 维护者信息
LABEL maintainer="your-name@example.com"
# 设置环境变量
ENV JMETER_VERSION=5.6.3
ENV JMETER_HOME=/opt/apache-jmeter-${JMETER_VERSION}
ENV PATH=$PATH:$JMETER_HOME/bin
# 安装依赖(JMeter 需 Java 环境)
RUN apt-get update && apt-get install -y \
openjdk-17-jre \
wget \
unzip \
&& rm -rf /var/lib/apt/lists/*
# 下载并解压 JMeter
RUN wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.zip \
&& unzip apache-jmeter-${JMETER_VERSION}.zip -d /opt/ \
&& rm apache-jmeter-${JMETER_VERSION}.zip
# 设置工作目录
WORKDIR /app
# 复制 Python 依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制所有测试文件到容器内
COPY . /app
# 容器启动默认执行 Python 测试脚本
CMD ["python", "python-script/run_test.py"]
3.编写 Python 依赖文件(requirements.txt)
python
pandas>=2.0.0 # 解析 JMeter 测试结果
openpyxl>=3.1.0 # 生成 Excel 测试报告
requests>=2.31.0 # 可选:Python 直接调用接口的依赖
- 编写核心文件
(1)JMeter 测试计划示例(jmeter-test/api-test.jmx)
你可以先通过 JMeter 图形界面录制/编写接口测试脚本,保存为 api-test.jmx,核心要点:
-
配置 HTTP 请求(目标接口地址、请求方法、参数)。
-
添加断言(如响应码 200、响应内容包含指定字段)。
-
配置结果输出:添加「查看结果树」「聚合报告」,并设置将结果输出到 ./result.jtl 文件(CSV 格式)。
(2)Python 执行脚本(python-script/<run_test.py>)
该脚本负责调用 JMeter 执行测试,解析结果并生成报告:
python
import os
import subprocess
import pandas as pd
from datetime import datetime
# 1. 定义路径(与容器内路径一致)
JMETER_BIN = "jmeter"
JMETER_SCRIPT = "/app/jmeter-test/api-test.jmx"
JMETER_RESULT = "/app/result.jtl"
REPORT_FILE = "/app/test-report.xlsx"
def run_jmeter_test():
"""调用 JMeter 执行接口测试"""
print("开始执行 JMeter 接口测试...")
# JMeter 命令行参数说明:
# -n:非 GUI 模式执行
# -t:指定测试计划文件
# -l:指定结果输出文件
# -j:指定日志文件
cmd = [
JMETER_BIN,
"-n",
"-t", JMETER_SCRIPT,
"-l", JMETER_RESULT,
"-j", "/app/jmeter.log"
]
try:
# 执行 JMeter 命令
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
print("JMeter 测试执行完成!")
return True
except subprocess.CalledProcessError as e:
print(f"JMeter 执行失败:{e.stderr}")
return False
def parse_jmeter_result():
"""解析 JMeter 生成的 .jtl 结果文件"""
if not os.path.exists(JMETER_RESULT):
print("未找到 JMeter 测试结果文件!")
return None
# 读取 JTL 文件(JMeter 默认 CSV 格式)
# 核心字段说明:time=响应时间(ms)、success=是否成功、responseCode=响应码、label=接口名称
df = pd.read_csv(
JMETER_RESULT,
usecols=["label", "time", "success", "responseCode", "responseMessage"],
dtype={"time": int, "success": bool, "responseCode": str}
)
# 统计结果
total = len(df)
pass_count = len(df[df["success"] == True])
fail_count = total - pass_count
avg_response_time = df["time"].mean() if total > 0 else 0
# 生成汇总数据
summary = {
"测试时间": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"总用例数": total,
"通过数": pass_count,
"失败数": fail_count,
"通过率": f"{pass_count/total*100:.2f}%" if total > 0 else "0%",
"平均响应时间(ms)": round(avg_response_time, 2)
}
return {"summary": summary, "detail": df}
def generate_report(result_data):
"""生成 Excel 测试报告"""
if not result_data:
return
# 使用 ExcelWriter 写入多个 Sheet
with pd.ExcelWriter(REPORT_FILE, engine="openpyxl") as writer:
# 汇总信息写入 "汇总" Sheet
summary_df = pd.DataFrame([result_data["summary"]])
summary_df.to_excel(writer, sheet_name="汇总", index=False)
# 详细结果写入 "详细用例" Sheet
result_data["detail"].to_excel(writer, sheet_name="详细用例", index=False)
print(f"测试报告已生成:{REPORT_FILE}")
if __name__ == "__main__":
# 执行流程:运行 JMeter → 解析结果 → 生成报告
if run_jmeter_test():
result = parse_jmeter_result()
if result:
generate_report(result)
# 打印汇总信息
print("\n===== 测试汇总 =====")
for k, v in result["summary"].items():
print(f"{k}: {v}")
else:
print("测试执行失败,未生成报告!")
构建并运行容器
(1)构建镜像
在项目根目录执行以下命令(确保 Docker 已启动):
docker build -t api-auto-test:v1 .
(2)运行容器
运行容器,并将测试报告挂载到本地目录(方便查看)
docker run -v /本地目录:/app api-auto-test:v1
- 替换 /本地目录 为你本地的文件夹路径(如 Windows 下的 D:\test-report),容器内生成的 Excel 报告会同步到该目录。
三、关键说明
- 环境适配:
-
JMeter 版本可根据需求修改(Dockerfile 中的 JMETER_VERSION)。
-
若需测试内网接口,运行容器时需添加 --network host(宿主机网络模式)。
- 脚本扩展:
-
Python 脚本可增加:测试数据生成(如随机参数)、接口前置条件(如登录获取 token)、结果推送(如发送邮件/钉钉)。
-
JMeter 脚本可增加:参数化、关联、并发线程组(压测场景)。
- 排错技巧:
-
查看 JMeter 日志:docker exec -it 容器ID cat /app/jmeter.log。
-
进入容器调试:docker exec -it 容器ID /bin/bash。
-
核心方案是基于 Docker 构建包含 Python + JMeter 的统一环境,避免本地环境差异问题。
-
分工逻辑:Python 负责测试流程控制和结果处理,JMeter 负责接口请求发送和基础断言。
-
关键操作:通过 Dockerfile 构建镜像 → 运行容器执行测试 → 挂载目录获取测试报告。
这套方案既保留了 JMeter 对接口测试的原生支持,又利用 Python 实现了灵活的结果处理和扩展,适合接口自动化测试的落地。