目前看已经有了几种粗略的性能测试用例方案,有一些已经进行了实践,有一些已经被我放弃了。分享出来,算是个梳理。
这里的测试用例方案分为两类:「用例传递」和「用例执行」。目前我的想法还是通过「HTTP」协议接口完成用例的传递和执行中控制。采用定时任务或者脚本轮询的方式进行执行的控制。目前来看肯定是一个Springboot
项目了,这都是后话了。
下面分享第一种设想:
基于HttpRequestBase对象的压测场景
这种测试场景应该说非常少了,基于单个或者多个固定的HttpRequestBase
对象的分布式压测方案,其实实现起来有点大材小用了。简单的请求,没有参数化规则,没有上下游接口调用,没有前置后置处理,缺乏链路功能支持。说了这么多缺点,下面分享基于HttpRequestBase
对象的优点:实现简单,用例传递非常好做。执行起来也直接可以使用框架提供的能力。兼容性好,可以直接从功能用例中提取部分用例然后执行,达到用例多用的目的。
实现Demo
这里需要区分用例来源。
HttpRequestBase
总体分成三部分:「请求行」、「请求头」和「请求体」。依照之前分享过的案例,将一个HttpRequestBase
对象拆成三分部。例如我们获取一个请求的方式如下:
public static void main(String[] args) throws UnsupportedEncodingException {
HttpPost httpPost = getHttpPost("http://localhost:12345/test/qps");
httpPost.addHeader(getHeader("token", "324u2u09uweidlxnvldfsad"));
httpPost.setEntity(new StringEntity(getJson("name=FunTester").toString(), DEFAULT_CHARSET));
}
不过这样不利于HttpRequestBase
对象在「HTTP」接口中传递,毕竟没有直接用「序列化和反序列化」的方法。所以我自己写了一个中间对象。
最开始的想法用fastJSON
实现:
public static void main(String[] args) {
HttpPost httpPost = getHttpPost("http://localhost:12345/test/qps");
httpPost.addHeader(getHeader("token", "324u2u09uweidlxnvldfsad"));
httpPost.setEntity(new StringEntity(getJson("name=FunTester").toString(), DEFAULT_CHARSET));
httpPost.addHeader(HttpClientConstant.ContentType_JSON);
JSONObject httpResponse = getHttpResponse(httpPost);
output(httpResponse);
String s = JSON.toJSONString(httpPost);
HttpPost httpPost1 = JSON.parseObject(s, httpPost.getClass());
JSONObject httpResponse1 = getHttpResponse(httpPost1);
output(httpResponse1);
}
测试结果如下:
INFO-> 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
WARN-> 响应体非json格式,已经自动转换成json格式!
INFO-> 请求uri:http://localhost:12345/test/qps , 耗时:236 ms , HTTPcode: 200
INFO->
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
> {
> ① . "code":-2,
> ① . "FunTester":200,
> ① . "content":"FunTester"
> }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
WARN-> 获取post请求参数时异常!
WARN-> 获取请求相应失败!请求内容:{requestType='POST', host='', apiName='', uri='http://localhost:12345/test/qps', headers={"Connection":"keep-alive"}, args={}, params={}, json={}, response={}}
java.lang.UnsupportedOperationException: public abstract int org.apache.http.params.HttpParams.getIntParameter(java.lang.String,int)
at com.alibaba.fastjson.JSONObject.invoke(JSONObject.java:485) ~[fastjson-1.2.62.jar:?]
at com.sun.proxy.$Proxy22.getIntParameter(Unknown Source) ~[?:?]
at org.apache.http.client.params.HttpClientParamConfig.getRequestConfig(HttpClientParamConfig.java:59) ~[httpclient-4.5.6.jar:4.5.6]
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:177) ~[httpclient-4.5.6.jar:4.5.6]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.6.jar:4.5.6]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.6.jar:4.5.6]
at com.funtester.httpclient.FunLibrary.getHttpResponse(FunLibrary.java:352) [classes/:?]
at com.funtest.javatest.FF.main(FF.java:21) [classes/:?]
INFO-> json 对象是空的!
Process finished with exit code 0
请求发生错误,其实这里面POST
请求实体拷贝会失败。所以这个方法行不通了,只能换一个自己实现的。
public static void main(String[] args) {
HttpPost httpPost = getHttpPost("http://localhost:12345/post");
httpPost.addHeader(getHeader("token", "324u2u09uweidlxnvldfsad"));
httpPost.setEntity(new StringEntity(getJson("name=FunTester").toString(), DEFAULT_CHARSET));
httpPost.addHeader(HttpClientConstant.ContentType_JSON);
JSONObject httpResponse = getHttpResponse(httpPost);
output(httpResponse);
FunRequest funRequest = FunRequest.initFromRequest(httpPost);
HttpRequestBase request = funRequest.getRequest();
JSONObject httpResponse1 = getHttpResponse(request);
output(httpResponse1);
String text = JSON.toJSONString(funRequest);
HttpRequestBase httpRequestBase = FunRequest.initFromString(text).getRequest();
JSONObject httpResponse2 = getHttpResponse(httpRequestBase);
output(httpResponse2);
}