由于当下测试的业务是基于任务流的,就是说在任务 1 完成后,可能会同时触发任务 2 和任务 3,任务 2 和任务 3 的提交顺序没有彼此依赖关系,
与此同时我设计的接口用例是按层次编写的,像下面的 Demo,
我就在想如果基于全排列,去自动排列组合出所有的场景,然后遍历执行这些场景,应该挺有意思的,
在一个 testSetList 中,用例是按顺序执行 testCaseList 的,但在同一个 testCaseList 中的用例顺序是可以无序执行的,
就是说一个用例集合中的用例是无序的,但用例集合之间的是有序的。
{
"projectName": "Demo",
"testSetList": [
{
"testCaseList": [
{
"caseInfo": {
"caseName": "login",
"caseOwner": "lishu",
"caseComment": "登录-胡斐"
}
}
]
},
{
"testCaseList": [
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "批发新款-提交"
}
}
]
},
{
"testCaseList": [
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "现货批发-增补供应商"
}
},
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "现货批发-下单"
}
}
]
},
{
"testCaseList": [
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "翻单-增补供应商"
}
},
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "下单审核-查询"
}
},
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "下单审核-不通过"
}
}
]
},
{
"testCaseList": [
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "现货批发-修改订单"
}
}
]
},
{
"testCaseList": [
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "下单审核-通过"
}
}
]
},
{
"testCaseList": [
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "文案任务-提交"
}
},
{
"caseInfo": {
"caseComment": "雪山飞狐",
"caseName": "商品列表-试穿"
}
}
]
}
]
}
public class Producer {
public static void arrange(List<ApiTestCase> apiTestCaseList, int start, int len, List<List<ApiTestCase>> setResultApiTestCasesList) {
if (start == len - 1) {
// for (int i = 0; i < apiTestCaseList.size(); i++) {
// System.out.print(apiTestCaseList.get(i).getCaseInfo().getCaseName() + "--" + apiTestCaseList.get(i).getMethod() + ", ");
// }
// System.out.println();
CaseList caseList = new CaseList();
caseList.setApiTestCaseList(apiTestCaseList);
String temp = JSON.toJSONString(caseList);
setResultApiTestCasesList.add(JSON.parseObject(temp, CaseList.class).getApiTestCaseList());
return;
}
for (int i = start; i < len; i++) {
ApiTestCase temp = apiTestCaseList.get(start);
apiTestCaseList.set(start, apiTestCaseList.get(i));
apiTestCaseList.set(i, temp);
arrange(apiTestCaseList, start + 1, len, setResultApiTestCasesList);
temp = apiTestCaseList.get(start);
apiTestCaseList.set(start, apiTestCaseList.get(i));
apiTestCaseList.set(i, temp);
}
}
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
String apiTestProjectStr = ApiTestUtils.loadCases(
"/Users/xxxx/Downloads/workspace/java/demo/src/main/resources/demo.json");
ApiTestProject apiTestProject = JSON.parseObject(apiTestProjectStr, ApiTestProject.class);
LinkedList<ApiTestSet> apiTestSets = apiTestProject.getTestSetList();
List<List<ApiTestCase>> resultApiTestCasesList = new LinkedList<>();
for (ApiTestSet apiTestSet : apiTestSets) {
System.out.print("this set's first case:" + apiTestSet.getTestCaseList().get(0).getCaseInfo().getCaseName());
System.out.println(", size:" + apiTestSet.getTestCaseList().size());
List<List<ApiTestCase>> setResultApiTestCasesList = new LinkedList<>();
arrange(apiTestSet.getTestCaseList(), 0, apiTestSet.getTestCaseList().size(), setResultApiTestCasesList);
if (setResultApiTestCasesList.size() == 1) {
if (resultApiTestCasesList.size() == 0) {
resultApiTestCasesList.add(setResultApiTestCasesList.get(0));
} else {
for (List<ApiTestCase> resultList : resultApiTestCasesList) {
for (List<ApiTestCase> setResultList : setResultApiTestCasesList) {
resultList.addAll(setResultList);
}
}
}
} else {
ResultList resultList = new ResultList();
resultList.setResultApiTestCasesList(new LinkedList<>());
resultList.getResultApiTestCasesList().addAll(resultApiTestCasesList);
// 对结果进行扩容
for (int i=0; i<setResultApiTestCasesList.size()-1; i++) {
String str = JSON.toJSONString(resultList);
ResultList tmp = JSON.parseObject(str, ResultList.class);
resultApiTestCasesList.addAll(tmp.getResultApiTestCasesList());
}
System.out.println("resultApiTestCasesList size:" + resultApiTestCasesList.size());
// 将结果分别填充至原场景末尾
for (int i=0; i<resultApiTestCasesList.size(); i++) {
resultApiTestCasesList.get(i).addAll(setResultApiTestCasesList.get(i % setResultApiTestCasesList.size()));
}
}
setResultApiTestCasesList.clear();
}
System.out.println(resultApiTestCasesList.size());
for (List<ApiTestCase> list : resultApiTestCasesList) {
for (ApiTestCase apiTestCase : list) {
System.out.print(apiTestCase.getCaseInfo().getCaseName() + " ");
}
System.out.println();
}
System.out.println("time:" + (System.currentTimeMillis() - start));
}
}
基本上是抄的别人的基于递归的全排列算法,自己改了改,基本上是搞定了
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 翻单-增补供应商 下单审核-查询 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 翻单-增补供应商 下单审核-不通过 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-查询 翻单-增补供应商 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-查询 下单审核-不通过 翻单-增补供应商 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-不通过 下单审核-查询 翻单-增补供应商 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-不通过 翻单-增补供应商 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 翻单-增补供应商 下单审核-查询 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 翻单-增补供应商 下单审核-不通过 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-查询 翻单-增补供应商 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-查询 下单审核-不通过 翻单-增补供应商 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-不通过 下单审核-查询 翻单-增补供应商 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-不通过 翻单-增补供应商 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 翻单-增补供应商 下单审核-查询 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 翻单-增补供应商 下单审核-不通过 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-查询 翻单-增补供应商 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-查询 下单审核-不通过 翻单-增补供应商 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-不通过 下单审核-查询 翻单-增补供应商 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-不通过 翻单-增补供应商 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 翻单-增补供应商 下单审核-查询 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 翻单-增补供应商 下单审核-不通过 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-查询 翻单-增补供应商 下单审核-不通过 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-查询 下单审核-不通过 翻单-增补供应商 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
login 批发新款-提交 现货批发-增补供应商 现货批发-下单 下单审核-不通过 下单审核-查询 翻单-增补供应商 现货批发-修改订单 下单审核-通过 文案任务-提交 商品列表-试穿
login 批发新款-提交 现货批发-下单 现货批发-增补供应商 下单审核-不通过 翻单-增补供应商 下单审核-查询 现货批发-修改订单 下单审核-通过 商品列表-试穿 文案任务-提交
我也知道全排列的场景十分的多,但大部分业务流最多同时执行的也就 3,4 个场景,全排列的话也就 6,24 个,
一开始还是没觉得会有多少,直到做完了以后才发现那不是一般的多,多的有算出来 18000 多的,直接撑到 OOM 了
所以,一些小的场景还是可以玩一玩的,复杂的就算了吧。。。
如何对 list 进行复制?
一开始试了各种 java 原生方法,复制出来的结果都是一模一样的,
就是说 list.get(0) 与 list.get(1) 的==结果竟然是 true,导致修改其中一个,其他的也变掉了,
最后查了网上的资料,基本上只能用序列化与反序列化了。