nGrinder工具進行接口性能測試

參考文獻:

https://blog.csdn.net/neven7/article/details/50669459

 

1.背景
之前在這篇文章中性能測試初探—接口性能測試介紹過nGrinder,本文將介紹在nGrinder腳本中使用資源文件中數據作爲接口參數和解析生成的CSV結果,生成TPS標準差,TPS波動率,最小/大RT,RT 25/50/75/80/85/90/95/99百分位數(原生結果中無這些結果,這些結果更有利於性能分析)。

2.實現
2-1.創建腳本


 
如果腳本中需獲取參數,可以使用Performance Test菜單下的Test Configuration->Show Advanced Configuration->Parameter輸入框中參數值(http://www.cubrid.org/wiki_ngrinder/entry/how-to-pass-a-parameter-to-the-script),但是隻支持1-50字符長度;如果參數值較長,可以使用resources(http://www.cubrid.org/wiki_ngrinder/entry/how-to-use-resources), 支持json, csv, txt, properties格式。

腳本示例如下:

定義String[] basic用於存放文件./resources/basicauth.txt中的值(數組元素爲文件中的每一行)

HTTP GET:


package org.ngrinder;

import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl;
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
// import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import HTTPClient.HTTPResponse
import HTTPClient.NVPair


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * A simple example using the HTTP plugin that shows the retrieval of a
 * single page via HTTP. 
 * 
 * This script is automatically generated by ngrinder.
 * 
 * @author hugang
 */
@RunWith(GrinderRunner)
class TestRunner {
    public static GTest test
    public static HTTPRequest request
    public static File file
    public static String[] basic

    @BeforeProcess
    public static void beforeProcess() {
        HTTPPluginControl.getConnectionDefaults().timeout = 6000
        test = new GTest(1, "10.75.0.55")
        request = new HTTPRequest()
        test.record(request);

        // 將文件內容轉成參數數組
        basic = new File("./resources/basicauth.txt") as String[];
        // grinder.logger.info(basic[0] + "  " + basic[1])
        grinder.logger.info("before process.");
    }

    @BeforeThread 
    public void beforeThread() {
        grinder.statistics.delayReports=true;
        grinder.logger.info("before thread.");
    }

    @Test
    public void test(){
        // 隨機獲取auth
        int index = (int) (Math.random() * basic.length);
        String basicAuth = basic[index];
        println(basicAuth);
        // GET請求,wiki http://grinder.sourceforge.net/g3/script-javadoc/net/grinder/plugin/http/HTTPRequest.html
        // param1: uri, param2: queryData, param3: headers
        HTTPResponse result = request.GET("http://10.75.0.55:8080/2/likes/by_me.json",[new NVPair("object_type", "pic")] as NVPair[], [new NVPair("Authorization", basicAuth)] as NVPair[])
        if (result.statusCode == 301 || result.statusCode == 302) {
            grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode); 
        } else {
            assertThat(result.statusCode, is(200));
            // 請求返回的數據
            // println(result.text);
            // 定義一個事務,接口返回數據校驗,是否包含
            assertThat(result.text, containsString("\"object_type\":\"pic\""));
        }
    }
}


HTTP post:

package org.ngrinder;

import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl;
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
// import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import HTTPClient.HTTPResponse
import HTTPClient.NVPair


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * A simple example using the HTTP plugin that shows the retrieval of a
 * single page via HTTP. 
 * 
 * This script is automatically generated by ngrinder.
 * 
 * @author hugang
 */
@RunWith(GrinderRunner)
class TestRunner {
    public static GTest test
    public static HTTPRequest request
    public static File file
    public static String[] basic

    @BeforeProcess
    public static void beforeProcess() {
        HTTPPluginControl.getConnectionDefaults().timeout = 6000
        test = new GTest(1, "10.210.230.28")
        request = new HTTPRequest()
        test.record(request);

        // 將文件內容轉成參數數組
        basic = new File("./resources/basicauth.txt") as String[];
        // grinder.logger.info(basic[0] + "  " + basic[1])
        grinder.logger.info("before process.");
    }

    @BeforeThread 
    public void beforeThread() {
        grinder.statistics.delayReports=true;
        grinder.logger.info("before thread.");
    }

    @Test
    public void test(){
        // 隨機獲取auth
        int index = (int) (Math.random() * basic.length);
        String basicAuth = basic[index];
        println(basicAuth);
        // POST請求,wiki http://grinder.sourceforge.net/g3/script-javadoc/net/grinder/plugin/http/HTTPRequest.html
        // param1: uri, param2: queryData, param3: headers
        HTTPResponse result = request.POST("http://10.210.230.28/2/statuses/update.json",[new NVPair("status", "text " + Math.random())] as NVPair[], [new NVPair("Authorization", basicAuth)] as NVPair[])
        if (result.statusCode == 301 || result.statusCode == 302) {
            grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode); 
        } else {
            assertThat(result.statusCode, is(200));
            // 請求返回的數據
            // println(result.text);
            // 定義一個事務,接口返回數據校驗,是否包含
            assertThat(result.text, containsString("\"created_at\":"));
        }
    }
}



2-2. 驗證腳本
點擊Validate Script, 會出現如下信息:

...
2016-02-15 16:56:32,140 INFO  Start time is 1455526592140 ms since Epoch
2016-02-15 16:56:32,318 INFO  http://10.75.0.55:8080/2/likes/by_me.json?object_type=pic -> 200 OK, 3414 bytes
2016-02-15 16:56:32,342 INFO  finished 1 run
2016-02-15 16:56:32,345 INFO  elapsed time is 204 ms
2016-02-15 16:56:32,345 INFO  Final statistics for this process:
2016-02-15 16:56:32,355 INFO  
             Tests        Errors       Mean Test    Test Time    TPS          Mean         Response     Response     Mean time to Mean time to Mean time to 
                                       Time (ms)    Standard                  response     bytes per    errors       resolve host establish    first byte   
                                                    Deviation                 length       second                                 connection                
                                                    (ms)                                                                                                    

Test 1       1            0            32.00        0.00         4.90         3414.00      16735.29     0            1.00         5.00         24.00         "10.75.0.55"

Totals       1            0            32.00        0.00         4.90         3414.00      16735.29     0            1.00         5.00         24.00    
...

Tests 爲1, Errors 爲0 表示腳本驗證通過。

2-3.設計場景


3.結果


3.1.彙總信息
如果還需獲取詳細信息,需下載csv文件:

彙總數據項目地址:https://github.com/neven7/ngrinder-csv-analysis

解析ngrinder csv結果,統計TPS標準差,TPS波動率,最小/大RT,RT 25/50/75/80/85/90/95/99百分位數

步驟:

將ngrinder 生成的csv文件:output.csv,放到工程src/main/resources下

執行src/main/java下ParseCsv.java文件

Console輸出結果示例:

TPS平均值:257.88

TPS標準差:33.10

TPS波動率:12.84%

RT平均響應時間:19.43 ms

Min RT:14.90 ms

RT 25百分位數:18.07 ms

RT 50百分位數:19.14 ms

RT 75百分位數:20.33 ms

RT 80百分位數:20.78 ms

RT 85百分位數:21.29 ms

RT 90百分位數:21.86 ms

RT 95百分位數:23.52 ms

RT 99百分位數:25.91 ms

Max RT:46.93 ms
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章