前面的文章讲了我的目的和如何基于CSV文件设置我的测试计划,没有了解过的可以点击链接查看:Jmeter之CSV参数设置及BeanShell对接口请求和响应数据处理(一)http://www.jianshu.com/p/113248c49612
本文主要分享我的完成通用CSV设置后,特殊处理的地方通过前置处理和后置处理实现。
1、BeanShell PreProcessor
下面实现的功能为
1)原文本特殊格式转换,csv文件写了一些"\n",会自动多加个"",导致实际请求的时候数据偏差,所以这里要做的就是纠正这些格式转换
//替换csv文件配置自动把"\n"转成"\\n"
String paramsPart1 = vars.get("defaultData");
String paramsPart2 = vars.get("myData");
String params = paramsPart2+paramsPart1;
String s = params.replace("\\n", "\n");
String myDataNew = paramsPart2.replace("\\n", "\n");
2)计算sign,并且传递出去,在http请求中可以使用变量signfromBeanShell
Sign怎么生成的:其实就是将所有用户请求的参数按照字母排序(包括timestamp,token),然后根据MD5加密(可以加点盐),生成sign签名,这就是所说的url签名算法。所以token+sign还能防止监听,保证程序的接口请求不会被恶意篡改、重放攻击等。
这里我把sign的算法封装到appSign中了,然后导出为jar包。
jmeter引用此jar包有两种引用方式:
- jar包直接放到D:\apache-jmeter-3.2\lib\ext目录下;
- 点击测试计划-页面最底部Add directory or jar to classpath-浏览-添加对应的jar包
beanshell是能完美支持java的,所以,简单的一个调用即可,并且需要把signfromBeanShell传递出去,可以在请求中直接使用此变量
import appSign.sign;
//把params传递,计算sign
String signResult=sign.getSign(s);
//计算结果赋值给jmeter请求使用
vars.put("signfromBeanShell",signResult);
3)因为测试中很多数据是中文,在实际请求中请求实体是urlEncode之后的,注意,此处没有把请求实体中的&、=进行urlEncode,仅仅为value,所以写了个encodeValue的函数
import java.net.URLEncoder;
private static String encodeValue(String data_csv) {
if (data_csv == null || data_csv.length() == 0) {
return "";
}
String[] strArray = data_csv.split("&");
StringBuilder sb = new StringBuilder();
for (String str : strArray) {
int index = str.indexOf("=");
String value = str.substring(index + 1);
String key = str.substring(0, index + 1);
sb.append(key).append(URLEncoder.encode(value,"UTF-8")).append("&");
}
String result = sb.toString();
result = result.substring(0, result.length() - 1);
return result;
}
//参与计算sign的的value为:未urlEncode,接口请求用的password为:已urlEncode
String myDataEncode = encodeValue(myDataNew);
vars.put("myData",myDataEncode);
System.out.println(myDataEncode);
上面分开说明了下,下面是完整的全部的preProcesser的代码:
import appSign.sign;
import java.net.URLEncoder;
private static String encodeValue(String data_csv) {
if (data_csv == null || data_csv.length() == 0) {
return "";
}
String[] strArray = data_csv.split("&");
StringBuilder sb = new StringBuilder();
for (String str : strArray) {
int index = str.indexOf("=");
String value = str.substring(index + 1);
String key = str.substring(0, index + 1);
sb.append(key).append(URLEncoder.encode(value,"UTF-8")).append("&");
}
String result = sb.toString();
result = result.substring(0, result.length() - 1);
return result;
}
//替换csv文件配置自动把"\n"转成"\\n"
String paramsPart1 = vars.get("defaultData");
String paramsPart2 = vars.get("myData");
String params = paramsPart2+paramsPart1;
String s = params.replace("\\n", "\n");
String myDataNew = paramsPart2.replace("\\n", "\n");
//把params传递,计算sign
String signResult=sign.getSign(s);
//计算结果赋值给jmeter请求使用
vars.put("signfromBeanShell",signResult);
//参与计算sign的的value为:未urlEncode,接口请求用的password为:已urlEncode
String myDataEncode = encodeValue(myDataNew);
vars.put("myData",myDataEncode);
System.out.println(myDataEncode);
2、BeanShell PostProcessor
app测试区分用户用的请求参数就是token了,但是token一直是变的,怎么能持续的测试过程不同类型的参数呢?
首先我区分了已登录和未登录的模板:未登录不需要传token参数的,已登录需要,那么已登录的token从哪里获得呢?
可以使用BeanShell PostProcessor完成,代码如下,中间用到了json这个外部包。
import org.json.*;
// get oauthToken for next http request
String response_data = prev.getResponseDataAsString();
JSONObject data_obj = new JSONObject(response_data);
try {
JSONObject data_obj = new JSONObject(response_data);
String apps_oauthToken = data_obj.get("data").get("appLoginInfo").get("oauthToken").toString();
vars.put("oauthToken", apps_oauthToken);
} catch (JSONException e) {
System.out.println("error:");
System.out.println(e.toString());
}
其他分支可以根据自己的需求自定义相关的前置和后置处理。上面这些都是一个java小白,摸爬滚打的成果。欢迎各位大神一起讨教~~~