fix(接口测试): 修复串行顺序错误问题

--bug=1009552 --user=赵勇 【接口测试】测试用例批量执行,串行,执行顺序不对 https://www.tapd.cn/55049933/s/1091257
This commit is contained in:
fit2-zhao 2022-01-13 11:06:54 +08:00 committed by song-tianyang
parent cd1296c59c
commit 6db9f9d085
6 changed files with 78 additions and 89 deletions

View File

@ -22,7 +22,9 @@ import io.metersphere.dto.MsExecResponseDTO;
import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.service.EnvironmentGroupProjectService;
import io.metersphere.utils.LoggerUtil;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.comparators.FixedOrderComparator;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
@ -32,10 +34,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
@Service
@Transactional(rollbackFor = Exception.class)
@ -145,6 +144,16 @@ public class ApiCaseExecuteService {
List<ApiTestCaseWithBLOBs> list = apiTestCaseMapper.selectByExampleWithBLOBs(example);
LoggerUtil.debug("查询到执行数据:" + list.size());
if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) {
if (request.getCondition() == null || !request.getCondition().isSelectAll()) {
// 按照id指定顺序排序
FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(request.getIds());
fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
BeanComparator beanComparator = new BeanComparator("id", fixedOrderComparator);
Collections.sort(list, beanComparator);
}
}
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
ApiDefinitionExecResultMapper batchMapper = sqlSession.getMapper(ApiDefinitionExecResultMapper.class);
if (StringUtils.isEmpty(request.getTriggerMode())) {
@ -152,7 +161,7 @@ public class ApiCaseExecuteService {
}
List<MsExecResponseDTO> responseDTOS = new LinkedList<>();
Map<String, ApiDefinitionExecResult> executeQueue = new HashMap<>();
Map<String, ApiDefinitionExecResult> executeQueue = new LinkedHashMap<>();
String status = request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) ? APITestStatus.Waiting.name() : APITestStatus.Running.name();
list.forEach(caseWithBLOBs -> {
ApiDefinitionExecResult report = ApiDefinitionExecResultUtil.initBase(caseWithBLOBs.getId(), APITestStatus.Running.name(), null, request.getConfig());

View File

@ -213,7 +213,6 @@
@runScenario="runDebug"
@stopScenario="stop"
@setDomain="setDomain"
@reloadResult="reloadResult"
@openScenario="openScenario"/>
</span>
</el-tree>
@ -468,7 +467,6 @@ export default {
showFollow: false,
envGroupId: "",
environmentType: ENV_TYPE.JSON,
debugResults: [],
}
},
watch: {
@ -641,7 +639,6 @@ export default {
this.reqTotalTime = 0;
this.reqTotal = 0;
this.reqSuccess = 0;
this.debugResults = [];
},
clearResult(arr) {
if (arr) {
@ -723,83 +720,49 @@ export default {
},
runningNodeChild(arr, resultData) {
arr.forEach(item => {
if (resultData && resultData.startsWith("result_")) {
let data = JSON.parse(resultData.substring(7));
if (data.method === 'Request' && data.subRequestResults && data.subRequestResults.length > 0) {
data.subRequestResults.forEach(subItem => {
if (item.data && item.data.id + "_" + item.data.parentIndex === subItem.resourceId) {
subItem.requestResult.console = data.responseResult.console;
item.data.requestResult.push(subItem);
//
this.resultEvaluation(subItem.resourceId, subItem.success);
item.data.testing = false;
item.data.debug = true;
}
})
} else if ((item.data && item.data.id + "_" + item.data.parentIndex === data.resourceId)
|| (item.data && item.data.resourceId + "_" + item.data.parentIndex === data.resourceId)) {
if (item.data.requestResult) {
item.data.requestResult.push(data);
} else {
item.data.requestResult = [data];
}
//
this.resultEvaluation(data.resourceId, data.success);
item.data.testing = false;
item.data.debug = true;
}
} else if (item.data && item.data.id + "_" + item.data.parentIndex === resultData) {
item.data.testing = true;
this.runningEditParent(item.parent);
}
this.setResults(resultData, item);
if (item.childNodes && item.childNodes.length > 0) {
this.runningNodeChild(item.childNodes, resultData);
}
})
},
setParentIndex(stepArray, fullPath) {
for (let i in stepArray) {
// debug
stepArray[i].data.parentIndex = fullPath ? fullPath + "_" + stepArray[i].data.index : stepArray[i].data.index;
if (stepArray[i].childNodes && stepArray[i].childNodes.length > 0) {
this.setParentIndex(stepArray[i].childNodes, stepArray[i].data.parentIndex);
setResults(resultData, item) {
if (resultData && resultData.startsWith("result_")) {
let data = JSON.parse(resultData.substring(7));
if (data.method === 'Request' && data.subRequestResults && data.subRequestResults.length > 0) {
data.subRequestResults.forEach(subItem => {
if (item.data && item.data.id + "_" + item.data.parentIndex === subItem.resourceId) {
subItem.requestResult.console = data.responseResult.console;
if (!item.data.requestResult) {
item.data.requestResult = [];
}
item.data.requestResult.push(subItem);
//
this.resultEvaluation(subItem.resourceId, subItem.success);
item.data.testing = false;
item.data.debug = true;
}
})
} else if ((item.data && item.data.id + "_" + item.data.parentIndex === data.resourceId)
|| (item.data && item.data.resourceId + "_" + item.data.parentIndex === data.resourceId)) {
if (!item.data.requestResult) {
item.data.requestResult = [];
}
item.data.requestResult.push(data);
//
this.resultEvaluation(data.resourceId, data.success);
item.data.testing = false;
item.data.debug = true;
}
}
},
reloadResult() {
if (this.debugResults && this.debugResults.length > 0) {
this.setParentIndex(this.$refs.stepTree.root.childNodes);
this.debugResults.forEach(item => {
this.runningEvaluation(item);
})
} else if (item.data && item.data.id + "_" + item.data.parentIndex === resultData) {
item.data.testing = true;
this.runningEditParent(item.parent);
}
},
runningEvaluation(resultData) {
if (this.$refs.stepTree && this.$refs.stepTree.root) {
this.$refs.stepTree.root.childNodes.forEach(item => {
if (item.data && item.data.id + "_" + item.data.parentIndex === resultData) {
item.data.testing = true;
} else if (resultData && resultData.startsWith("result_")) {
let data = JSON.parse(resultData.substring(7));
if (data.method === 'Request' && data.subRequestResults && data.subRequestResults.length > 0) {
data.subRequestResults.forEach(subItem => {
if (item.data && item.data.id + "_" + item.data.parentIndex === subItem.resourceId) {
item.data.requestResult.push(subItem);
//
this.resultEvaluation(subItem.resourceId, subItem.success);
item.data.testing = false;
item.data.debug = true;
}
})
} else if (item.data && item.data.id + "_" + item.data.parentIndex === data.resourceId
|| (item.data && item.data.resourceId + "_" + item.data.parentIndex === data.resourceId)) {
item.data.requestResult.push(data);
//
this.resultEvaluation(data.resourceId, data.success);
item.data.testing = false;
item.data.debug = true;
}
}
this.setResults(resultData, item);
if (item.childNodes && item.childNodes.length > 0) {
this.runningNodeChild(item.childNodes, resultData);
}
@ -818,16 +781,12 @@ export default {
}
}
this.runningEvaluation(e.data);
if (e.data && e.data.startsWith("result_")) {
this.debugResults.push(e.data);
}
this.message = getUUID();
if (e.data && e.data.indexOf("MS_TEST_END") !== -1) {
this.runScenario = undefined;
this.debugLoading = false;
this.message = "stop";
this.stopDebug = "stop";
this.currentScenario.debugResults = this.debugResults;
this.reload();
}
},

View File

@ -113,6 +113,9 @@ export default {
this.scenario.projectId = getCurrentProjectID();
}
if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded) {
let scenarios = JSON.parse(JSON.stringify(this.scenario.hashTree));
let map = new Map();
this.formatResult(map, scenarios);
this.result = this.$get("/api/automation/getApiScenario/" + this.scenario.id, response => {
if (response.data) {
this.scenario.loaded = true;
@ -137,7 +140,7 @@ export default {
this.scenario.headers = obj.headers;
this.scenario.variables = obj.variables;
this.scenario.environmentMap = obj.environmentMap;
this.$emit('reloadResult');
this.setResult(this.scenario.hashTree, map);
this.$emit('refReload');
}
})
@ -178,6 +181,34 @@ export default {
},
},
methods: {
formatResult(map, scenarios) {
scenarios.forEach(item => {
if (this.stepFilter.get("AllSamplerProxy").indexOf(item.type) !== -1 && item.requestResult) {
let key = (item.id ? item.id : item.resourceId) + "_" + item.index;
if (map.has(key)) {
map.get(key).push(...item.requestResult);
} else {
map.set(key, item.requestResult);
}
}
if (item.hashTree && item.hashTree.length > 0) {
this.formatResult(map, item.hashTree);
}
})
},
setResult(array, scenarios) {
if (array && scenarios) {
array.forEach(item => {
let key = (item.id ? item.id : item.resourceId) + "_" + item.index;
if (scenarios.has(key)) {
item.requestResult = scenarios.get(key);
}
if (item.hashTree && item.hashTree.length > 0) {
this.setResult(item.hashTree, scenarios);
}
})
}
},
run() {
this.scenario.run = true;
let runScenario = JSON.parse(JSON.stringify(this.scenario));

View File

@ -35,7 +35,6 @@
@refReload="refReload"
@openScenario="openScenario"
@setDomain="setDomain"
@reloadResult="reloadResult"
/>
</keep-alive>
</div>
@ -236,9 +235,6 @@ export default {
setDomain() {
this.$emit("setDomain");
},
reloadResult() {
this.$emit('reloadResult');
}
}
}
</script>

View File

@ -106,9 +106,6 @@
this.reload();
},
},
created() {
this.$emit('reloadResult');
},
methods: {
reload() {
this.loading = true

View File

@ -161,9 +161,6 @@ export default {
},
};
},
created() {
this.$emit('reloadResult');
},
watch: {
message() {
this.reload();