重放浏览器多个请求性能测试实践

2021-02-24 10:07:16 浏览数 (1)

前两天写了一篇文章重放浏览器单个请求性能测试实践,介绍了如何从浏览器中复制请求,来获取请求对象,进而完成单接口的性能测试工作。今天就来分享一下如何通过这种方式进行多接口性能测试。

复制请求

这里我用了复制所有请求,通过一些过滤条件进行筛选需要测试的请求。

复制浏览器所有请求

这个复制出来的数据太多了,格式基本和之前的一样,我就不重复展示了。

获取HttpRequestBase对象

这里唯一和前文不同的就是从一个文件中获取多个HTTPrequestbase请求对象,这里我用了一个CurlRequestBase,只要检测到结束标志符号**--compressed**,立刻生成一个HTTPrequestbase对象,紧接着把初始的CurlRequestBase对象还原,这样不会干扰下一个请求的数据。

具体方法如下:

代码语言:javascript复制
    /**
     * 从curl复制结果中获取请求
     * @param path
     * @return
     */
    public static List<HttpRequestBase> getRequests(String path) {
        def fileinfo = WriteRead.readTxtFileByLine(LONG_Path   path).stream().map {it.trim()}
        def requests = []
        def base = new CurlRequestBase()
        fileinfo.each {
            if (it.startsWith("curl")) {
                def split = it.split(" ", 2)
                def type = split[0]
                def value = split[1]
                base.url = value.substring(value.indexOf('h'), value.lastIndexOf("'"))
            } else if (it.startsWith("-H")) {
                def split = it.split(" ", 2)[1].split(": ")
                base.headers << FanLibrary.getHeader(split[0].substring(1), split[1].substring(0, split[1].lastIndexOf("'")))
            } else if (it.startsWith("--data-raw")) {
                base.params = getJson(it.substring(it.indexOf("'")   1, it.lastIndexOf("'")).split("&"))
                base.type = RequestType.POST
            } else if (it.startsWith("--compressed")) {
                requests << getRequest(base)
                base = new CurlRequestBase()
            }
        }
        requests.findAll {
            it != null && it.getFirstHeader("accept").getValue().contains("application/json")
        }
    }

    /**
     * 将curlrequestbase对象转换成HTTPrequestbase
     * @param base
     * @return
     */
    static HttpRequestBase getRequest(CurlRequestBase base) {
        if (filterWords.any {
            base.url.contains(it)
        }) return
        base.type == RequestType.GET ? FunRequest.isGet().setUri(base.url).addHeader(base.headers).getRequest() : FunRequest.isPost().setUri(base.url).addHeader(base.headers).addParams(base.params).getRequest()
    }

中间用了两次过滤,一次是根据CurlRequestBase对象的url属性进行过滤,主要是过滤掉jscss、图片、网页和媒体文件包括无用的请求。一次是通过请求头accept字段中application/json信息过滤,把响应结果不是JSONObject的请求也过滤掉。

代码语言:javascript复制
    public static def filterWords = [".js", ".png", ".gif", ".css", ".ico", "list_unread", ".svg", ".htm", ".jpeg",".ashx"]
    
        if (filterWords.any {
            base.url.contains(it)
        }) return
代码语言:javascript复制
        requests.findAll {
            it != null && it.getFirstHeader("accept").getValue().contains("application/json")
        }

性能测试

脚本如下:

代码语言:javascript复制
    public static void main(String[] args) {
        def requests = getRequests("get")
        output(requests.size())
        def threads = []
        requests.each {
            output FanLibrary.getHttpResponse(it)
            threads << new RequestThreadTime<HttpRequestBase>(it, 100, null)
        }
        new Concurrent(threads, "FunTester测试").start()
        testOver()
    }

控制台输出

代码语言:javascript复制
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":40,
>  ① . "total":9993,
>  ① . "qps":99.92275560021898,
>  ① . "failRate":0.0,
>  ① . "threads":4,
>  ① . "startTime":"2021-01-27 15:37:43",
>  ① . "endTime":"2021-01-27 15:39:23",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":9993,
>  ① . "mark":"FunTester测试20210127153743",
>  ① . "table":"rnt"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
INFO-> 
    FunTester测试4

 >>响应时间分布图,横轴排序分成桶的序号,纵轴每个桶的中位数<<
  --<中位数数据最小值为:25 ms,最大值:124 ms>--
                                                                  ██ 
                                                                  ██ 
                                                                  ██ 
                                                               ▅▅ ██ 
                                                               ██ ██ 
                                                               ██ ██ 
                                                               ██ ██ 
                                                               ██ ██ 
                                                               ██ ██ 
                                                               ██ ██ 
                                                               ██ ██ 
                                                            ██ ██ ██ 
                                                            ██ ██ ██ 
                                                            ██ ██ ██ 
                                                            ██ ██ ██ 
                                                         ▃▃ ██ ██ ██ 
                                             ▂▂ ▂▂ ▃▃ ▅▅ ██ ██ ██ ██ 
            ▁▁ ▁▁ ▃▃ ▄▄ ▄▄ ▄▄ ▅▅ ▅▅ ▇▇ ▇▇ ██ ██ ██ ██ ██ ██ ██ ██ ██ 
▅▅ ▅▅ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 

INFO-> gc回收线程结束了!

Process finished with exit code 0

最后的响应结果需要使用等宽字体查看才行,如果系统默认的字是非等宽的,请参照下图:

FunTester性能测试结果

关于如何使用性能测试框架和生成性能测试结果,有兴趣的可以翻一翻以前的文章。


FunTester,非著名测试开发,文章记录学习和感悟,欢迎关注,交流成长。
  • Gitee地址https://gitee.com/fanapi/tester
  • GitHub地址https://github.com/JunManYuanLong/FunTester

0 人点赞