feat(测试计划): 统计报告新增性能测试用例饼图

This commit is contained in:
shiziyuan9527 2021-01-12 18:08:40 +08:00
parent 20c9d9b50c
commit 17ecef469b
11 changed files with 199 additions and 18 deletions

View File

@ -6,6 +6,7 @@ import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.track.dto.TestCaseReportMetricDTO;
import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.dto.TestPlanDTO;
import io.metersphere.track.dto.TestPlanLoadCaseDTO;
import org.apache.commons.lang3.StringUtils;
public abstract class ReportComponent {
@ -26,4 +27,7 @@ public abstract class ReportComponent {
public void readRecord(ApiScenarioDTO testCase) {
}
public void readRecord(TestPlanLoadCaseDTO testCase) {
}
}

View File

@ -4,10 +4,7 @@ import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ScenarioStatus;
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.track.dto.FailureTestCasesAdvanceDTO;
import io.metersphere.track.dto.TestCaseReportMetricDTO;
import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.dto.TestPlanDTO;
import io.metersphere.track.dto.*;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
@ -17,6 +14,7 @@ public class ReportFailureAdvanceResultComponent extends ReportComponent {
private List<TestPlanCaseDTO> functionalTestCases = new ArrayList<>();
private List<TestPlanApiCaseDTO> apiTestCases = new ArrayList<>();
private List<ApiScenarioDTO> scenarioTestCases = new ArrayList<>();
private List<TestPlanLoadCaseDTO> loadTestCases = new ArrayList<>();
public ReportFailureAdvanceResultComponent(TestPlanDTO testPlan) {
super(testPlan);
@ -44,12 +42,20 @@ public class ReportFailureAdvanceResultComponent extends ReportComponent {
}
}
@Override
public void readRecord(TestPlanLoadCaseDTO testCase) {
if (StringUtils.equals(testCase.getCaseStatus(), "error")) {
this.loadTestCases.add(testCase);
}
}
@Override
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
FailureTestCasesAdvanceDTO failureTestCasesAdvanceDTO = new FailureTestCasesAdvanceDTO();
failureTestCasesAdvanceDTO.setFunctionalTestCases(functionalTestCases);
failureTestCasesAdvanceDTO.setApiTestCases(apiTestCases);
failureTestCasesAdvanceDTO.setScenarioTestCases(scenarioTestCases);
failureTestCasesAdvanceDTO.setLoadTestCases(loadTestCases);
testCaseReportMetric.setFailureTestCases(failureTestCasesAdvanceDTO);
}
}

View File

@ -16,15 +16,19 @@ public class ReportResultAdvancedChartComponent extends ReportComponent {
Map<String, TestCaseReportStatusResultDTO> functionalStatusResultMap = new HashMap<>();
Map<String, TestCaseReportStatusResultDTO> apiStatusResultMap = new HashMap<>();
Map<String, TestCaseReportStatusResultDTO> scenarioStatusResultMap = new HashMap<>();
Map<String, TestCaseReportStatusResultDTO> loadStatusResultMap = new HashMap<>();
private static Map<String, String> apiResultMap = new HashMap<>();
private static Map<String, String> scenarioResultMap = new HashMap<>();
private static Map<String, String> loadResultMap = new HashMap<>();
static {
apiResultMap.put("success", TestPlanTestCaseStatus.Pass.name());
apiResultMap.put("error", TestPlanTestCaseStatus.Failure.name());
scenarioResultMap.put(ScenarioStatus.Success.name(), TestPlanTestCaseStatus.Pass.name());
scenarioResultMap.put(ScenarioStatus.Fail.name(), TestPlanTestCaseStatus.Failure.name());
loadResultMap.put("success", TestPlanTestCaseStatus.Pass.name());
loadResultMap.put("error", TestPlanTestCaseStatus.Failure.name());
}
public ReportResultAdvancedChartComponent(TestPlanDTO testPlan) {
@ -47,6 +51,11 @@ public class ReportResultAdvancedChartComponent extends ReportComponent {
getStatusResultMap(scenarioStatusResultMap, scenarioResultMap.get(testCase.getLastResult()));
}
@Override
public void readRecord(TestPlanLoadCaseDTO testCase) {
getStatusResultMap(loadStatusResultMap, loadResultMap.get(testCase.getCaseStatus()));
}
@Override
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
testCaseReportMetric.setExecuteResult(getReportStatusResult());
@ -57,6 +66,7 @@ public class ReportResultAdvancedChartComponent extends ReportComponent {
buildFunctionalStatusResult(reportStatusResult);
buildApiStatusResult(reportStatusResult);
buildScenarioStatusResult(reportStatusResult);
buildLoadStatusResult(reportStatusResult);
return reportStatusResult;
}
@ -87,6 +97,14 @@ public class ReportResultAdvancedChartComponent extends ReportComponent {
reportStatusResult.setScenarioResult(scenarioStatusResult);
}
private void buildLoadStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) {
List<TestCaseReportStatusResultDTO> loadStatusResult = new ArrayList<>();
addToReportStatusResultList(loadStatusResultMap, loadStatusResult, TestPlanTestCaseStatus.Pass.name());
addToReportStatusResultList(loadStatusResultMap, loadStatusResult, TestPlanTestCaseStatus.Failure.name());
addToReportStatusResultList(loadStatusResultMap, loadStatusResult, TestPlanTestCaseStatus.Underway.name());
reportStatusResult.setLoadResult(loadStatusResult);
}
private void addToReportStatusResultList(Map<String, TestCaseReportStatusResultDTO> resultMap, List<TestCaseReportStatusResultDTO> reportStatusResultList, String status) {
if (resultMap.get(status) != null) {
reportStatusResultList.add(resultMap.get(status));

View File

@ -13,4 +13,5 @@ public class FailureTestCasesAdvanceDTO {
private List<TestPlanCaseDTO> functionalTestCases;
private List<TestPlanApiCaseDTO> apiTestCases;
private List<ApiScenarioDTO> scenarioTestCases;
private List<TestPlanLoadCaseDTO> loadTestCases;
}

View File

@ -11,5 +11,6 @@ public class TestCaseReportAdvanceStatusResultDTO {
private List<TestCaseReportStatusResultDTO> functionalResult;
private List<TestCaseReportStatusResultDTO> apiResult;
private List<TestCaseReportStatusResultDTO> scenarioResult;
private List<TestCaseReportStatusResultDTO> loadResult;
}

View File

@ -26,13 +26,11 @@ import io.metersphere.notice.service.NoticeSendService;
import io.metersphere.service.SystemParameterService;
import io.metersphere.track.Factory.ReportComponentFactory;
import io.metersphere.track.domain.ReportComponent;
import io.metersphere.track.dto.TestCaseReportMetricDTO;
import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.dto.TestPlanDTO;
import io.metersphere.track.dto.TestPlanDTOWithMetric;
import io.metersphere.track.dto.*;
import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.AddTestPlanRequest;
import io.metersphere.track.request.testplan.LoadCaseRequest;
import io.metersphere.track.request.testplancase.QueryTestPlanCaseRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
@ -649,6 +647,7 @@ public class TestPlanService {
List<Issues> issues = buildFunctionalCaseReport(planId, components);
buildApiCaseReport(planId, components);
buildScenarioCaseReport(planId, components);
buildLoadCaseReport(planId, components);
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
components.forEach(component -> {
@ -680,6 +679,17 @@ public class TestPlanService {
}
}
public void buildLoadCaseReport(String planId, List<ReportComponent> components) {
LoadCaseRequest request = new LoadCaseRequest();
request.setTestPlanId(planId);
List<TestPlanLoadCaseDTO> loadDTOs = testPlanLoadCaseService.list(request);
for (TestPlanLoadCaseDTO item : loadDTOs) {
for (ReportComponent component : components) {
component.readRecord(item);
}
}
}
public List<Issues> buildFunctionalCaseReport(String planId, List<ReportComponent> components) {
IssuesService issuesService = (IssuesService) CommonBeanFactory.getBean("issuesService");
List<TestPlanCaseDTO> testPlanTestCases = listTestCaseByPlanId(planId);

View File

@ -184,6 +184,7 @@ export default {
},
methods: {
initTable() {
console.log('init')
this.selectRows = new Set();
let param = {};
param.testPlanId = this.planId;
@ -198,7 +199,7 @@ export default {
},
refreshStatus() {
this.refreshScheduler = setInterval(() => {
let arr = this.tableData.filter(data => data.status !== 'Completed' && data.status !== 'Error');
let arr = this.tableData.filter(data => data.status !== 'Completed' && data.status !== 'Error' && data.status !== "Saved");
if (arr.length > 0) {
this.initTable();
} else {

View File

@ -4,6 +4,7 @@
<functional-failure-cases-list v-if="showFunctional" :functional-test-cases="failureTestCases.functionalTestCases"/>
<api-failure-cases-list v-if="showApi" :api-test-cases="failureTestCases.apiTestCases"/>
<scenario-failure-cases-list v-if="showScenario" :scenario-test-cases="failureTestCases.scenarioTestCases"/>
<load-failure-cases-list v-if="showLoad" :load-test-cases="failureTestCases.loadTestCases"/>
</common-component>
</template>
@ -18,13 +19,15 @@
import FunctionalFailureCasesList from "./component/FunctionalFailureCasesList";
import ApiFailureCasesList from "./component/ApiFailureCasesList";
import ScenarioFailureCasesList from "./component/ScenarioFailureCasesList";
import LoadFailureCasesList
from "@/business/components/track/plan/view/comonents/report/TemplateComponent/component/LoadFailureCasesList";
export default {
name: "FailureResultAdvanceComponent",
components: {
ScenarioFailureCasesList,
ApiFailureCasesList,
FunctionalFailureCasesList,
StatusTableItem, MethodTableItem, TypeTableItem, PriorityTableItem, CommonComponent},
StatusTableItem, MethodTableItem, TypeTableItem, PriorityTableItem, CommonComponent, LoadFailureCasesList},
props: {
failureTestCases: {
type: Object,
@ -73,6 +76,15 @@
lastResult: "Failure",
updateTime: new Date(),
}
],
loadTestCases: [
{
caseName: 'testCase4',
projectName: 'P3',
userName: '/module1/module2',
createTime: new Date(),
status: 'error',
}
]
}
}
@ -80,14 +92,18 @@
},
computed: {
showFunctional() {
return this.failureTestCases.functionalTestCases.length > 0 || (this.failureTestCases.apiTestCases.length <= 0 && this.failureTestCases.scenarioTestCases.length <= 0);
return this.failureTestCases.functionalTestCases.length > 0
|| (this.failureTestCases.apiTestCases.length <= 0 && this.failureTestCases.scenarioTestCases.length <= 0 && this.failureTestCases.loadTestCases.length <= 0);
},
showApi() {
return this.failureTestCases.apiTestCases.length > 0;
},
showScenario() {
return this.failureTestCases.scenarioTestCases.length > 0;
}
},
showLoad() {
return this.failureTestCases.loadTestCases.length > 0;
},
},
methods: {
goFailureTestCase(row) {

View File

@ -17,6 +17,11 @@
<ms-pie-chart v-if="isShow" :text="'场景测试用例'"
:name="$t('test_track.plan_view.test_result')" :data="scenarioCharData"/>
</div>
<div class="char-item" v-if="showLoad">
<ms-pie-chart v-if="isShow" :text="'性能测试用例'"
:name="$t('test_track.plan_view.test_result')" :data="loadCharData"/>
</div>
</div>
</common-component>
@ -43,6 +48,7 @@
functionalCharData: [],
apiCharData: [],
scenarioCharData: [],
loadCharData: [],
isShow: true
}
},
@ -69,19 +75,28 @@
{status: 'Failure', count: '350'},
{status: 'Underway', count: '110'},
],
loadResult: [
{status: 'Pass', count: '205'},
{status: 'Failure', count: '350'},
{status: 'Underway', count: '110'},
],
}
}
}
},
computed: {
showFunctional() {
return this.executeResult.functionalResult.length > 0 || (this.executeResult.apiResult.length <= 0 && this.executeResult.scenarioResult.length <= 0);
return this.executeResult.functionalResult.length > 0
|| (this.executeResult.apiResult.length <= 0 && this.executeResult.scenarioResult.length <= 0 && this.executeResult.loadResult.length <= 0);
},
showApi() {
return this.executeResult.apiResult.length > 0;
},
showScenario() {
return this.executeResult.scenarioResult.length > 0;
},
showLoad() {
return this.executeResult.loadResult.length > 0;
}
},
watch: {
@ -97,6 +112,7 @@
this.getFunctionalCharData();
this.getApiCharData();
this.getScenarioCharData();
this.getLoadCharData();
this.reload();
},
getFunctionalCharData() {
@ -129,6 +145,16 @@
});
}
},
getLoadCharData() {
this.loadCharData = [];
if (this.executeResult.loadResult) {
this.executeResult.loadResult.forEach(item => {
let data = this.dataMap.get(item.status);
data.value = item.count;
this.loadCharData.push(data);
});
}
},
reload() {
this.isShow = false;
this.$nextTick(function () {

View File

@ -0,0 +1,96 @@
<template>
<div class="failure-cases-list">
<div class="failure-cases-list-header">
性能测试用例
</div>
<el-table
row-key="id"
@row-click="goFailureTestCase"
:data="loadTestCases">
<el-table-column
prop="caseName"
:label="$t('commons.name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="projectName"
:label="$t('load_test.project_name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="userName"
:label="$t('load_test.user_name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
sortable
prop="createTime"
:label="$t('commons.create_time')">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
prop="status"
column-key="status"
:filters="statusFilters"
:label="$t('commons.status')">
<template v-slot:default="{row}">
<ms-performance-test-status :row="row"/>
</template>
</el-table-column>
<!-- <el-table-column-->
<!-- prop="caseStatus"-->
<!-- :label="$t('test_track.plan.load_case.execution_status')">-->
<!-- <template v-slot:default="{row}">-->
<!-- <el-tag size="mini" type="danger" v-if="row.caseStatus === 'error'">-->
<!-- {{ row.caseStatus }}-->
<!-- </el-tag>-->
<!-- <el-tag size="mini" type="success" v-else-if="row.caseStatus === 'success'">-->
<!-- {{ row.caseStatus }}-->
<!-- </el-tag>-->
<!-- <span v-else>-</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
</div>
</template>
<script>
import MsTag from "@/business/components/common/components/MsTag";
import PriorityTableItem from "@/business/components/track/common/tableItems/planview/PriorityTableItem";
import TypeTableItem from "@/business/components/track/common/tableItems/planview/TypeTableItem";
import MethodTableItem from "@/business/components/track/common/tableItems/planview/MethodTableItem";
import StatusTableItem from "@/business/components/track/common/tableItems/planview/StatusTableItem";
import MsPerformanceTestStatus from "@/business/components/performance/test/PerformanceTestStatus";
export default {
name: "LoadFailureCasesList",
components: {MsTag, PriorityTableItem, TypeTableItem, MethodTableItem, StatusTableItem, MsPerformanceTestStatus},
props: ['loadTestCases'],
data() {
return {
statusFilters: [
{text: 'Saved', value: 'Saved'},
{text: 'Starting', value: 'Starting'},
{text: 'Running', value: 'Running'},
{text: 'Reporting', value: 'Reporting'},
{text: 'Completed', value: 'Completed'},
{text: 'Error', value: 'Error'}
],
}
},
methods: {
goFailureTestCase(row) {
this.$emit("openFailureTestCase", row);
}
}
}
</script>
<style scoped>
</style>

View File

@ -205,11 +205,13 @@ export default {
if (this.reportId) {
this.result = this.$get("/performance/report/" + this.reportId, res => {
let data = res.data;
this.status = data.status;
this.$set(this.report, "id", this.reportId);
this.$set(this.report, "status", data.status);
if (this.status === "Completed") {
this.initReportTimeInfo();
if (data) {
this.status = data.status;
this.$set(this.report, "id", this.reportId);
this.$set(this.report, "status", data.status);
if (this.status === "Completed") {
this.initReportTimeInfo();
}
}
});
}