基于Jmeter的性能测试框架搭建
谈到性能测试部分公司连专门用于性能测试的环境都没有更别提性能测试框架/平台了。下面笔者就“基于Jmeter的性能测试框架搭建”这个话题谈谈自己的一些想法。工具JmeterInfluxdbGrafanaTelegrafJenkinsAntGitlab理念测试人员只需专注脚本编写及性能结果分析。脚本提交Gitlab后自动触发构建性能结果实时展现。性能测试脚本统一管理。性能测试框架实现方法依赖Jmeter的Backend Listener监听器采集tps,响应时间cpu,内存等信息至Influxdb时序数据库然后再通过Grafana展现性能结果。依赖Jenkins的webhook插件监听push事件即push脚本至gitlab则触发Ant构建。一、脚本上传小工具开发压测小工具开始构建为了简便测试人员操作特开发此压测小工具实现功能如下上传脚本前初始化本地git仓库。克隆git仓库。根据上传的脚本修改build.xml文件。push脚本和build.xml文件。使用JGit访问Gitlabdom4j处理xml文件。pom.xml配置如下?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.tool/groupId artifactIdperformanceTestTool/artifactId version1.0-SNAPSHOT/version build plugins plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId configuration source6/source target6/target /configuration /plugin /plugins /build repositories repository idjgit-repository/id urlhttps://repo.eclipse.org/content/groups/releases//url /repository /repositories !-- Core Library -- dependencies dependency groupIdorg.eclipse.jgit/groupId artifactIdorg.eclipse.jgit/artifactId version4.11.0.201803080745-r/version /dependency !-- Smart HTTP Servlet -- dependency groupIdorg.eclipse.jgit/groupId artifactIdorg.eclipse.jgit.http.server/artifactId version4.11.0.201803080745-r/version /dependency !-- AWT UI Helpers -- dependency groupIdorg.eclipse.jgit/groupId artifactIdorg.eclipse.jgit.ui/artifactId version4.11.0.201803080745-r/version /dependency !-- JUnit Test Support -- dependency groupIdorg.eclipse.jgit/groupId artifactIdorg.eclipse.jgit.junit/artifactId version4.11.0.201803080745-r/version /dependency dependency groupIddom4j/groupId artifactIddom4j/artifactId version1.6.1/version /dependency /dependencies /projectclone项目至本地仓库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 version1.0 encodingUTF-8 standaloneno? project basedir. defaultrun nameAnt tstamp format patternyyyyMMddhhmm propertytime/ /tstamp !-- jmeter路径-- property namejmeter.home valueD:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1/ !-- jmeter jtl测试报告生成路径-- property namejmeter.result.jtl.dir valueD:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\report\jtl/ !-- jmeter html测试报告生成路径-- property namejmeter.result.html.dir valueD:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\report\html/ !-- 参数化-- property nameReportName valueTestReport/ property namejmeter.result.jtlName value${jmeter.result.jtl.dir}/${ReportName}${time}.jtl/ property namejmeter.result.htmlName value${jmeter.result.html.dir}/${ReportName}${time}.html/ target namerun antcall targettest/ !--性能脚本构建时生成报告时间太长注释掉 -- !-- antcall targetreport/ -- /target target nametest taskdef classnameorg.programmerplanet.ant.taskdefs.jmeter.JMeterTask namejmeter/ jmeter jmeterhome${jmeter.home} resultlog${jmeter.result.jtlName} !-- 构建路径与jenkins上工作空间配置保持一致 -- testplans dirD:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\jenkins_jobworkspace includes测试.jmx/ property namejmeter.save.saveservice.output_format valuexml/ /jmeter /target target namereport 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 namecollapse.png/ include nameexpand.png/ /fileset /copy /target /project通过分析上面的build.xml文件发现构建脚本由includes的值来定义如果值为“*.jmx”则会构建dir目录下所有的jmx文件。由于我们只需构建上传的脚本那有必要修改build文件使includes的值等于上传的脚本名称。testplans dirD:\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 PluginGit pluginGitLab PluginGitlab Hook Plugin可以在线安装也可以下载本地安装下载地址。jenkins-系统配置-全局工具配置。配置jdk,git,ant。jenkins-项目-配置。自定义空间与build.xml设置的构建路径保持一致jenkins构建时会把git仓库pull到该路径下。testplans dirD:\tools\PerformanceTesting\Jmeter_influxdb_grafana\apache-jmeter-3.1\TestCase\jenkins_jobworkspace includes测试.jmx/AI写代码注意下图的Targets需同build.xml文件一致。target namerun antcall targettest/ !--性能脚本构建时生成报告时间太长注释掉 -- !-- antcall targetreport/ -- /target构建由于依赖webhook 来监听push事件触发构建拷贝下图的URL并在“高级”选项中生成“Secret token”后续在gitlab添加webhook。构建触发器构建触发器gitlab-webhook配置。由于只需监听push事件所有下图只勾选了Push events“”。添加webhook后点击“Test”进行测试如果返回200/201则表明webhook配置成功。webhookwebhook-test如果不想使用Secret token配置webhook也可按以下方式来配置打开jenkins的“设置”页面找到API Token然后在gitlab上添加webhook url即可结构如下图2所示(UserId:APITokenjenkins构建器url)。API Tokenwebhook.png三、配置Influxdb,Grafana,TelegrafInfluxdbGrafanaTelegraf在笔者的另一篇文章Jmeter排忧解难—性能测试 监控有提及百度也大把文章此处不再详述。四、编写测试脚本使用jmeter编写一个简单的测试脚本来进行测试主要依赖Backend Listener监听器来集成influxdb。测试脚本测试脚本五、性能结果分析运行“一、脚本上传小工具开发”提及的压测小工具就可以对性能结果做实时监控了。下图1仅对tps和响应时间做采集由于笔者未在被测服务器上安装Telegraf所以cpu,内存等数据暂不采集有兴趣的童鞋可以自行探索。更详细的监控结果如图2所示。性能测试结果性能测试结果六、构建日志登录jenkins可以查看详细的构建日志。Jenkins构建日志后续改进其实以上框架还存在不少待改进之处笔者后续再逐步解决。Grafana性能图表实时展现测试过程中需实时截图形成测试报告不够人性化。解决方案自动生成测试报告并邮件通知。Grafana性能图表需测试人员实时监控人力成本较高。解决方案自动生成测试报告并邮件通知。多脚本构建的话无法区分Grafana展现的性能图表对应哪个脚本。解决方案传参区分脚本并生成每个接口对应的测试报告。如果考虑持续监控可加入预警功能。解决方案依赖Grafana的预警功能。未能自动生成测试报告。解决方案自动生成测试报告并邮件通知。需登录jenkins停止脚本构建操作不够便利。解决方案前端增加停止构建操作。每次只能提交一个脚本进行构建。解决方案支持批量构建。最后下方这份完整的软件测试 视频教程已经整理上传完成需要的朋友们可以自行领取【保证100%免费】软件测试面试文档我们学习必然是为了找到高薪的工作下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料并且有字节大佬给出了权威的解答刷完这一套面试资料相信大家都能找到满意的工作。