前言:以往在json串比对的时候,我们都是一对一的忽略顺序比对方式,本次遇到了一个奇怪比对方式(反正我是之前没想到的),看来又得撸码打包了。
别总以为测试人员就不需要撸码,没听说一句老话么,不会前端的测试不是好的架构师(搞笑的)。好了,bb这么多,就是希望没事提高一下自身水平,还是来看看什么情况。先给大家简单讲一讲之前我们在做接口自动化测试的时候,我们是进行json串的比对,像这样:
//[OLD]
//用例预期结果:
[{"channel":"AA","value":12},{"channel":"BB","value":20}]
//接口返回的结果:
[{"channel":"BB","value":20},{"channel":"AA","value":12}]
这样的比对很简单,只需要以数组的形式比对就可以了(或者其他方法),以下是我从CSDN里面参考的代码(需要自行导如Gson包)
/**
* 比较两个json字符串是否等价
* (本次用的是gson2.8.5的包,自行下载)
*/
public boolean same(String a, String b) {
if (a == null) {
return b == null;
}
if (a.equals(b)) {
return true;
}
JsonElement aElement = parser.parse(a);
JsonElement bElement = parser.parse(b);
if (gson.toJson(aElement).equals(gson.toJson(bElement))) {
return true;
}
return same(aElement, bElement);
}
private boolean same(JsonElement a, JsonElement b) {
if (a.isJsonObject() && b.isJsonObject()) {
return same((JsonObject) a, (JsonObject) b);
} else if (a.isJsonArray() && b.isJsonArray()) {
return same((JsonArray) a, (JsonArray) b);
} else if (a.isJsonPrimitive() && b.isJsonPrimitive()) {
return same((JsonPrimitive) a, (JsonPrimitive) b);
} else if (a.isJsonNull() && b.isJsonNull()) {
return same((JsonNull) a, (JsonNull) b);
} else {
return Boolean.FALSE;
}
}
【可以自行打成包然后放入jmeter进行比对json】
现在,由于开发那边改了需求,连我的比对方式也得改变[图片上传失败...(image-b4a2b3-1556261984721)] 。Just Like This:
//[NEW]
//用例预期结果:
[{"channel":"AA","value":12},{"channel":"BB","value":20}]
//接口返回的结果:
[{"value":20,"channel":"BB"},{"channel":"AA","value":12},{"channel":"CC","value":100},{"channel":"DD","value":100},{"channel":"EE","value":100}]
要求这样的比对为true,Emmmm.....
这不是数学上面的包含关系么,我想想怎么办?
我想想,在小时候学数学的时候,老师教得这么一个原理:当A⊂B的时候,得出A∩B = A。
在Java里面的Connection框架里面,有一个集合的方法求交集,那就是retainAll()
即(参考代码https://blog.csdn.net/qq_25806863/article/details/70312046):
//Set集合
Set<String> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>();
set1.add("a"); set1.add("b"); set1.add("c");
set2.add("c"); set2.add("d"); set2.add("e");
//交集 set1.retainAll(set2);
System.out.println("交集是 "+set1);
我也去尝试了一下,的确是不行的,为什么?因为这次不仅仅是考虑到两个json串的顺序,还考虑到了串里面key、value的顺序在里面了(认真观察[NEW]的那串json)。此时,我的大佬在旁边给了一点提示,要不要考虑使用List,Gson转成对象试试?
于是有了以下的代码(可提供参考意见进行改进):
public class Demo {
public boolean sameJson(String jsonA, String jsonB) {
// 通过Gson转对象
Gson gson = new Gson();
// 通过List存储对象
List<Info> infoListA = gson.fromJson(jsonA, new TypeToken<List<Info>>() {
}.getType());
List<Info> infoListB = gson.fromJson(jsonB, new TypeToken<List<Info>>() {
}.getType());
// 计数
int count = 0;
for (Info infoa : infoListA) {
for (Info infob : infoListB) {
if (!infoa.equals(infob)) {
continue;
}
count++;
}
}
if (count == infoListA.size()) {
return true;
} else {
return false;
}
}
/*
* 造一个key value实体类
*/
public class DemoInfo {
private String channel;
private int value;
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
// 重写了equals方法,以短的json
public boolean equals(DemoInfo info) {
if (info.getChannel() != null) {
if (this.channel.equals(info.getChannel())
&& this.value == info.getValue()) {
return true;
}
}
return false;
}
}
}
写到了这里,提出几点疑问:
1、为什么我写方法接的是String类型,而不是json类型?
2、DemoInfo这个对象每次都需要自己创建,会不会麻烦?
3、还有没有其他的办法?
那么如何打成包给jmeter用呢?
参考传送门:https://blog.csdn.net/qq_34845382/article/details/53885907
划重点:[注意点]
打包之前,一定要建立一个MANIFEST.MF文件在工程内
Manifest-Version: 1.0 ------------------------前面都要留一个空格
Class-Path: ./gson-2.8.5.jar ------------------------第三方包放在一起,当前文件夹
Main-Class: com.xxx.Main ------------------------包名.主类
打包的过程我就不详细讲了,接下来我讲讲jmeter那边应该怎么用。
首先,肯定是将打好的包放在D:\apache-jmeter-3.3\lib\ext下面啦(别忘了放第三方的jar包),然后?打开jmeter咯。搞个demo先:
把准备好的csv用例demo
脚本运行:
下一期我讲解答以上的问题,希望各位大神提出宝贵的建议,优化测试方法。