JMeter二次开发--实现配置和运行UI自动化测试

  1. JMeter版本:3.3
  2. JMeter下载地址: https://archive.apache.org/dist/jmeter/binaries/
  3. Selenium版本:3.11
  4. JDK 1.8

>第1步:Maven工程创建

使用STS创建的Maven工程,忽略步骤

>第2步:pom.xml设置

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 2     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 3     <modelVersion>4.0.0</modelVersion>
 4     <groupId>com.test</groupId>
 5     <artifactId>Jmeter</artifactId>
 6     <version>0.0.1-SNAPSHOT</version>
 7
 8     <properties>
 9         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!--
10             源文件编码 -->
11         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><!--
12             文件拷贝时的 -->
13         <maven.compiler.encoding>UTF-8</maven.compiler.encoding><!-- 编译时的编码 -->
14         <selenium-version>3.11.0</selenium-version>
15     </properties>
16
17     <dependencies>
18         <!-- java jmeter依赖jar包 -->
19         <dependency>
20             <groupId>org.apache.jmeter</groupId>
21             <artifactId>ApacheJMeter_core</artifactId>
22             <version>3.3</version>
23         </dependency>
24         <dependency>
25             <groupId>org.apache.jmeter</groupId>
26             <artifactId>ApacheJMeter_java</artifactId>
27             <version>3.3</version>
28         </dependency>
29
30         <dependency>
31             <groupId>org.seleniumhq.selenium</groupId>
32             <artifactId>selenium-java</artifactId>
33             <version>${selenium-version}</version>
34         </dependency>
35
36         <dependency>
37             <groupId>org.seleniumhq.selenium</groupId>
38             <artifactId>selenium-server</artifactId>
39             <version>${selenium-version}</version>
40         </dependency>
41
42         <dependency>
43             <groupId>org.seleniumhq.selenium</groupId>
44             <artifactId>selenium-remote-driver</artifactId>
45             <version>${selenium-version}</version>
46         </dependency>
47     </dependencies>
48
49     <build>
50         <plugins>
51             <plugin>
52                 <groupId>org.apache.maven.plugins</groupId>
53                 <artifactId>maven-compiler-plugin</artifactId>
54                 <configuration>
55                     <source>1.8</source>
56                     <target>1.8</target>
57                 </configuration>
58             </plugin>
59
60             <plugin>
61                 <artifactId>maven-assembly-plugin</artifactId>
62                 <configuration>
63                     <descriptor>src/main/assembly/assembly.xml</descriptor>
64                 </configuration>
65                 <executions>
66                     <execution>
67                         <id>make-assembly</id>
68                         <phase>package</phase>
69                         <goals>
70                             <goal>single</goal>
71                         </goals>
72                     </execution>
73                 </executions>
74             </plugin>
75         </plugins>
76     </build>
77 </project>

pom.xml

>第3步:添加assembly.xml用于导出工程的依赖

<!-- Copyright 1999-2011 Alibaba Group. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -->
<assembly><id>assembly</id><formats><format>tar.gz</format></formats><includeBaseDirectory>true</includeBaseDirectory><dependencySets><dependencySet><outputDirectory>lib</outputDirectory></dependencySet></dependencySets>
</assembly>

assembly.xml

>第4步:创建基于PO的测试类:Login.java

  1 package com.test;
  2
  3 import java.util.concurrent.TimeUnit;
  4
  5 import org.apache.poi.util.SystemOutLogger;
  6 import org.openqa.selenium.By;
  7 import org.openqa.selenium.WebDriver;
  8 import org.openqa.selenium.WebElement;
  9 import org.openqa.selenium.interactions.Action;
 10 import org.openqa.selenium.interactions.Actions;
 11 import org.openqa.selenium.support.CacheLookup;
 12 import org.openqa.selenium.support.FindBy;
 13 import org.openqa.selenium.support.How;
 14 import org.openqa.selenium.support.PageFactory;
 15 import org.openqa.selenium.support.pagefactory.AjaxElementLocatorFactory;
 16 import org.openqa.selenium.support.ui.ExpectedCondition;
 17 import org.openqa.selenium.support.ui.ExpectedConditions;
 18 import org.openqa.selenium.support.ui.Select;
 19 import org.openqa.selenium.support.ui.WebDriverWait;
 20 import org.slf4j.Logger;
 21 import org.slf4j.LoggerFactory;
 22
 23 /**
 24  * @author Wulei
 25  * @date 2018-4-26
 26  *
 27  */
 28 public class Login {
 29     private WebDriver driver;
 30
 31     public Login(WebDriver driver) {
 32         this.driver = driver;
 33         PageFactory.initElements(new AjaxElementLocatorFactory(driver, 30), this);//初始化元素时等待时间
 34     }
 35
 36     @FindBy(id = "loginHtml:username")
 37     @CacheLookup
 38     private WebElement userName;
 39
 40     @FindBy(id = "loginHtml:password")
 41     @CacheLookup
 42     private WebElement password;
 43
 44     @FindBy(id = "loginHtml:domain")
 45     @CacheLookup
 46     private WebElement domain;
 47
 48     @FindBy(id = "loginHtml:userDomain")
 49     @CacheLookup
 50     private WebElement userDomain;
 51
 52     @FindBy(id = "loginHtml:loginBtn")
 53     @CacheLookup
 54     private WebElement loginBtn;
 55
 56     @FindBy(css = "ul.nav.navbar-nav.navbar-right.header-menu li:nth-child(3)")
 57     @CacheLookup
 58     private WebElement userIcon;
 59
 60     @FindBy(css = "ul.nav.navbar-nav.navbar-right.header-menu li:nth-child(5)")
 61     @CacheLookup
 62     private WebElement logoutIcon;
 63
 64     @FindBy(partialLinkText = "Logout")
 65     private WebElement logout;
 66
 67     @FindBy(css = "div.errors ul li")
 68     @CacheLookup
 69     private WebElement errorMsg;
 70
 71     @FindBy(id = "si_searchAttrInput")
 72     @CacheLookup
 73     private WebElement searchAttrInput;
 74
 75     @FindBy(xpath = "//*[@id=\"userProfilePopup\"]/div/div/div[3]/button[@id=\"cancelBtn\"]")
 76     @CacheLookup
 77     private WebElement closeBt;
 78
 79     @FindBy(how = How.XPATH, using = "//*[@id=\"mainHeader\"]/div/nav/div[2]/ul[2]/li[3]/a")
 80     private WebElement profile;
 81
 82
 83     public void login(String userName, String password, String custId, String domain)
 84             throws Exception {
 85         this.userName.sendKeys(userName);
 86         this.password.sendKeys(password);
 87         this.domain.clear();
 88         this.domain.sendKeys(custId);
 89         Select select = null;
 90         for (int i = 0; i < 3; i++) {
 91             try {
 92                 select = new Select(userDomain);
 93                 select.selectByVisibleText(domain);
 94                 break;
 95             } catch (org.openqa.selenium.StaleElementReferenceException e) {
 96             }
 97         }
 98
 99         loginBtn.click();
100
101         try {
102             TimeUnit.SECONDS.sleep(2);
103         } catch (InterruptedException e) {
104             e.printStackTrace();
105         }
106
107         PageFactory.initElements(new AjaxElementLocatorFactory(driver, 30), this);
108     }
109
110     public boolean isLoggedIn() {
111         boolean result = true;
112         // check if input search box can be located
113         try {
114             new WebDriverWait(driver,5).until(ExpectedConditions.visibilityOf(searchAttrInput));
115         } catch (org.openqa.selenium.TimeoutException e) {
116             result = false;
117         }
118         return result;
119     }
120
121     public String getErrorMsg() {
122         return errorMsg.getText();
123     }
124
125     public Login logout() throws InterruptedException {
126         closeBt.click();
127         Thread.sleep(2000);
128         logoutIcon.click();
129         logout.click();
130         return this;
131     }
132 }

Login.java

>第5步:创建自动化测试类:AutoTest.java

 1 package com.test;
 2
 3 import java.util.concurrent.TimeUnit;
 4
 5 import org.openqa.selenium.WebDriver;
 6 import org.openqa.selenium.chrome.ChromeDriver;
 7
 8 public class AutoTest {
 9     public static Boolean runTest(String url, String su) throws Exception {
10         WebDriver driver = new ChromeDriver();
11         driver.manage().window().maximize();
12         driver.manage().timeouts().implicitlyWait(12, TimeUnit.SECONDS);
13         driver.get(url);
14         Login loginObj = new Login(driver);
15         loginObj.login("admin", "admin*1", su, "LOCAL");
16         return true;
17     }
18
19 }

AutoTest.java

>第6步【核心】:创建类继承AbstractJavaSamplerClient

 1 package com.test;
 2
 3 import org.apache.jmeter.config.Arguments;
 4 import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
 5 import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
 6 import org.apache.jmeter.samplers.SampleResult;
 7
 8 public class CustomJMeter extends AbstractJavaSamplerClient{
 9
10     @Override
11     public void setupTest(JavaSamplerContext args) {
12
13     }
14
15     @Override
16     public Arguments getDefaultParameters() {
17             Arguments params = new Arguments();
18             params.addArgument("Url", "https://10.30.2.151/phoenix/login-html.jsf"); // 定义一个参数,显示到Jmeter的参数列表中,第一个参数为参数默认的显示名称,第二个参数为默认值
19             params.addArgument("Org", "super");
20             params.addArgument("Name", "wulei");
21             return params;
22     }
23
24     @Override
25     public SampleResult runTest(JavaSamplerContext context) {
26         SampleResult sr = new SampleResult();
27         try {
28             sr.sampleStart();
29
30             String arg1 = context.getParameter("Url");
31             String arg2 = context.getParameter("Org");
32             AotuTest.runTest(arg1, arg2);
33             sr.setSampleLabel("结果");
34             sr.setResponseData("返回结果:"+AotuTest.runTest(arg1, arg2), "UTF-8");
35             sr.setDataType(SampleResult.TEXT);
36             sr.setSuccessful(true);
37         } catch (Exception e) {
38             sr.setSuccessful(false);
39             e.printStackTrace();
40         }finally {
41             sr.sampleEnd();// jmeter 结束统计响应时间标记
42         }
43         return sr;
44     }
45
46     @Override
47     public void teardownTest(JavaSamplerContext context) {
48         // TODO Auto-generated method stub
49         super.teardownTest(context);
50     }
51 }
52   

CustomJMeter.java

创建完毕后的过程结构如下图:

>第7步:Maven打包package,并查看打包结果

>第8步:将包移到JMeter的对应目录中

Jmeter-0.0.1-SNAPSHOT.jar  --------复制到------>JMeter目录:apache-jmeter-3.3\lib\ext

Jmeter-0.0.1-SNAPSHOT-assembly.tar.gz --------将压缩包里面的lib目录下的全部jar包复制到------>JMeter目录:apache-jmeter-3.3\lib

结果如下图:

>第9步:运行JMeter的java请求,运行用例

运行后会自动运行测试代码(打开Chrome浏览器并登陆系统)查看结果如下:


代码CustomJMeter.java详解

CustomJMeter.java继承AbstractJavaSamplerClient类后,重写了如下方法:

1.setupTest方法:运行JMeter取样器前执行的操作,初始化一些操作,可以为空。

@Override
public void setupTest(JavaSamplerContext args) {

  //TODO

}

2.teardownTest方法:取样器的回收方法,可以为空。

@Override
public void teardownTest(JavaSamplerContext context) {
  // TODO Auto-generated method stub
  super.teardownTest(context);
}

3.getDefaultParameters方法【重要】:定义JMeter传递的参数,也就是JMeter的JAVA请求显示的参数列表。可以设置默认值。

@Override
public Arguments getDefaultParameters() {
  Arguments params = new Arguments(); //初始化参数
  params.addArgument("Url", "https://10.30.2.151/phoenix/login-html.jsf"); // 定义一个参数,显示到Jmeter的参数列表中,第一个参数为参数默认的显示名称,第二个参数为默认值
  params.addArgument("Org", "super");
  params.addArgument("Name", "wulei");//这里定义了3个参数并都设置了默认值
  return params;
}

对应JMeter的显示:

4.runTest【最重要】方法:定义取样器的运行的内容和设置取样器的返回结果

@Override
public SampleResult runTest(JavaSamplerContext context) {
  SampleResult sr = new SampleResult();//初始化取样器的返回
  try {
    sr.sampleStart();//开始运行取样器

    String arg1 = context.getParameter("Url");        //获取JMeter运行时传递的实际参数值
    String arg2 = context.getParameter("Org");           //获取JMeter运行时传递的实际参数值
    AotuTest.runTest(arg1, arg2);              //运行自动化测试,并将参数传递到测试方法中
    sr.setSampleLabel("结果");               //参考下图:定义取样器的结果标签,查看结果树中可以查看
    sr.setResponseData("返回结果:"+AotuTest.runTest(arg1, arg2), "UTF-8"); //参考下图:setResponseData,结果会显示在响应结果框中
    sr.setDataType(SampleResult.TEXT);          //参考下图:设置结果的数据类型为TEXT
    sr.setSuccessful(true);                //参考下图:定义测试结果,可以判断定义
  } catch (Exception e) {
    sr.setSuccessful(false);
    e.printStackTrace();
  }finally {
    sr.sampleEnd();// jmeter 结束统计响应时间标记
  }
  return sr;
}


写在最后

JMeter二次开发的本质很简单就是重写方法,打包和运行。这里的例子是使用的是自动化测试,大家可以忽略例子本身,而只关注继承类的实现。网络上很多的例子都是实现加法,减法等运算。实际是一样的。只不过测试类的区别。

转载于:https://www.cnblogs.com/forfreewill/articles/9007995.html

JMeter进阶系列01--JMeter二次开发相关推荐

  1. JavaScript进阶系列01,函数的声明,函数参数,函数闭包

    本篇主要体验JavaScript函数的声明.函数参数以及函数闭包. □ 函数的声明 ※ 声明全局函数 通常这样声明函数: function doSth() { alert("可以在任何时候调 ...

  2. Windows下搭建ESP-IDF开发环境,适合ESP32/S2/C3/S3系列模组二次开发

    前言 本教程适用于以下两种用户: ①无Linux环境搭建经验或搭建Linux开发环境不成功: ②使用安信可windows一体化环境IDE V1.5开发环境搭建不成功: 本教程提供了windows下搭建 ...

  3. Linux下搭建ESP-IDF 开发环境教程,适合ESP32/S2/C3/S3系列模组二次开发

    1 Ubuntu安装 在Linux下编译速度比Windows快很多,一般推荐优先使用Linux开发.Ubuntu是非常常见的Linux操作系统. 网上已经有非常多的Ubuntu安装教程,这里推荐一篇, ...

  4. WCF 4.0 进阶系列 – 第十二章 实现单向操作和异步操作(中)

    单向操作特别适用于"触发然后忘记"场景,在该场景中,客户端程序并不期望服务回传任何信息.但是,许多操作并不适用于这种情况,其向客户端程序返回数据.为了处理这些情况,WCF支持异步操 ...

  5. WCF 4.0 进阶系列 – 第十二章 实现单向操作和异步操作(下)

    使用消息队列 消息队列是本书WCF异步技术中的最后一个出场的.消息队列可以为消息传输提供持久性.可靠性和事务性.甚至,发送消息的客户端程序与接受消息的服务可以不必同时运行.但使用该灵活性需要付出一定的 ...

  6. WCF 4.0 进阶系列 – 第十二章 实现单向操作和异步操作(上)

    当客户端程序调用一个单向操作后,客户端可以继续运行而不用等待服务完成该操作.你可以通过操作合约指定单向操作行为.达到该目的的最简单方式是在当以操作时设置Operation-Contract特性类的Is ...

  7. JMeter基础系列(八) JMeter断言之JSON断言

    若服务器返回的Response Body为JSON格式的数据,使用JSON断言来判断测试结果是较好的选择. 首先需要根据JSON Path从返回的JSON数据中提取需要判断的实际结果,再设置预期结果, ...

  8. 《Python进阶系列》十二:最全魔术方法整理

    Python中的魔术方法 所谓魔法函数(Magic Methods),是Python的一种高级语法,允许你在类中自定义函数,并绑定到类的特殊方法中.比如在类A中自定义__str__()函数,则在调用s ...

  9. 【全栈接口测试进阶系列教程】入门到入职的jmeter接口测试工具实战,接口测试步骤,正则表达式jsonpath,断言,接口加密,beanshell,jdbc,jmeter+ant+jenkins

    目录 [本文简介看之前请详细的看完介绍] 本文是全网首发的[全栈接口测试进阶系列教程]jmeter接口测试工具从入门到入职, 接口系列包含 接口测试系列包含所有的接口测试工具入门到入职,如果你喜欢的话 ...

最新文章

  1. open的O_DIRECT选项
  2. Linux学习 Unit 4
  3. linux 线程 pthread create 源码 剖析
  4. 【PC工具】更新文件夹多文件群体比较工具WinMerge
  5. CentOS7安装wdCP面板,快速搭建web运行环境(图文详解)
  6. 同态加密应用_重新设计具有同态性的银行应用
  7. structure101_使用structure101分析软件包的依赖关系
  8. spyder pyecharts不显示_165Hz+1ms仅需千元左右 优派VX2771HDPRO显示器
  9. wince linux 性能,wince remote call profiler(性能分析)
  10. discuz数据从godaddy主机中导出的mysql数据乱码变问号???的解决方法
  11. 高并发下Java多线程编程基础
  12. 使用 Akka 实现 Master 与 Worker 之间的通信
  13. for循环的使用步骤 1104
  14. PHP编码规范 代码样式风格规范
  15. 网站繁简体切换(二)
  16. 创建者模式 --- 工厂模式
  17. 金蝶14.0系统服务器安装教程,大神面对win7系统安装金蝶kis14.0的方式
  18. H5网页漫画小说苹果cms模板源码/支持对接公众号/支持三级分销
  19. WebStorm和VSCode配置
  20. 2021年中国房地产行业发展现状及2022年前景展望「图」

热门文章

  1. HTML5全屏API
  2. OPMS 1.2 版本更新发布
  3. Duktape 集成
  4. vs中不得不会的一些小技巧(1)——细说查找
  5. python的logging模块,记录所发生的异常。
  6. APP时代,市场选择是个技术活
  7. SQL分割字符串,SQL按照指定字符分割字符串,SQL处理字符串...
  8. php phar 无法创建,php composer.phar install 安装问题
  9. C++求数组中的逆序对
  10. 神经网络模拟sin 发现的规律和大神傅里叶说的一致