feat(接口测试): 报告增加运行模式和资源池的显示

--story=1010762 --user=王孝刚 【测试跟踪】测试报告显示(运行模式、资源池)-UI测试
https://www.tapd.cn/55049933/s/1313758
This commit is contained in:
wxg0103 2022-12-07 16:21:58 +08:00 committed by 刘瑞斌
parent b4ff3a2d3e
commit 64e5e3b6d8
13 changed files with 226 additions and 41 deletions

View File

@ -0,0 +1,15 @@
package io.metersphere.api.dto;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class ApiReportEnvConfigUtil {
private String envName;
private String resourcePoolName;
}

View File

@ -41,4 +41,7 @@ public class ApiScenarioReportDTO {
//<项目名称<环境名称>>
private LinkedHashMap<String, List<String>> projectEnvMap;
private String mode;
private String poolName;
}

View File

@ -385,6 +385,7 @@ public class ApiScenarioExecuteService {
configDTO.setEnvMap(request.getEnvironmentMap());
request.setConfig(configDTO);
}
request.getConfig().setEnvMap(request.getEnvironmentMap());
// 生成调试结果
ApiScenarioReportResult report = apiScenarioReportService.initDebugResult(request);
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(request.getScenarioId());

View File

@ -162,6 +162,8 @@ public class ApiDefinitionService {
private ApiScenarioMapper apiScenarioMapper;
@Resource
private JMeterService jMeterService;
@Resource
private BaseTestResourcePoolService baseTestResourcePoolService;
private final ThreadLocal<Long> currentApiOrder = new ThreadLocal<>();
private final ThreadLocal<Long> currentApiCaseOrder = new ThreadLocal<>();
@ -1573,7 +1575,11 @@ public class ApiDefinitionService {
if (StringUtils.isNotBlank(contentStr)) {
JSONObject content = JSONUtil.parseObject(contentStr);
if (StringUtils.isNotEmpty(result.getEnvConfig())) {
content.put("envName", this.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig()));
ApiReportEnvConfigUtil envNameByEnvConfig = this.getEnvNameByEnvConfig(result.getProjectId(), result.getEnvConfig());
if (envNameByEnvConfig != null) {
content.put("envName", envNameByEnvConfig.getEnvName());
content.put("poolName", envNameByEnvConfig.getResourcePoolName());
}
}
contentStr = content.toString();
reportResult.setContent(contentStr);
@ -1584,9 +1590,8 @@ public class ApiDefinitionService {
return reportResult;
}
public String getEnvNameByEnvConfig(String projectId, String envConfig) {
String envName = null;
public ApiReportEnvConfigUtil getEnvNameByEnvConfig(String projectId, String envConfig) {
ApiReportEnvConfigUtil apiReportEnvConfig = new ApiReportEnvConfigUtil();
RunModeConfigDTO runModeConfigDTO = null;
try {
runModeConfigDTO = JSON.parseObject(envConfig, RunModeConfigDTO.class);
@ -1595,9 +1600,17 @@ public class ApiDefinitionService {
}
if (StringUtils.isNotEmpty(projectId) && runModeConfigDTO != null && MapUtils.isNotEmpty(runModeConfigDTO.getEnvMap())) {
String envId = runModeConfigDTO.getEnvMap().get(projectId);
envName = apiTestEnvironmentService.selectNameById(envId);
apiReportEnvConfig.setEnvName(apiTestEnvironmentService.selectNameById(envId));
}
return envName;
if (runModeConfigDTO != null && StringUtils.isNotBlank(runModeConfigDTO.getResourcePoolId())) {
TestResourcePool resourcePool = baseTestResourcePoolService.getResourcePool(runModeConfigDTO.getResourcePoolId());
if (resourcePool != null) {
apiReportEnvConfig.setResourcePoolName(resourcePool.getName());
}
} else {
apiReportEnvConfig.setResourcePoolName("LOCAL");
}
return apiReportEnvConfig;
}
public ApiReportResult getDbResult(String testId, String type) {
@ -2785,8 +2798,10 @@ public class ApiDefinitionService {
runModeConfigDTO.setEnvMap(new HashMap<>() {{
this.put(request.getProjectId(), request.getEnvironmentId());
}});
runModeConfigDTO.setResourcePoolId(request.getConfig().getResourcePoolId());
result.setEnvConfig(JSON.toJSONString(runModeConfigDTO));
}
result.setActuator(request.getConfig().getResourcePoolId());
apiDefinitionExecResultMapper.insert(result);
}
if (request.isEditCaseRequest() && CollectionUtils.isNotEmpty(request.getTestElement().getHashTree()) && CollectionUtils.isNotEmpty(request.getTestElement().getHashTree().get(0).getHashTree())) {

View File

@ -764,6 +764,16 @@ public class TestPlanApiCaseService {
result.setName(reportName);
result.setProjectId(apiCase.getProjectId());
result.setTriggerMode(TriggerMode.MANUAL.name());
RunModeConfigDTO runModeConfigDTO = new RunModeConfigDTO();
jMeterService.verifyPool(result.getProjectId(), runModeConfigDTO);
if (StringUtils.isNotEmpty(testPlanApiCase.getEnvironmentId())) {
runModeConfigDTO.setEnvMap(new HashMap<>() {{
this.put(result.getProjectId(), testPlanApiCase.getEnvironmentId());
}});
runModeConfigDTO.setResourcePoolId(runModeConfigDTO.getResourcePoolId());
result.setEnvConfig(JSON.toJSONString(runModeConfigDTO));
}
result.setActuator(runModeConfigDTO.getResourcePoolId());
apiDefinitionExecResultMapper.insert(result);
apiCase.setId(testId);

View File

@ -129,6 +129,7 @@ public class ApiScenarioReportService {
reportResult.setTestId(reportId);
ApiScenarioReportDTO dto = apiScenarioReportStructureService.apiIntegratedReport(reportId);
apiScenarioReportStructureService.initProjectEnvironmentByEnvConfig(dto, result.getEnvConfig());
apiScenarioReportStructureService.getEnvConfig(dto, result.getEnvConfig());
reportResult.setContent(JSON.toJSONString(dto));
return reportResult;
}

View File

@ -13,6 +13,8 @@ import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.utils.*;
import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.RequestResult;
import io.metersphere.dto.RunModeConfigDTO;
import io.metersphere.service.BaseTestResourcePoolService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
@ -70,6 +72,8 @@ public class ApiScenarioReportStructureService {
private ApiScenarioEnvService apiScenarioEnvService;
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
private BaseTestResourcePoolService baseTestResourcePoolService;
public void save(List<ApiScenarioWithBLOBs> apiScenarios, String reportId, String reportType) {
List<StepTreeDTO> dtoList = new LinkedList<>();
@ -500,6 +504,10 @@ public class ApiScenarioReportStructureService {
dto.setName(report.getName());
dto.setEnvConfig(report.getEnvConfig());
this.initProjectEnvironmentByEnvConfig(dto, report.getEnvConfig());
this.getEnvConfig(dto, report.getEnvConfig());
if (report != null && report.getReportType().equals(ReportTypeConstants.SCENARIO_INDEPENDENT.name())) {
dto.setMode(null);
}
return dto;
}
}
@ -692,4 +700,24 @@ public class ApiScenarioReportStructureService {
return (T) clazz.getInterfaces();
}
}
public void getEnvConfig(ApiScenarioReportDTO dto, String envConfig) {
RunModeConfigDTO runModeConfigDTO = null;
try {
runModeConfigDTO = JSON.parseObject(envConfig, RunModeConfigDTO.class);
} catch (Exception e) {
LogUtil.error("解析" + envConfig + "为RunModeConfigDTO时失败", e);
}
if (runModeConfigDTO != null && StringUtils.isNotBlank(runModeConfigDTO.getResourcePoolId())) {
TestResourcePool resourcePool = baseTestResourcePoolService.getResourcePool(runModeConfigDTO.getResourcePoolId());
if (resourcePool != null) {
dto.setPoolName(resourcePool.getName());
}
} else {
dto.setPoolName("LOCAL");
}
if (runModeConfigDTO != null && StringUtils.isNotBlank(runModeConfigDTO.getMode())) {
dto.setMode(runModeConfigDTO.getMode());
}
}
}

View File

@ -13,6 +13,8 @@
:debug="debug"
:report="report"
:project-env-map="projectEnvMap"
:mode="mode"
:pool-name="poolName"
@reportExport="handleExport"
@reportSave="handleSave" />
@ -99,6 +101,8 @@
:project-env-map="projectEnvMap"
:title="report.name"
:content="content"
:mode="mode"
:pool-name="poolName"
:report="report"
:total-time="totalTime" />
</div>
@ -163,6 +167,8 @@ export default {
tempResult: [],
projectEnvMap: {},
showCancel: false,
poolName: '',
mode: '',
};
},
activated() {
@ -489,6 +495,10 @@ export default {
if (report.projectEnvMap) {
this.projectEnvMap = report.projectEnvMap;
}
if (report.poolName) {
this.poolName = report.poolName;
}
this.mode = report.mode;
this.fullTreeNodes = report.steps;
this.content.console = report.console;
this.content.error = report.error;

View File

@ -3,6 +3,8 @@
:title="title"
:report="report"
:project-env-map="projectEnvMap"
:pool-name="poolName"
:mode="mode"
:type="$t('report.api_test_report')">
<ms-metric-chart :content="content" :is-export="true" :totalTime="totalTime" :report="report" />
<div class="scenario-result" v-for="(scenario, index) in content.scenarios" :key="index" :scenario="scenario">
@ -95,6 +97,8 @@ export default {
totalTime: Number,
projectEnvMap: {},
title: String,
poolName: String,
mode: String,
},
data() {
return {};

View File

@ -81,7 +81,26 @@
</div>
</el-col>
</el-row>
<el-row v-if="showProjectEnv" type="flex">
<el-row type="flex" style="margin-top: 5px">
<el-col v-if="this.mode">
<div style="float: left">
<span> {{ $t('report.run_model') + ':' }} </span>
</div>
<div style="color: #61c550; margin-left: 10px; float: left">
{{ getModeName(this.mode) }}
</div>
</el-col>
<el-col v-if="this.poolName">
<div style="float: left">
<span> {{ $t('load_test.select_resource_pool') + ':' }} </span>
</div>
<div style="color: #61c550; margin-left: 10px; float: left">
{{ this.poolName }}
</div>
</el-col>
<el-col></el-col>
</el-row>
<el-row v-if="showProjectEnv" type="flex" style="margin-top: 5px">
<span> {{ $t('commons.environment') + ':' }} </span>
<div v-for="(values, key) in projectEnvMap" :key="key" style="margin-right: 10px">
{{ key + ':' }}
@ -121,6 +140,8 @@ export default {
default: false,
},
isPlan: Boolean,
poolName: String,
mode: String,
},
computed: {
showProjectEnv() {
@ -235,6 +256,14 @@ export default {
}
});
},
getModeName(mode) {
switch (mode) {
case 'serial':
return this.$t('run_mode.serial');
case 'parallel':
return this.$t('run_mode.parallel');
}
},
},
};
</script>

View File

@ -54,13 +54,24 @@
</div>
</el-col>
</el-row>
<el-row type="flex" v-if="response && response.envName">
<div style="font-size: 14px; color: #aaaaaa; float: left">
<span> {{ $t('commons.environment') + ':' }} </span>
</div>
<div style="font-size: 14px; color: #61c550; margin-left: 10px; float: left">
{{ response.envName }}
</div>
<el-row type="flex" style="margin-top: 5px">
<el-col v-if="response && response.poolName">
<div style="font-size: 14px; color: #aaaaaa; float: left">
<span> {{ $t('load_test.select_resource_pool') + ':' }} </span>
</div>
<div style="font-size: 14px; color: #61c550; margin-left: 10px; float: left">
{{ response.poolName }}
</div>
</el-col>
<el-col type="flex" v-if="response && response.envName">
<div style="font-size: 14px; color: #aaaaaa; float: left">
<span> {{ $t('commons.environment') + ':' }} </span>
</div>
<div style="font-size: 14px; color: #61c550; margin-left: 10px; float: left">
{{ response.envName }}
</div>
</el-col>
<el-col></el-col>
</el-row>
</div>
</template>

View File

@ -1,6 +1,13 @@
<template>
<div class="report-export">
<ms-report-title :title="title" :type="type" :report="report" :project-env-map="projectEnvMap"/>
<ms-report-title
:title="title"
:type="type"
:report="report"
:project-env-map="projectEnvMap"
:mode="mode"
:pool-name="poolName"
/>
<slot></slot>
</div>
</template>
@ -10,13 +17,19 @@ import MsReportTitle from "./MsReportTitle";
export default {
name: "MsReportExportTemplate",
components: {MsReportTitle},
props: {title: String, type: String, report: Object, projectEnvMap: {}},
}
components: { MsReportTitle },
props: {
title: String,
type: String,
report: Object,
projectEnvMap: {},
mode: String,
poolName: String,
},
};
</script>
<style scoped>
.report-export {
padding: 30px;
}

View File

@ -5,23 +5,55 @@
<div class="title">
{{ type }}- {{ title }}
<span v-if="report && (report.endTime || report.createTime)">
<span style="margin-left: 10px">{{ $t('report.test_start_time') }}</span>
<span class="time"> {{ report.createTime | datetimeFormat }}</span>
<span style="margin-left: 10px">{{ $t('report.test_end_time') }}</span>
<span class="time"> {{ report.endTime | datetimeFormat }}</span>
</span>
<span style="margin-left: 10px"
>{{ $t("report.test_start_time") }}</span
>
<span class="time"> {{ report.createTime | datetimeFormat }}</span>
<span style="margin-left: 10px"
>{{ $t("report.test_end_time") }}</span
>
<span class="time"> {{ report.endTime | datetimeFormat }}</span>
</span>
</div>
</div>
<div class="report-right">
<img class="logo" src="/assets/logo-MeterSphere.png">
<img class="logo" src="/assets/logo-MeterSphere.png" />
</div>
</el-row>
<el-row v-if="showProjectEnv" type="flex">
<span> {{ $t('commons.environment') + ':' }} </span>
<div v-for="(values,key) in projectEnvMap" :key="key" style="margin-right: 10px">
<el-row type="flex" style="margin-top: 5px">
<el-col v-if="this.mode">
<div style="float: left">
<span> {{ $t("report.run_model") + ":" }} </span>
</div>
<div style="color: #61c550; margin-left: 10px; float: left">
{{ getModeName(this.mode) }}
</div>
</el-col>
<el-col v-if="this.poolName">
<div style="float: left">
<span> {{ $t("load_test.select_resource_pool") + ":" }} </span>
</div>
<div style="color: #61c550; margin-left: 10px; float: left">
{{ this.poolName }}
</div>
</el-col>
<el-col></el-col>
</el-row>
<el-row v-if="showProjectEnv" type="flex" style="margin-top: 5px">
<span> {{ $t("commons.environment") + ":" }} </span>
<div
v-for="(values, key) in projectEnvMap"
:key="key"
style="margin-right: 10px"
>
{{ key + ":" }}
<ms-tag v-for="(item,index) in values" :key="index" type="success" :content="item"
style="margin-left: 2px"/>
<ms-tag
v-for="(item, index) in values"
:key="index"
type="success"
:content="item"
style="margin-left: 2px"
/>
</div>
</el-row>
</div>
@ -32,21 +64,37 @@ import MsTag from "../MsTag";
export default {
name: "MsReportTitle",
components: {MsTag},
props: {title: String, type: String, report: Object, projectEnvMap: {}},
components: { MsTag },
props: {
title: String,
type: String,
report: Object,
projectEnvMap: {},
mode: String,
poolName: String,
},
data() {
return {}
return {};
},
computed: {
showProjectEnv() {
return this.projectEnvMap && JSON.stringify(this.projectEnvMap) !== '{}';
return this.projectEnvMap && JSON.stringify(this.projectEnvMap) !== "{}";
},
}
}
},
methods: {
getModeName(mode) {
switch (mode) {
case "serial":
return this.$t("run_mode.serial");
case "parallel":
return this.$t("run_mode.parallel");
}
},
},
};
</script>
<style scoped>
.report-left {
float: left;
}
@ -58,10 +106,9 @@ export default {
.logo {
height: 30px;
line-height: 30px;
vertical-align: middle
vertical-align: middle;
}
.report-left {
font-size: 15px;
}
@ -73,6 +120,4 @@ export default {
.title {
margin-bottom: 5px;
}
</style>