【无标题】

JMeter 与 Python 容器化自动化测试

要把 JMeter 和 Python 结合到容器(Docker)中,实现接口自动化测试的完整方案,核心是通过容器化统一测试环境,同时发挥 JMeter 压测能力和 Python 灵活的脚本处理能力。

Dockerfile 构建、测试脚本示例、容器运行命令

一、方案设计思路

  1. 容器基础环境:基于官方 Python 镜像,安装 JMeter 及依赖,保证环境一致性。

  2. 分工明确:

  • Python:负责测试数据生成、接口前置/后置处理、测试结果解析/入库、报告生成。

  • JMeter:负责接口请求发送、并发压测、基础断言。

  1. 交互方式:Python 通过调用 JMeter 命令行执行测试计划(.jmx 文件),并读取 JMeter 输出的测试结果(如 .jtl 文件)进行二次处理。

二、完整实现步骤

  1. 项目目录结构

先按如下结构整理文件,确保容器内路径统一:

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. 编写核心文件
    (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 报告会同步到该目录。
    三、关键说明
  1. 环境适配:
  • JMeter 版本可根据需求修改(Dockerfile 中的 JMETER_VERSION)。

  • 若需测试内网接口,运行容器时需添加 --network host(宿主机网络模式)。

  1. 脚本扩展:
  • Python 脚本可增加:测试数据生成(如随机参数)、接口前置条件(如登录获取 token)、结果推送(如发送邮件/钉钉)。

  • JMeter 脚本可增加:参数化、关联、并发线程组(压测场景)。

  1. 排错技巧:
  • 查看 JMeter 日志:docker exec -it 容器ID cat /app/jmeter.log。

  • 进入容器调试:docker exec -it 容器ID /bin/bash。

  1. 核心方案是基于 Docker 构建包含 Python + JMeter 的统一环境,避免本地环境差异问题。

  2. 分工逻辑:Python 负责测试流程控制和结果处理,JMeter 负责接口请求发送和基础断言。

  3. 关键操作:通过 Dockerfile 构建镜像 → 运行容器执行测试 → 挂载目录获取测试报告。

这套方案既保留了 JMeter 对接口测试的原生支持,又利用 Python 实现了灵活的结果处理和扩展,适合接口自动化测试的落地。

相关推荐
rayufo3 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
Python 老手5 小时前
Python while 循环 极简核心讲解
java·python·算法
开源技术5 小时前
如何将本地LLM模型与Ollama和Python集成
开发语言·python
weixin_437044645 小时前
Netbox批量添加设备——堆叠设备
linux·网络·python
我有医保我先冲5 小时前
AI 时代 “任务完成“ 与 “专业能力“ 的区分:理论基础、行业影响与个人发展策略
人工智能·python·机器学习
测试开发Kevin6 小时前
小tip:换行符CRLF 和 LF 的区别以及二者在实际项目中的影响
java·开发语言·python
爱学习的阿磊6 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
阿狸OKay6 小时前
einops 库和 PyTorch 的 einsum 的语法
人工智能·pytorch·python
编码者卢布7 小时前
【Azure Storage Account】Azure Table Storage 跨区批量迁移方案
后端·python·flask
可触的未来,发芽的智生7 小时前
狂想:为AGI代称造字ta,《第三类智慧存在,神的赐名》
javascript·人工智能·python·神经网络·程序人生