「原创声明:保留所有权利,禁止转载」
前两天写了一篇文章重放浏览器单个请求性能测试实践,介绍了如何从浏览器中复制请求,来获取请求对象,进而完成单接口的性能测试工作。今天就来分享一下如何通过这种方式进行多接口性能测试。
复制请求
这里我用了复制所有请求,通过一些过滤条件进行筛选需要测试的请求。
这个复制出来的数据太多了,格式基本和之前的一样,我就不重复展示了。
获取 HttpRequestBase 对象
这里唯一和前文不同的就是从一个文件中获取多个HTTPrequestbase
请求对象,这里我用了一个CurlRequestBase
,只要检测到结束标志符号--compressed,立刻生成一个HTTPrequestbase
对象,紧接着把初始的CurlRequestBase
对象还原,这样不会干扰下一个请求的数据。
具体方法如下:
/**
* 从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
属性进行过滤,主要是过滤掉js
、css
、图片、网页和媒体文件包括无用的请求。一次是通过请求头accept
字段中application/json
信息过滤,把响应结果不是JSONObject
的请求也过滤掉。
public static def filterWords = [".js", ".png", ".gif", ".css", ".ico", "list_unread", ".svg", ".htm", ".jpeg",".ashx"]
if (filterWords.any {
base.url.contains(it)
}) return
requests.findAll {
it != null && it.getFirstHeader("accept").getValue().contains("application/json")
}
性能测试
脚本如下:
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()
}
控制台输出
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ 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":"\r\n\t\"
> }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
INFO->
FunTester测试4
>>响应时间分布图,横轴排序分成桶的序号,纵轴每个桶的中位数<<
--<中位数数据最小值为:25 ms,最大值:124 ms>--
██
██
██
▅▅ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██ ██
██ ██ ██
██ ██ ██
██ ██ ██
▃▃ ██ ██ ██
▂▂ ▂▂ ▃▃ ▅▅ ██ ██ ██ ██
▁▁ ▁▁ ▃▃ ▄▄ ▄▄ ▄▄ ▅▅ ▅▅ ▇▇ ▇▇ ██ ██ ██ ██ ██ ██ ██ ██ ██
▅▅ ▅▅ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
INFO-> gc回收线程结束了!
Process finished with exit code 0
最后的响应结果需要使用等宽字体查看才行,如果系统默认的字是非等宽的,请参照下图:
关于如何使用性能测试框架和生成性能测试结果,有兴趣的可以翻一翻以前的文章。
FunTester,非著名测试开发,文章记录学习和感悟,欢迎关注,交流成长。
TesterHome 为用户提供「保留所有权利,禁止转载」的选项。
除非获得原作者的单独授权,任何第三方不得转载标注了「原创声明:保留所有权利,禁止转载」的内容,否则均视为侵权。
具体请参见TesterHome 知识产权保护协议。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!