【无标题】

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 实现了灵活的结果处理和扩展,适合接口自动化测试的落地。

相关推荐
CesareCheung2 小时前
Jmeter压测时如何设置只登录一次后压其他的接口
jmeter·性能优化
内存不泄露2 小时前
基于 Spring Boot 的医院预约挂号系统(全端协同)设计与实现
java·vue.js·spring boot·python·flask
码农幻想梦2 小时前
实验7 知识表示与推理
开发语言·人工智能·python
写代码的【黑咖啡】2 小时前
深入理解 Python 中的 SQLAlchemy
开发语言·python·oracle
未定义.2212 小时前
第1篇:0基础入门!Python+Selenium环境搭建与第一个自动化脚本
python·功能测试·selenium·自动化·jenkins·pytest
特行独立的猫2 小时前
python+Proxifier+mitmproxy实现监听本地网路所有的http请求
开发语言·爬虫·python·http
深蓝电商API2 小时前
Scrapy Spider 参数化:动态传入 start_urls 和自定义设置
爬虫·python·scrapy
CCPC不拿奖不改名2 小时前
基于FastAPI的API开发(爬虫的工作原理):从设计到部署详解+面试习题
爬虫·python·网络协议·tcp/ip·http·postman·fastapi
___波子 Pro Max.2 小时前
Python中Optional类型的作用解析
python