Jmeter二次開發——基於Java請求
阿新 • • 發佈:2020-12-19
# 簡述
這近幾年,越來越多非http的協議需要進行效能測試,包括不僅限於各類rpc、mq、快取等。對於這些協議,市面上可能沒有現成的工具可以直接使用,這個時候,我們可以自己動手,通過編寫相應的JavaSampler來高效地開展效能測試工作。
# 環境準備
- java環境已搭建ok
- jmeter環境已搭建ok
- idea開發環境已配置ok
java和jmeter環境搭建,可參考[Jmeter——環境搭建](https://www.cnblogs.com/hong-fithing/p/7640014.html)
# 二次開發
## 二次開發前提
- 需要lib/ext中的ApacheJMeter_core.jar
- 擴充套件java請求則還需要ApacheJMeter_java.jar
- 擴充套件http請求則需要ApacheJMeter_http.jar
匯入jar包,自行匯入,可參考[IDEA的基本操作——匯入匯出jar包](https://www.cnblogs.com/hong-fithing/p/13964449.html)
## Jmeter Java Sampler
### 方法簡介
```
public Arguments getDefaultParameters(); 可選,定義可用引數及預設值,獲取介面的引數;
public void setupTest(JavaSamplerContext arg0); 可選,測試前執行,做一些初始化工作,類似於LR的init和Junit中的setUp();
public SampleResult runTest(JavaSamplerContext arg0); 必選,實現自定義請求,類似於LR的Action;
public void teardownTest(JavaSamplerContext arg0); 可選,測試結束時呼叫,類似於LR的end和Junit中的tearDown();
```
### 方法執行順序
getDefaultParameters() > setupTest(JavaSamplerContext arg0) > runTest(JavaSamplerContext arg0) > teardownTest(JavaSamplerContext arg0)
### 常用方法
- addArgument("name", "value") 定義引數
- sampleStart() 定義事務的開始,類似於LR的lr_start_transaction,和LR一樣事務間不要放無關程式碼
- sampleEnd() 定義事務的結束,類似於LR的lr_end_transaction
- setSuccessful(true、false) 設定執行結果的成功或失敗,Jmeter統計成功失敗的次數,在聚合報告中能夠體現。
## 類的繼承
在做二次開發的時候,大家都知道,自己定義的類需要繼承AbstractJavaSamplerClient,可為什麼要繼承這個類,而不是其他,想必大家也都知道。為了能看的更明白,我們直接來看程式碼,如下所示:
```
public abstract class AbstractJavaSamplerClient implements JavaSamplerClient {
private static final Logger log = LoggerFactory.getLogger(AbstractJavaSamplerClient.class);
private static final org.apache.log.Logger oldLogger = LoggingManager.getLoggerForClass();
public AbstractJavaSamplerClient() {
}
public void setupTest(JavaSamplerContext context) {
log.debug(this.getClass().getName() + ": setupTest");
}
public void teardownTest(JavaSamplerContext context) {
log.debug(this.getClass().getName() + ": teardownTest");
}
public Arguments getDefaultParameters() {
return null;
}
/** @deprecated */
@Deprecated
protected org.apache.log.Logger getLogger() {
return oldLogger;
}
protected Logger getNewLogger() {
return log;
}
}
```
我們從上述程式碼看到有構造方法,3個普通方法,這3個方法是不是似曾相識?是的,在前文中就有提到。但發現,還少一個runTest方法,那它在哪呢?想必就是在這個類**JavaSamplerClient**中了。我們繼續來看程式碼,如下所示:
```
public interface JavaSamplerClient {
void setupTest(JavaSamplerContext var1);
SampleResult runTest(JavaSamplerContext var1);
void teardownTest(JavaSamplerContext var1);
Arguments getDefaultParameters();
}
```
好了,現在知道4個方法的來源了,在自己類中,實現功能,其實就是將這4個方法重寫,來實現自己的功能即可。思路有了,我們就來真實來寫個demo吧。
## getDefaultParameters
編寫getDefaultParameters()方法,使用addArgument方法,設定入參,程式碼示例如下:
```
/**
* 這個方法是用來自定義java方法入參的
* params.addArgument("x","");表示入參名字叫x,預設值為空。
* @return
*/
@Override
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("x","");
return params;
}
```
該引數設定,在jmeter介面中會展示,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218204521674-805410389.png)
## setupTest
setupTest,做自動化、效能測試都有類似概念,就是在測試前執行,做一些初始化工作。示例程式碼如下所示:
```
/**
* 每個執行緒測試前執行一次,做一些初始化工作
* 獲取輸入的引數,賦值給變數,引數也可以在下面的runTest方法中獲取,這裡是為了展示該方法的作用
* @param arg0
*/
@Override
public void setupTest(JavaSamplerContext arg0) {
x = arg0.getParameter("x");
}
```
## runTest
runTest是程式碼邏輯處理部分,示例程式碼實現的功能就是做數字簡單的比較,demo而已,具體如下所示:
```
/**
* 真正執行邏輯的方法
* @param arg0
* @return
*/
@Override
public SampleResult runTest(JavaSamplerContext arg0) {
SampleResult sr = new SampleResult();
sr.setSamplerData("請求引數x的值為:"+x);
try {
// jmeter 開始統計響應時間標記
sr.sampleStart();
int sum = Integer.parseInt(x);
if (sum<0){
logger.info(sum + "<0的值是"+ "-1");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("結果是:"+"-1", "utf-8");
//設定響應失敗
sr.setSuccessful(false);
}
else {
String str = String.valueOf(x);
final StringBuilder builder = new StringBuilder(str);
if (builder.reverse().toString().equals(str)) { //reverse 字串反轉,比如輸入66,反轉後為66,再做比較
logger.info(sum + "> 0的值做比較後是"+ "0");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("結果是:"+"0", "utf-8");
sr.setDataType(SampleResult.TEXT);
}else {
logger.info(sum + ">0的值是"+ "1");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("結果是:"+"1", "utf-8");
}
//設定響應執行成功
sr.setSuccessful(true);
}
} catch (Throwable e) {
//有異常,執行失敗
sr.setSuccessful(false);
e.printStackTrace();
} finally {
// jmeter 結束統計響應時間標記
sr.sampleEnd();
}
return sr;
}
```
## teardownTest
teardownTest,與setupTest是對應關係,做自動化、效能測試都有類似概念,就是在測試結束後執行,做一些清理工作。示例程式碼如下所示:
```
/**
* 測試結束後呼叫
* @param arg0
*/
@Override
public void teardownTest(JavaSamplerContext arg0) {
SampleResult sr = new SampleResult();
logger.info("測試結束");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("測試結束", "utf-8");
}
```
完成程式碼編寫後,可以先除錯一波,確保正確後,匯出jar包,放到jmeter對應目錄lib/ext下。匯出jar包的操作,可參考[IDEA的基本操作——匯入匯出jar包](https://www.cnblogs.com/hong-fithing/p/13964449.html)
## 實際效果
說了這麼多,我們來執行下程式碼看下實際效果,啟動jmeter,新增java 請求,並選擇剛編寫的java方法,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218212801041-2076968231.png)
### 輸出為-1
先來演示輸出為-1的效果,我們可以從程式碼中看出,結果為-1,輸入值小於0即可。
我們入參-9,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218212957662-1280639581.png)
執行程式碼,通過結果樹檢視請求資料,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218212919276-1247675925.png)
檢視響應資料,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218213210382-1536250784.png)
我們看介面響應情況,響應是失敗的,為啥是失敗的呢?我們從程式碼可知,入參小於0時,強制設定成了響應失敗,執行效果如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218213427291-516628374.png)
### 輸出為1
再來演示輸出為1的效果,我們可以從程式碼中看出,結果為1,輸入值大於0即可。
我們入參78,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218213725226-1297045977.png)
執行程式碼,通過結果樹檢視請求資料,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218213706143-1162738798.png)
檢視響應資料,響應的狀態也是成功的,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218213749671-728293001.png)
### 輸出等於0
最後演示下輸出為0的效果,我們可以從程式碼中看出,結果為0,輸入值轉換後還相等,則輸出為0。
我們入參66,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218215802159-154794346.png)
執行程式碼,通過結果樹檢視請求資料,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218214111443-1074267583.png)
檢視響應資料,響應的狀態也是成功的,如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218214128667-1977677777.png)
# 完整程式碼
再貼下今天演示demo的完整程式碼,如下所示:
```
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.protocol.java.test.JavaTest;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/**
* @author_router:wenyihuqingjiu
* @date:2020-12-18
*
*/
public class PalindromeDemo extends AbstractJavaSamplerClient {
private static Logger logger = LogManager.getLogger(PalindromeDemo.class.getName());
private String x;
/**
* 這個方法是用來自定義java方法入參的
* params.addArgument("x","");表示入參名字叫x,預設值為空。
* @return
*/
@Override
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("x","");
return params;
}
/**
* 每個執行緒測試前執行一次,做一些初始化工作
* 獲取輸入的引數,賦值給變數,引數也可以在下面的runTest方法中獲取,這裡是為了展示該方法的作用
* @param arg0
*/
@Override
public void setupTest(JavaSamplerContext arg0) {
x = arg0.getParameter("x");
}
/**
* 真正執行邏輯的方法
* @param arg0
* @return
*/
@Override
public SampleResult runTest(JavaSamplerContext arg0) {
SampleResult sr = new SampleResult();
sr.setSamplerData("請求引數x的值為:"+x);
try {
// jmeter 開始統計響應時間標記
sr.sampleStart();
int sum = Integer.parseInt(x);
if (sum<0){
logger.info(sum + "<0的值是"+ "-1");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("結果是:"+"-1", "utf-8");
//設定響應失敗
sr.setSuccessful(false);
}
else {
String str = String.valueOf(x);
final StringBuilder builder = new StringBuilder(str);
if (builder.reverse().toString().equals(str)) { //reverse 字串反轉,比如輸入66,反轉後為66,再做比較
logger.info(sum + "> 0的值做比較後是"+ "0");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("結果是:"+"0", "utf-8");
sr.setDataType(SampleResult.TEXT);
}else {
logger.info(sum + ">0的值是"+ "1");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("結果是:"+"1", "utf-8");
}
//設定響應執行成功
sr.setSuccessful(true);
}
} catch (Throwable e) {
//有異常,執行失敗
sr.setSuccessful(false);
e.printStackTrace();
} finally {
// jmeter 結束統計響應時間標記
sr.sampleEnd();
}
return sr;
}
/**
* 測試結束後呼叫
* @param arg0
*/
@Override
public void teardownTest(JavaSamplerContext arg0) {
SampleResult sr = new SampleResult();
logger.info("測試結束");
// 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應資料裡面了。
sr.setResponseData("測試結束", "utf-8");
}
}
```
# 問題總結
執行程式碼,報錯提示沒有LoggerFactory,報錯如下所示:
![](https://img2020.cnblogs.com/blog/1242227/202012/1242227-20201218215143857-1392983937.png)
解決辦法:重新下載slf4j包即可。
以上就是今天的分享內容了,二次開發java請求,小小demo,有誤之處,望批評