jmeter中java協議請求


主要參考文章:http://www.cnblogs.com/yangxia-test/p/4019541.html

 

 

測試工具:myecplise10.5

jdk版本:1.8.73

jmeter: 2.13

 

一、核心步驟

1.創建一個Java工程;

2.將JMeter的lib目錄下的jar文件添加進此工程的Build Path;

3.創建一個類並實現JavaSamplerClient接口繼承AbstractJavaSamplerClient,並重寫;

public Arguments getDefaultParameters();設置可用參數及的默認值,已設置的參數會顯示在jmeter GUI的參數列表中;
public void setupTest(JavaSamplerContext arg0):每個線程測試前執行一次,做一些初始化工作;
public SampleResult runTest(JavaSamplerContext arg0):開始測試,從arg0參數可以獲得參數值,並調用被測方法,完成與服務器的交互;
public void teardownTest(JavaSamplerContext arg0):測試結束時調用;

  setupTest和teardownTest方法不需要時可以不寫。runTest 該方法是java Sampler實現的重點,執行次數取決於線程數和循環次數。

  以上4個方法中只有runTest是必須實現的,其他3個可根據需求去覆蓋。這4個方法執行的先后順序與其前面的顯示順序相對應。

  如果需要對多個方法進行性能測試,則需要建多個測試類,多個測試類可以放在同一個包下面,也可以放在單獨的包中。

4.Export為Runnable Jar File

5.將此jar包放入JMETER_HOME\lib\ext目錄;

6.以管理員身份打開JMeter;

7.創建線程組、Java Request、查看結果樹,進行測試;

 

二、實例

1.在eclipse里面新建一個工程:JavaForJMeter

2.把{Jmeter_home}\lib目錄下的所有jar,引用的jar包復制到lib目錄,並添加進此工程的Build Path;

注意:lib\ext目錄下ApacheJMeter_core.jar,ApacheJMeter_java.jar兩個jar包肯定需要build到項目中,另外還需要對其如果在ecplise中執行時報其他錯可再添加相應的jar包。為方便,就可導入lib目錄下的所有jar包。 

  Logkit-2.0.jar :記錄 jmeter 打屏日志使用的包
  Httpclient-4.3.2.jar : http 相關接口包

 

3.添加類Hello,代碼如下:

package test;

public class Hello {
    public String sayHello()
    {
        return "Hello";
    }
//    public String sayHelloToPerson(String s)
//    {
//        if(s == null || s.equals(""))
//            s = "nobody";
//        return (new StringBuilder()).append("Hello ").append(s).toString();
//    }
    public int sum(int a,int b)
    {
        return a+b;
    }
}

4.添加類perftest,並繼承AbstractJavaSamplerClient,並添加代碼如下:

注意:

1)System.out等的輸出會顯示在啟動JMeter時的命令窗口內,但過多的輸出會影響性能的准確性。

2)http請求在任何情況下都會有給客戶端一個反饋,但是java請求不一定。在設置的壓力較大時,服務器可能會吃不消直接異常退出,客戶端獲取不到任何返回值,保存返回結果的對象(如本例中的resultData)的值就為null。所以需要做空指針的判斷,保證代碼的正常運行。

package test;

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.samplers.SampleResult;
import test.Hello;

public class test extends AbstractJavaSamplerClient {
    private String a;
    private String b;

    private String resultData = null ;

    // 這個方法是用來自定義java方法入參的。
    // params.addArgument("num1","");表示入參名字叫num1,默認值為空。
    // 設置可用參數及的默認值;
    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("num1", "");//未設默認值
        params.addArgument("num2", "");
        return params;
    }

    // 每個線程測試前執行一次,做一些初始化工作;
    public void setupTest(JavaSamplerContext arg0) {
   }
// 開始測試,從arg0參數可以獲得參數值; public SampleResult runTest(JavaSamplerContext arg0) { a = arg0.getParameter("num1"); b = arg0.getParameter("num2"); SampleResult sr = new SampleResult(); sr.setSampleLabel("qingqiu"); try { sr.sampleStart();// jmeter 開始統計響應時間標記 Hello test = new Hello(); // 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應數據里面了。 resultData = String.valueOf(test.sum(Integer.parseInt(a), Integer .parseInt(b))); if (resultData != null && resultData.length() > 0) { sr.setResponseData("結果是:"+resultData, null);//第二個參數指定編碼方法 sr.setDataType(SampleResult.TEXT); } System.out.println(resultData); sr.setSuccessful(true); //將這行放在上邊if語句里更好? } catch (Throwable e) { sr.setSuccessful(false); //設置本次測試結果為false e.printStackTrace(); } finally { sr.sampleEnd();// jmeter 結束統計響應時間標記 } return sr; } // 測試結束時調用; public void teardownTest(JavaSamplerContext arg0) { //System.out.println(end); // System.out.println("The cost is"+(end-start)/1000); } // main只是為了調試用,最后打jar包的時候注釋掉。 public static void main(String[] args) { Arguments params = new Arguments(); params.addArgument("num1", "1");//設置參數,並賦予默認值1 params.addArgument("num2", "2");//設置參數,並賦予默認值2 JavaSamplerContext arg0 = new JavaSamplerContext(params); test test = new test(); test.setupTest(arg0); //無初始化,可不使用 test.runTest(arg0); test.teardownTest(arg0); //方法中無代碼,可不使用 } }

main方法執行結果如下: 

WARN    2016-03-20 00:20:01.895 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.body_real_size', defaulting to:true WARN 2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.headers_size', defaulting to:true WARN 2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.timestamp.start', defaulting to:false WARN 2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.useNanoTime', defaulting to:true WARN 2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for int property:'sampleresult.nanoThreadSleep', defaulting to:5000 INFO 2016-03-20 00:20:01.941 [jmeter.s] (): Note: Sample TimeStamps are END times INFO 2016-03-20 00:20:01.942 [jmeter.s] (): sampleresult.default.encoding is set to ISO-8859-1 INFO 2016-03-20 00:20:01.942 [jmeter.s] (): sampleresult.useNanoTime=true INFO 2016-03-20 00:20:01.942 [jmeter.s] (): sampleresult.nanoThreadSleep=5000 3

 

5.Export為Runnable Jar File:hello.jar

注意:不需要將整個工程導出,只需要選中包名(test)在file菜單中點擊export-》選java項的jar file-》默認選項,設置jar路徑,生成相應可以執行jar包。

 

修改MANIFEST.MF。MANIFEST.MF文件描述了jar包的相關信息,包括jar包的版本、創建人和類搜索路徑等。如果是可執行jar包,會包含Main-Class屬性,表明Main方法入口。Class-Path指定依賴的jar包,當前路徑是jar包所在目錄,若要引用當前目錄下一個子目錄中的jar包,使用以下格式:子目錄/jar包名稱,多個jar包之間用空格分隔,在任何平台上路徑分割符都是'/'。

 

如果導出的jar包依賴了別的jar包,需要在MANIFEST.MF文件中指明依賴的jar包的名字。在導出的jar包上右鍵,選擇用WinRAR打開,打開META_INF\MANIFEST.MF文件,添加依賴的jar包的名字,名字之前用空格分隔,比如:

 

Class-Path: lib/ApacheJMeter_core.jar lib/ApacheJMeter_java.jar lib/avalon-framework-4.1.4.jar lib/commons-logging-1.2.jar lib/logkit-2.0.jar

 

 

 

6.將此hello.jar包放入JMETER_HOME\lib\ext目錄;

7.打開JMeter,添加線程組,添加Java請求,查看結果樹。

在Thread Group上是右擊,Add-->Sampler-->Java Request。

注意:此處java請求為sampler中的java請求,而非配置元件中的java請求默認值。只有添加的sampler中的java請求, 在查看結果樹中才會有值。

在兩個路徑下的請求,都會生成如下日志:

2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Running the test! 
2016/03/20 00:27:33 INFO  - jmeter.samplers.SampleEvent: List of sample_variables: [] 
2016/03/20 00:27:33 INFO  - jmeter.gui.util.JMeterMenuBar: setRunning(true,*local*) 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Starting ThreadGroup: 1 : 線程組 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Starting 1 threads for group 線程組. 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Thread will continue on error 
2016/03/20 00:27:33 INFO  - jmeter.threads.ThreadGroup: Starting thread group number 1 threads 1 ramp-up 1 perThread 1000.0 delayedStart=false 
2016/03/20 00:27:33 INFO  - jmeter.threads.ThreadGroup: Started thread group number 1 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: All thread groups have been started 
2016/03/20 00:27:33 INFO  - jmeter.threads.JMeterThread: Thread started: 線程組 1-1 
2016/03/20 00:27:33 INFO  - jmeter.threads.JMeterThread: Thread is done: 線程組 1-1 
2016/03/20 00:27:33 INFO  - jmeter.threads.JMeterThread: Thread finished: 線程組 1-1 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Notifying test listeners of end of test 
2016/03/20 00:27:33 INFO  - jmeter.gui.util.JMeterMenuBar: setRunning(false,*local*) 

 

jmeter中頁面:

 {Jmeter_home}\lib\ext目錄下繼承AbstractJavaSamplerClient類或實現JavaSamplerClient接口的測試類的類名都會出現在類名稱后面的下拉框中,JaveTest和SleepTest為jmeter默認實現的2個java請求Sampler。

 參數化時,可使用CSV Data Set Config設置從文件中動態獲取參數值,設置參數名稱為num1,對應的值為${num1}。這里可直接使用固定值。

一般不需要做統計分析的時候不用保存Response Data,並且如果要保存的Response Data數據量很大的話,可能會影響性能數據的准確性質。

如果要保存的話,還需要在configure(按鈕在上面未顯示出來),要同時勾選save as XML,save Response Data(XML)兩項,並且需要指定結果數據要寫入的文件名。不管指定的保存結果的文件格式是不是xml,結果數據都是以xml的格式存儲的。

要注意的是,在服務器上執行jmeter的時候,也需要另外指定上面的保存結果信息的文件名及路徑,因為Response Data是不會保存到-l參數后面指定的jtl文件中的。對其他信息的保存也可以參考這個方法。

選中請求后,可看到相應請求的“請求”與“響應數據”標簽。

 

增加log日志:

package test;

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.samplers.SampleResult;
import org.apache.log.Logger;

import test.Hello;

public class test extends AbstractJavaSamplerClient {
    private String a;
    private String b;
    
    private Logger log = getLogger(); // 在 jmeter 中 LogViewer 打印相關信息

    private String resultData;

    // 這個方法是用來自定義java方法入參的。
    // params.addArgument("num1","");表示入參名字叫num1,默認值為空。
    // 設置可用參數及的默認值;
//
參數設置,配置后Jmeter新建java sampler時會顯示對應參數,測試時可編寫jmeter腳本為參數賦值(與http sampler類似)
    public Arguments getDefaultParameters() {
        log.info( "execute getDefaultParameters..." );
        Arguments params = new Arguments();
        params.addArgument("num1", "");
        params.addArgument("num2", "");
        return params;
    }

    // 每個線程測試前執行一次,做一些初始化工作;
    public void setupTest(JavaSamplerContext arg0) {
    }

    // 開始測試,從arg0參數可以獲得參數值;
    public SampleResult runTest(JavaSamplerContext arg0) {
            log .info( "execute runTest..." );
            a = arg0.getParameter("num1");
            b = arg0.getParameter("num2");
            SampleResult sr = new SampleResult();
            sr.setSampleLabel("qingqiulog");
            try {
                sr.sampleStart();// jmeter 開始統計響應時間標記
                Hello test = new Hello();
                // 通過下面的操作就可以將被測方法的響應輸出到Jmeter的察看結果樹中的響應數據里面了。
                resultData = String.valueOf(test.sum(Integer.parseInt(a), Integer
                        .parseInt(b)));
                if (resultData != null && resultData.length() > 0) {
                    sr.setResponseData("結果是:"+resultData, null);
                    sr.setDataType(SampleResult.TEXT);
                }
                System.out.println(resultData);
                sr.setSuccessful(true);
                log.info( "sucess");
            } catch (Throwable e) {
                sr.setSuccessful(false);
                log.info( "fail..." );
                e.printStackTrace();
            } finally {
                sr.sampleEnd();// jmeter 結束統計響應時間標記
            }
            return sr;
        }

    // 測試結束時調用;
    public void teardownTest(JavaSamplerContext arg0) {
         log.info( "結束" );
         System.out.println("end");
        // System.out.println("The cost is"+(end-start)/1000);
    }

    // main只是為了調試用,最后打jar包的時候注釋掉。

      public static void main(String[] args) { 
          Arguments params = new Arguments(); 
          params.addArgument("num1", "1");//設置參數,並賦予默認值1 
          params.addArgument("num2", "2");//設置參數,並賦予默認值2
          JavaSamplerContext arg0 = new JavaSamplerContext(params); 
          test test = new test(); 
          test.setupTest(arg0); 
          test.runTest(arg0);
          test.teardownTest(arg0); 
      }


}

結果:

INFO    2016-03-25 17:17:33.131 [jmeter.p] (): execute runTest...
WARN    2016-03-25 17:17:33.198 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.body_real_size', defaulting to:true
WARN    2016-03-25 17:17:33.198 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.headers_size', defaulting to:true
WARN    2016-03-25 17:17:33.199 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.timestamp.start', defaulting to:false
WARN    2016-03-25 17:17:33.199 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.useNanoTime', defaulting to:true
WARN    2016-03-25 17:17:33.199 [jmeter.u] (): Unexpected value set for int property:'sampleresult.nanoThreadSleep', defaulting to:5000
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): Note: Sample TimeStamps are END times
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): sampleresult.default.encoding is set to ISO-8859-1
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): sampleresult.useNanoTime=true
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): sampleresult.nanoThreadSleep=5000
3
INFO    2016-03-25 17:17:33.202 [jmeter.p] (): sucess
INFO    2016-03-25 17:17:33.202 [jmeter.p] (): 結束
end

 

 如果要出報告的話,需要添加“聚合報告”一項。

 

參考資料:

 http://www.cnblogs.com/zhangchaoyang/articles/2530731.html

Jmeter性能測試實踐之java請求 具體實例寫的比較細一些

利用JMeter的Java請求采樣器進行rpc接口的性能測試

http://blog.csdn.net/musen518/article/details/50327217

有循環使用參數部分http://www.tuicool.com/articles/26ZV7n


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM