refactor(测试计划):场景用例批量执行可选环境

This commit is contained in:
shiziyuan9527 2021-08-12 11:08:57 +08:00 committed by 刘瑞斌
parent 61469c1e8a
commit 46cc049051
6 changed files with 116 additions and 9 deletions

View File

@ -173,6 +173,11 @@ public class TestPlanController {
return testPlanService.getApiCaseEnv(caseIds); return testPlanService.getApiCaseEnv(caseIds);
} }
@PostMapping("/api/scenario/env")
public Map<String, List<String>> getApiScenarioEnv(@RequestBody List<String> caseIds) {
return testPlanService.getApiScenarioEnv(caseIds);
}
@GetMapping("/report/export/{planId}") @GetMapping("/report/export/{planId}")
public void exportHtmlReport(@PathVariable String planId, HttpServletResponse response) throws UnsupportedEncodingException { public void exportHtmlReport(@PathVariable String planId, HttpServletResponse response) throws UnsupportedEncodingException {
testPlanService.exportPlanReport(planId, response); testPlanService.exportPlanReport(planId, response);

View File

@ -22,6 +22,9 @@ import io.metersphere.track.dto.*;
import io.metersphere.track.request.testcase.TestPlanScenarioCaseBatchRequest; import io.metersphere.track.request.testcase.TestPlanScenarioCaseBatchRequest;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -49,6 +52,8 @@ public class TestPlanScenarioCaseService {
private ProjectService projectService; private ProjectService projectService;
@Resource @Resource
private ApiTestEnvironmentMapper apiTestEnvironmentMapper; private ApiTestEnvironmentMapper apiTestEnvironmentMapper;
@Resource
private SqlSessionFactory sqlSessionFactory;
public List<ApiScenarioDTO> list(TestPlanScenarioRequest request) { public List<ApiScenarioDTO> list(TestPlanScenarioRequest request) {
request.setProjectId(null); request.setProjectId(null);
@ -154,6 +159,9 @@ public class TestPlanScenarioCaseService {
if (CollectionUtils.isEmpty(planCaseIdList)) { if (CollectionUtils.isEmpty(planCaseIdList)) {
MSException.throwException("未找到执行场景!"); MSException.throwException("未找到执行场景!");
} }
if (testPlanScenarioRequest.getConfig() != null && !testPlanScenarioRequest.getConfig().getEnvMap().isEmpty()) {
this.setScenarioEnv(planCaseIdList, testPlanScenarioRequest.getConfig().getEnvMap());
}
planCaseIdList.forEach(item -> { planCaseIdList.forEach(item -> {
idStr.append("\"").append(item).append("\"").append(","); idStr.append("\"").append(item).append("\"").append(",");
}); });
@ -179,6 +187,36 @@ public class TestPlanScenarioCaseService {
return apiAutomationService.run(request); return apiAutomationService.run(request);
} }
private void setScenarioEnv(List<String> planScenarioIds, Map<String, String> envMap) {
if (CollectionUtils.isEmpty(planScenarioIds)) {
return;
}
TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample();
testPlanApiScenarioExample.createCriteria().andIdIn(planScenarioIds);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(testPlanApiScenarioExample);
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TestPlanApiScenarioMapper mapper = sqlSession.getMapper(TestPlanApiScenarioMapper.class);
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
String env = testPlanApiScenario.getEnvironment();
if (StringUtils.isBlank(env)) {
continue;
}
Map<String, String> map = JSON.parseObject(env, Map.class);
if (map.isEmpty()) {
continue;
}
Set<String> set = map.keySet();
for (String s : set) {
if (StringUtils.isNotBlank(envMap.get(s))) {
map.put(s, envMap.get(s));
}
}
testPlanApiScenario.setEnvironment(JSON.toJSONString(map));
mapper.updateByPrimaryKeyWithBLOBs(testPlanApiScenario);
}
sqlSession.flushStatements();
}
public List<TestPlanApiScenario> getCasesByPlanId(String planId) { public List<TestPlanApiScenario> getCasesByPlanId(String planId) {
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
example.createCriteria().andTestPlanIdEqualTo(planId); example.createCriteria().andTestPlanIdEqualTo(planId);

View File

@ -1302,6 +1302,42 @@ public class TestPlanService {
return envMap; return envMap;
} }
public Map<String, List<String>> getApiScenarioEnv(List<String> planApiScenarioIds) {
Map<String, List<String>> envMap = new HashMap<>();
if (CollectionUtils.isEmpty(planApiScenarioIds)) {
return envMap;
}
TestPlanApiScenarioExample scenarioExample = new TestPlanApiScenarioExample();
scenarioExample.createCriteria().andIdIn(planApiScenarioIds);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExampleWithBLOBs(scenarioExample);
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
String env = testPlanApiScenario.getEnvironment();
if (StringUtils.isBlank(env)) {
continue;
}
Map<String, String> map = JSON.parseObject(env, Map.class);
if (!map.isEmpty()) {
Set<String> set = map.keySet();
for (String s : set) {
String e = map.get(s);
if (envMap.containsKey(s)) {
List<String> list = envMap.get(s);
if (!list.contains(e)) {
list.add(e);
}
} else {
List<String> envs = new ArrayList<>();
envs.add(e);
envMap.put(s, envs);
}
}
}
}
return envMap;
}
public void exportPlanReport(String planId, HttpServletResponse response) throws UnsupportedEncodingException { public void exportPlanReport(String planId, HttpServletResponse response) throws UnsupportedEncodingException {
TestPlan testPlan = getTestPlan(planId); TestPlan testPlan = getTestPlan(planId);
if (StringUtils.isBlank(testPlan.getReportId())) { if (StringUtils.isBlank(testPlan.getReportId())) {

View File

@ -98,7 +98,7 @@ export default {
projectIds: new Set(), projectIds: new Set(),
}; };
}, },
props: ['planCaseIds'], props: ['planCaseIds', 'type'],
methods: { methods: {
open(testType) { open(testType) {
this.runModeVisible = true; this.runModeVisible = true;
@ -141,7 +141,13 @@ export default {
}, },
showPopover() { showPopover() {
this.projectIds.clear(); this.projectIds.clear();
this.$post('/test/plan/api/case/env', this.planCaseIds, res => { let url = "";
if (this.type === 'apiCase') {
url = '/test/plan/api/case/env';
} else if (this.type === 'apiScenario') {
url = '/test/plan/api/scenario/env';
}
this.$post(url, this.planCaseIds, res => {
let data = res.data; let data = res.data;
if (data) { if (data) {
this.projectEnvListMap = data; this.projectEnvListMap = data;
@ -150,7 +156,7 @@ export default {
} }
} }
this.$refs.envPopover.openEnvSelect(); this.$refs.envPopover.openEnvSelect();
}) });
} }
}, },
}; };

View File

@ -145,7 +145,7 @@
<batch-edit :dialog-title="$t('test_track.case.batch_edit_case')" :type-arr="typeArr" :value-arr="valueArr" <batch-edit :dialog-title="$t('test_track.case.batch_edit_case')" :type-arr="typeArr" :value-arr="valueArr"
:select-row="$refs.table ? $refs.table.selectRows : new Set()" ref="batchEdit" @batchEdit="batchEdit"/> :select-row="$refs.table ? $refs.table.selectRows : new Set()" ref="batchEdit" @batchEdit="batchEdit"/>
<ms-plan-run-mode @handleRunBatch="handleRunBatch" ref="runMode" :plan-case-ids="testPlanCaseIds"/> <ms-plan-run-mode @handleRunBatch="handleRunBatch" ref="runMode" :plan-case-ids="testPlanCaseIds" :type="'apiCase'"/>
</el-card> </el-card>
<ms-task-center ref="taskCenter"/> <ms-task-center ref="taskCenter"/>
</div> </div>

View File

@ -56,8 +56,12 @@
<template v-slot:default="{row}"> <template v-slot:default="{row}">
<div v-if="row.envs"> <div v-if="row.envs">
<span v-for="(k, v, index) in row.envs" :key="index"> <span v-for="(k, v, index) in row.envs" :key="index">
<span v-if="index===0 || index===1">{{v}}: <span v-if="index===0 || index===1">
<el-tag type="success" size="mini" effect="plain">{{k}}</el-tag><br/> <span class="project-name" :title="v">{{v}}</span>:
<el-tag type="success" size="mini" effect="plain">
{{k}}
</el-tag>
<br/>
</span> </span>
<el-popover <el-popover
placement="top" placement="top"
@ -157,7 +161,7 @@
<!-- 批量编辑 --> <!-- 批量编辑 -->
<batch-edit :dialog-title="$t('test_track.case.batch_edit_case')" :type-arr="typeArr" :value-arr="valueArr" <batch-edit :dialog-title="$t('test_track.case.batch_edit_case')" :type-arr="typeArr" :value-arr="valueArr"
:select-row="this.$refs.table ? this.$refs.table.selectRows : new Set()" ref="batchEdit" @batchEdit="batchEdit"/> :select-row="this.$refs.table ? this.$refs.table.selectRows : new Set()" ref="batchEdit" @batchEdit="batchEdit"/>
<ms-plan-run-mode @handleRunBatch="handleRunBatch" ref="runMode"/> <ms-plan-run-mode @handleRunBatch="handleRunBatch" ref="runMode" :plan-case-ids="planCaseIds" :type="'apiScenario'"/>
<ms-task-center ref="taskCenter"/> <ms-task-center ref="taskCenter"/>
</div> </div>
</template> </template>
@ -180,7 +184,7 @@ import {
import {TEST_PLAN_SCENARIO_CASE} from "@/common/js/constants"; import {TEST_PLAN_SCENARIO_CASE} from "@/common/js/constants";
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
import BatchEdit from "@/business/components/track/case/components/BatchEdit"; import BatchEdit from "@/business/components/track/case/components/BatchEdit";
import MsPlanRunMode from "../../../common/PlanRunMode"; import MsPlanRunMode from "@/business/components/track/plan/common/PlanRunModeWithEnv";
import PriorityTableItem from "@/business/components/track/common/tableItems/planview/PriorityTableItem"; import PriorityTableItem from "@/business/components/track/common/tableItems/planview/PriorityTableItem";
import {API_SCENARIO_FILTERS} from "@/common/js/table-constants"; import {API_SCENARIO_FILTERS} from "@/common/js/table-constants";
import MsTaskCenter from "../../../../../task/TaskCenter"; import MsTaskCenter from "../../../../../task/TaskCenter";
@ -275,6 +279,7 @@ export default {
valueArr: { valueArr: {
projectEnv: [] projectEnv: []
}, },
planCaseIds: []
} }
}, },
computed: { computed: {
@ -373,6 +378,11 @@ export default {
}) })
}, },
handleBatchExecute() { handleBatchExecute() {
let rows = this.orderBySelectRows(this.$refs.table.selectRows);
this.planCaseIds = [];
rows.forEach(row => {
this.planCaseIds.push(row.id);
})
this.$refs.runMode.open('API'); this.$refs.runMode.open('API');
}, },
orderBySelectRows(rows){ orderBySelectRows(rows){
@ -409,9 +419,12 @@ export default {
this.$post("/test/plan/scenario/case/run", param, response => { this.$post("/test/plan/scenario/case/run", param, response => {
this.$message(this.$t('commons.run_message')); this.$message(this.$t('commons.run_message'));
this.$refs.taskCenter.open(); this.$refs.taskCenter.open();
this.search();
}, () => {
this.search();
}); });
} }
this.search();
}, },
execute(row) { execute(row) {
this.infoDb = false; this.infoDb = false;
@ -537,4 +550,13 @@ export default {
margin-left: 5px; margin-left: 5px;
} }
.project-name {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100px;
vertical-align: middle;
}
</style> </style>