• nGrinder工具进行接口性能测试


    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百分位数

    步骤:

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

    2. 执行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

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/neven7/article/details/50669459
  • 相关阅读:
    HDU 1850 Being a Good Boy in Spring Festival
    UESTC 1080 空心矩阵
    HDU 2491 Priest John's Busiest Day
    UVALive 6181
    ZOJ 2674 Strange Limit
    UVA 12532 Interval Product
    UESTC 1237 质因子分解
    UESTC 1014 Shot
    xe5 android listbox的 TMetropolisUIListBoxItem
    xe5 android tts(Text To Speech)
  • 原文地址:https://www.cnblogs.com/ceshi2016/p/8668639.html
Copyright © 2020-2023  润新知