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

引言

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

工具

Jmeter
Influxdb
Grafana
Telegraf
Jenkins
Ant
Gitlab

理念

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


    基于Jmeter的性能测试框架搭建_第1张图片
    性能测试框架

实现方法

  • 依赖Jmeter的Backend Listener监听器,采集tps,响应时间,cpu,内存等信息至Influxdb时序数据库,然后再通过Grafana展现性能结果。
  • 依赖Jenkins的webhook插件监听push事件,即push脚本至gitlab则触发Ant构建。
一、脚本上传小工具开发

基于Jmeter的性能测试框架搭建_第2张图片
压测小工具

基于Jmeter的性能测试框架搭建_第3张图片
开始构建

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

  • 上传脚本前,初始化本地git仓库。
  • 克隆git仓库。
  • 根据上传的脚本修改build.xml文件。
  • push脚本和build.xml文件。

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



    4.0.0

    com.tool
    performanceTestTool
    1.0-SNAPSHOT
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    6
                    6
                
            
        
    


    
        
            jgit-repository
            https://repo.eclipse.org/content/groups/releases/
        
    

    
    
        
            org.eclipse.jgit
            org.eclipse.jgit
            4.11.0.201803080745-r
        

        
        
            org.eclipse.jgit
            org.eclipse.jgit.http.server
            4.11.0.201803080745-r
        

        
        
            org.eclipse.jgit
            org.eclipse.jgit.ui
            4.11.0.201803080745-r
        

        
        
            org.eclipse.jgit
            org.eclipse.jgit.junit
            4.11.0.201803080745-r
        

        
            dom4j
            dom4j
            1.6.1
        
    


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文件配置:



    
        
    
      
    
     
    
    
    
      
    
    
    
    
    
        
        
        
    
    
    
        
        
             
            
            

        
    
        
    
        
                 
        
            
                
                
            
        
    


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


修改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。


    基于Jmeter的性能测试框架搭建_第4张图片
    jdk

    基于Jmeter的性能测试框架搭建_第5张图片
    git&ant
  • jenkins-项目-配置。
    自定义空间与build.xml设置的构建路径保持一致,jenkins构建时,会把git仓库pull到该路径下。

基于Jmeter的性能测试框架搭建_第6张图片
自定义空间

基于Jmeter的性能测试框架搭建_第7张图片
git源码管理

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

    
        
        
        
    
基于Jmeter的性能测试框架搭建_第8张图片
构建

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


基于Jmeter的性能测试框架搭建_第9张图片
构建触发器

基于Jmeter的性能测试框架搭建_第10张图片
构建触发器
  • gitlab-webhook配置。
    由于只需监听push事件,所有下图只勾选了Push events“”。添加webhook后,点击“Test”进行测试,如果返回200/201,则表明webhook配置成功。


    基于Jmeter的性能测试框架搭建_第11张图片
    webhook

    webhook-test

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


    基于Jmeter的性能测试框架搭建_第12张图片
    API Token

    webhook.png
三、配置Influxdb,Grafana,Telegraf

Influxdb+Grafana+Telegraf在笔者的另一篇文章有提及,百度也大把文章,此处不再详述。

四、编写测试脚本

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


基于Jmeter的性能测试框架搭建_第13张图片
测试脚本

基于Jmeter的性能测试框架搭建_第14张图片
测试脚本
五、性能结果分析

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


基于Jmeter的性能测试框架搭建_第15张图片
性能测试结果

基于Jmeter的性能测试框架搭建_第16张图片
性能测试结果
六、构建日志

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


基于Jmeter的性能测试框架搭建_第17张图片
Jenkins构建日志

后续改进

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

  • Grafana性能图表实时展现,测试过程中需实时截图形成测试报告,不够人性化。
    解决方案:自动生成测试报告并邮件通知。
  • Grafana性能图表需测试人员实时监控,人力成本较高。
    解决方案:自动生成测试报告并邮件通知。
  • 多脚本构建的话,无法区分Grafana展现的性能图表对应哪个脚本。
    解决方案:传参区分脚本,并生成每个接口对应的测试报告。
  • 如果考虑持续监控,可加入预警功能。
    解决方案:依赖Grafana的预警功能。
  • 未能自动生成测试报告。
    解决方案:自动生成测试报告并邮件通知。
  • 需登录jenkins停止脚本构建,操作不够便利。
    解决方案:前端增加停止构建操作。
  • 每次只能提交一个脚本进行构建。
    解决方案:支持批量构建。

《基于Jmeter的性能测试框架搭建》改进一
《基于Jmeter的性能测试框架搭建》改进二

你可能感兴趣的:(基于Jmeter的性能测试框架搭建)