news 2026/4/25 0:23:37

基于Jmeter的性能测试框架搭建

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Jmeter的性能测试框架搭建

谈到性能测试,部分公司连专门用于性能测试的环境都没有,更别提性能测试框架/平台了。下面,笔者就“基于Jmeter的性能测试框架搭建”这个话题,谈谈自己的一些想法。

工具

Jmeter
Influxdb
Grafana
Telegraf
Jenkins
Ant
Gitlab

理念
  • 测试人员只需专注脚本编写及性能结果分析。脚本提交Gitlab后自动触发构建,性能结果实时展现。

  • 性能测试脚本统一管理。

  • 性能测试框架

实现方法
  • 依赖Jmeter的Backend Listener监听器,采集tps,响应时间,cpu,内存等信息至Influxdb时序数据库,然后再通过Grafana展现性能结果。

  • 依赖Jenkins的webhook插件监听push事件,即push脚本至gitlab则触发Ant构建。

一、脚本上传小工具开发

压测小工具

开始构建

为了简便测试人员操作,特开发此压测小工具,实现功能如下:

  • 上传脚本前,初始化本地git仓库。

  • 克隆git仓库。

  • 根据上传的脚本修改build.xml文件。

  • push脚本和build.xml文件。

使用JGit访问Gitlab,dom4j处理xml文件。pom.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tool</groupId> <artifactId>performanceTestTool</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>6</source> <target>6</target> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>jgit-repository</id> <url>https://repo.eclipse.org/content/groups/releases/</url> </repository> </repositories> <!-- Core Library --> <dependencies> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit</artifactId> <version>4.11.0.201803080745-r</version> </dependency> <!-- Smart HTTP Servlet --> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.http.server</artifactId> <version>4.11.0.201803080745-r</version> </dependency> <!-- AWT UI Helpers --> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ui</artifactId> <version>4.11.0.201803080745-r</version> </dependency> <!-- JUnit Test Support --> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.junit</artifactId> <version>4.11.0.201803080745-r</version> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> </dependencies> </project>

clone项目至本地仓库:

public static void cloneProject() throws Exception { //每次clone前先初始化 Util.deletefile(localProject); File file = new File(localProject); try { //克隆代码库命令 CloneCommand cloneCommand = Git.cloneRepository(); cloneCommand.setURI(remoteRepoURI) //设置远程URI .setBranch("master") //设置clone下来的分支 .setDirectory(file) //设置下载存放路径 .setCredentialsProvider(usernamePasswordCredentialsProvider) .call(); } catch (GitAPIException e) { e.printStackTrace(); } }

pull操作:

public static void pullFiles() throws IOException, GitAPIException { //git仓库地址 Git git = new Git(new FileRepository(localProject+"/.git")); git.pull().setRemoteBranchName("master"). setCredentialsProvider(usernamePasswordCredentialsProvider).call(); }

push 操作:

public static void pushFiles(String filePath,String commitMess) throws IOException, GitAPIException { File fileFrom = new File(filePath); File fileTemp = new File(localProject); File fileTo = new File(fileTemp.getAbsolutePath()+"/"+fileFrom.getName()); fileTo.createNewFile(); Util.copyFiles(fileFrom,fileTo); //拷贝脚本文件至git本地仓库 Repository rep = new FileRepository(localProject+"\\.git"); Git git1 = new Git(rep); git1.add().addFilepattern(fileFrom.getName()).call(); //此处必须使用本地仓库中需推送的文件名 git1.add().addFilepattern("build.xml").call(); //push修改后的build文件 //提交 git1.commit().setMessage(commitMess).call(); git1.push().setCredentialsProvider(usernamePasswordCredentialsProvider).call(); }

build.xml文件配置:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <project basedir="." default="run" name="Ant"> <tstamp> <format pattern="yyyyMMddhhmm" property="time"/> </tstamp> <!-- jmeter路径--> <property name="jmeter.home" value="D:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1"/> <!-- jmeter jtl测试报告生成路径--> <property name="jmeter.result.jtl.dir" value="D:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\report\jtl"/> <!-- jmeter html测试报告生成路径--> <property name="jmeter.result.html.dir" value="D:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\report\html"/> <!-- 参数化--> <property name="ReportName" value="TestReport"/> <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}${time}.jtl"/> <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${time}.html"/> <target name="run"> <antcall target="test"/> <!--性能脚本构建时,生成报告时间太长,注释掉 --> <!-- antcall target="report"/ --> </target> <target name="test"> <taskdef classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" name="jmeter"/> <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}"> <!-- 构建路径,与jenkins上工作空间配置保持一致 --> <testplans dir="D:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\jenkins_jobworkspace" includes="测试.jmx"/> <property name="jmeter.save.saveservice.output_format" value="xml"/> </jmeter> </target> <target name="report"> <xslt in="${jmeter.result.jtlName}" out="${jmeter.result.htmlName}" style="${jmeter.home}/extras/jmeter.results.shanhe.me.xsl"/> <!-- 测试报告--> <copy todir="${jmeter.result.html.dir}"> <fileset dir="${jmeter.home}/extras"> <include name="collapse.png"/> <include name="expand.png"/> </fileset> </copy> </target> </project>

通过分析上面的build.xml文件,发现构建脚本由includes的值来定义,如果值为“*.jmx”,则会构建dir目录下所有的jmx文件。由于我们只需构建上传的脚本,那有必要修改build文件,使includes的值等于上传的脚本名称。

<testplans dir="D:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\jenkins_jobworkspace" includes="测试.jmx"/>

修改build文件的includes值:

public static void modifyBuild(String filePath,String modifyName) throws ParserConfigurationException, IOException, SAXException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new File(filePath)); // 读取xml文件 NodeList targetList = doc.getElementsByTagName("testplans"); //获取testplans节点 for (int i = 0; i < targetList.getLength(); i++) { Node case_node = targetList.item(i); // 第一个caseNo节点 Element elem0 = (Element) case_node; // caseNo节点对象 String target_name = elem0.getAttribute("includes"); System.out.println("修改前includes = " + target_name); // 节点属性 elem0.setAttribute("includes",modifyName); String target_name1 = elem0.getAttribute("includes"); System.out.println("修改后includes = " + target_name1); // 节点属性 } saveXml(filePath, doc); }

至此,第一阶段的工作已完成。当然,你也可以通过Git bash来push脚本触发构建,但是你得另外想办法来控制脚本的构建,因为Ant是根据build.xml文件来指定构建哪些脚本的。

二、配置Jenkins,Gitlab
  • 安装jenkins插件。
    Ant Plugin
    Git plugin
    GitLab Plugin
    Gitlab Hook Plugin
    可以在线安装,也可以下载本地安装,下载地址。

  • jenkins-系统配置-全局工具配置。
    配置jdk,git,ant。

  • jenkins-项目-配置。
    自定义空间与build.xml设置的构建路径保持一致,jenkins构建时,会把git仓库pull到该路径下。

<testplans dir="D:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\jenkins_jobworkspace" includes="测试.jmx"/>

AI写代码

注意下图的Targets需同build.xml文件一致。

<target name="run"> <antcall target="test"/> <!--性能脚本构建时,生成报告时间太长,注释掉 --> <!-- antcall target="report"/ --> </target>

构建

由于依赖webhook 来监听push事件触发构建,拷贝下图的URL,并在“高级”选项中生成“Secret token”,后续在gitlab添加webhook。

构建触发器

构建触发器

  • gitlab-webhook配置。
    由于只需监听push事件,所有下图只勾选了Push events“”。添加webhook后,点击“Test”进行测试,如果返回200/201,则表明webhook配置成功。

  • webhook

    webhook-test

    如果不想使用Secret token配置webhook,也可按以下方式来配置:
    打开jenkins的“设置”页面,找到API Token,然后在gitlab上添加webhook url即可,结构如下图2所示(UserId:APIToken@jenkins构建器url)。

    API Token

    webhook.png

三、配置Influxdb,Grafana,Telegraf

Influxdb+Grafana+Telegraf在笔者的另一篇文章<Jmeter排忧解难—性能测试 监控>有提及,百度也大把文章,此处不再详述。

四、编写测试脚本

使用jmeter编写一个简单的测试脚本来进行测试,主要依赖Backend Listener监听器来集成influxdb。

测试脚本

测试脚本

五、性能结果分析

运行“一、脚本上传小工具开发”提及的压测小工具,就可以对性能结果做实时监控了。下图1仅对tps和响应时间做采集,由于笔者未在被测服务器上安装Telegraf,所以cpu,内存等数据暂不采集,有兴趣的童鞋可以自行探索。更详细的监控结果如图2所示。

性能测试结果

性能测试结果

六、构建日志

登录jenkins,可以查看详细的构建日志。

Jenkins构建日志

后续改进

其实以上框架还存在不少待改进之处,笔者后续再逐步解决。

  • Grafana性能图表实时展现,测试过程中需实时截图形成测试报告,不够人性化。
    解决方案:自动生成测试报告并邮件通知。

  • Grafana性能图表需测试人员实时监控,人力成本较高。
    解决方案:自动生成测试报告并邮件通知。

  • 多脚本构建的话,无法区分Grafana展现的性能图表对应哪个脚本。
    解决方案:传参区分脚本,并生成每个接口对应的测试报告。

  • 如果考虑持续监控,可加入预警功能。
    解决方案:依赖Grafana的预警功能。

  • 未能自动生成测试报告。
    解决方案:自动生成测试报告并邮件通知。

  • 需登录jenkins停止脚本构建,操作不够便利。
    解决方案:前端增加停止构建操作。

  • 每次只能提交一个脚本进行构建。
    解决方案:支持批量构建。

最后:下方这份完整的软件测试 视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​​件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 0:22:57

15门免费深度学习课程全解析:从入门到进阶

1. 深度学习入门指南&#xff1a;15门免费在线课程全解析深度学习正在重塑我们与技术互动的方式。从手机上的语音助手到医学影像分析&#xff0c;这项技术已经渗透到日常生活的方方面面。作为一名在AI领域工作多年的从业者&#xff0c;我经常被问到&#xff1a;"如何系统学…

作者头像 李华
网站建设 2026/4/25 0:20:55

LLM内存优化:RoMe架构的DRAM接口革新

1. 项目概述&#xff1a;面向LLM的DRAM接口革新在当今AI计算领域&#xff0c;大语言模型&#xff08;LLM&#xff09;对内存系统的需求正推动着DRAM架构的重新思考。传统DRAM接口设计基于一个基本假设&#xff1a;应用程序需要随机访问不同大小的数据块。这种假设催生了以缓存行…

作者头像 李华
网站建设 2026/4/25 0:14:12

用手机热点和网络调试助手,5分钟搞定ESP8266模块的TCP通信测试

5分钟极简测试&#xff1a;用手机热点快速验证ESP8266的TCP通信能力 刚拿到ESP8266模块时&#xff0c;最让人焦虑的莫过于不确定硬件是否正常工作。我曾见过不少开发者花几小时搭建复杂测试环境&#xff0c;最后发现只是AT指令格式错误。其实要验证基础通信功能&#xff0c;完全…

作者头像 李华
网站建设 2026/4/25 0:08:27

标普500超额收益预测与风险约束配置优化

预测股票市场收益&#xff0c;尤其是像标准普尔500指数这样的宽基指数&#xff0c;是量化金融领域的经典难题。Kaggle上的“Hull Tactical - Market Prediction”竞赛将这一难题置于机器学习实战的语境中&#xff0c;其目标超越了单纯的数值预测&#xff1a;要求参赛者构建一个…

作者头像 李华