提交 5006919f 编写于 作者: C chenjianxing

重构测试报告

上级 200522d1
package io.metersphere.commons.utils;
import java.math.BigDecimal;
public class MathUtils {
/**
* 获取百分比
* 保留一位小数
* @param value
* @return
*/
public static double getPercentWithDecimal(double value) {
return new BigDecimal(value * 100)
.setScale(1, BigDecimal.ROUND_HALF_UP)
.doubleValue();
}
}
package io.metersphere.track.Factory;
import io.metersphere.track.domain.*;
import io.metersphere.track.dto.TestPlanDTO;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class ReportComponentFactory {
public static ReportComponent createComponent(String componentId, TestPlanDTO testPlan) {
if (StringUtils.equals("1", componentId)) {
return new ReportBaseInfoComponent(testPlan);
} else if (StringUtils.equals("2", componentId)) {
return new ReportResultComponent(testPlan);
} else if (StringUtils.equals("3", componentId)) {
return new ReportResultChartComponent(testPlan);
} else if (StringUtils.equals("4", componentId)) {
return new ReportFailureResultComponent(testPlan);
}
return null;
}
public static List<ReportComponent> createComponents(List<String> componentIds, TestPlanDTO testPlan) {
List<ReportComponent> components = new ArrayList<>();
componentIds.forEach(id -> {
ReportComponent component = createComponent(id, testPlan);
if (component != null) {
components.add(component);
}
});
return components;
}
}
package io.metersphere.track.domain;
import io.metersphere.track.dto.TestCaseReportMetricDTO;
import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.dto.TestPlanDTO;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class ReportBaseInfoComponent extends ReportComponent {
private Set<String> executorsSet = new HashSet<>();
public ReportBaseInfoComponent(TestPlanDTO testPlan) {
super(testPlan);
componentId = "1";
}
@Override
public void readRecord(TestPlanCaseDTO testCase) {
executorsSet.add(testCase.getExecutor());
}
@Override
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
testCaseReportMetric.setProjectName(testPlan.getProjectName());
testCaseReportMetric.setPrincipal(testPlan.getPrincipal());
testCaseReportMetric.setExecutors(new ArrayList<>(this.executorsSet));
}
}
package io.metersphere.track.domain;
import io.metersphere.track.dto.TestCaseReportMetricDTO;
import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.dto.TestPlanDTO;
public abstract class ReportComponent {
protected String componentId;
protected TestPlanDTO testPlan;
public ReportComponent(TestPlanDTO testPlan) {
this.testPlan = testPlan;
}
public abstract void readRecord(TestPlanCaseDTO testCase);
public abstract void afterBuild(TestCaseReportMetricDTO testCaseReportMetric);
}
package io.metersphere.track.domain;
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.track.dto.TestCaseReportMetricDTO;
import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.dto.TestPlanDTO;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class ReportFailureResultComponent extends ReportComponent {
private List<TestPlanCaseDTO> failureTestCases = new ArrayList<>();
public ReportFailureResultComponent(TestPlanDTO testPlan) {
super(testPlan);
componentId = "4";
}
@Override
public void readRecord(TestPlanCaseDTO testCase) {
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Failure.name())) {
this.failureTestCases.add(testCase);
}
}
@Override
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
testCaseReportMetric.setFailureTestCases(failureTestCases);
}
}
package io.metersphere.track.domain;
import io.metersphere.track.dto.TestCaseReportMetricDTO;
import io.metersphere.track.dto.TestCaseReportStatusResultDTO;
import io.metersphere.track.dto.TestPlanCaseDTO;
import io.metersphere.track.dto.TestPlanDTO;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ReportResultChartComponent extends ReportComponent {
Map<String, TestCaseReportStatusResultDTO> reportStatusResultMap = new HashMap<>();
public ReportResultChartComponent(TestPlanDTO testPlan) {
super(testPlan);
componentId = "3";
}
@Override
public void readRecord(TestPlanCaseDTO testCase) {
getStatusResultMap(reportStatusResultMap, testCase);
}
@Override
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
testCaseReportMetric.setExecuteResult(new ArrayList<>(reportStatusResultMap.values()));
}
private void getStatusResultMap(Map<String, TestCaseReportStatusResultDTO> reportStatusResultMap, TestPlanCaseDTO testCase) {
TestCaseReportStatusResultDTO statusResult = reportStatusResultMap.get(testCase.getStatus());
if (statusResult == null) {
statusResult = new TestCaseReportStatusResultDTO();
statusResult.setStatus(testCase.getStatus());
statusResult.setCount(0);
}
statusResult.setCount(statusResult.getCount() + 1);
reportStatusResultMap.put(testCase.getStatus(), statusResult);
}
}
package io.metersphere.track.domain;
import com.alibaba.fastjson.JSON;
import io.metersphere.base.domain.TestCaseNode;
import io.metersphere.base.domain.TestCaseNodeExample;
import io.metersphere.base.mapper.TestCaseNodeMapper;
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.MathUtils;
import io.metersphere.track.dto.*;
import io.metersphere.track.service.TestCaseNodeService;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
public class ReportResultComponent extends ReportComponent {
private List<TestCaseNodeDTO> nodeTrees = new ArrayList<>();
private Map<String, Set<String>> childIdMap = new HashMap<>();
private Map<String, TestCaseReportModuleResultDTO> moduleResultMap = new HashMap<>();
public ReportResultComponent(TestPlanDTO testPlan) {
super(testPlan);
componentId = "2";
init();
}
public void init() {
TestCaseNodeService testCaseNodeService = (TestCaseNodeService) CommonBeanFactory.getBean("testCaseNodeService");
TestCaseNodeMapper testCaseNodeMapper = (TestCaseNodeMapper) CommonBeanFactory.getBean("testCaseNodeMapper");
TestCaseNodeExample testCaseNodeExample = new TestCaseNodeExample();
testCaseNodeExample.createCriteria().andProjectIdEqualTo(testPlan.getProjectId());
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(testCaseNodeExample);
nodeTrees = testCaseNodeService.getNodeTrees(nodes);
nodeTrees.forEach(item -> {
Set<String> childIds = new HashSet<>();
getChildIds(item, childIds);
childIdMap.put(item.getId(), childIds);
});
}
@Override
public void readRecord(TestPlanCaseDTO testCase) {
getModuleResultMap(childIdMap, moduleResultMap, testCase, nodeTrees);
}
@Override
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
nodeTrees.forEach(rootNode -> {
TestCaseReportModuleResultDTO moduleResult = moduleResultMap.get(rootNode.getId());
if (moduleResult != null) {
moduleResult.setModuleName(rootNode.getName());
}
});
for (TestCaseReportModuleResultDTO moduleResult : moduleResultMap.values()) {
moduleResult.setPassRate(MathUtils.getPercentWithDecimal(moduleResult.getPassCount()*1.0f/moduleResult.getCaseCount()));
if (moduleResult.getCaseCount() <= 0) {
moduleResultMap.remove(moduleResult.getModuleId());
}
}
testCaseReportMetric.setModuleExecuteResult(new ArrayList<>(moduleResultMap.values()));
}
private void getChildIds(TestCaseNodeDTO rootNode, Set<String> childIds) {
childIds.add(rootNode.getId());
List<TestCaseNodeDTO> children = rootNode.getChildren();
if(children != null) {
Iterator<TestCaseNodeDTO> iterator = children.iterator();
while(iterator.hasNext()){
getChildIds(iterator.next(), childIds);
}
}
}
private void getModuleResultMap(Map<String, Set<String>> childIdMap, Map<String, TestCaseReportModuleResultDTO> moduleResultMap, TestPlanCaseDTO testCase, List<TestCaseNodeDTO> nodeTrees) {
childIdMap.forEach((rootNodeId, childIds) -> {
if (childIds.contains(testCase.getNodeId())) {
TestCaseReportModuleResultDTO moduleResult = moduleResultMap.get(rootNodeId);
if (moduleResult == null) {
moduleResult = new TestCaseReportModuleResultDTO();
moduleResult.setCaseCount(0);
moduleResult.setPassCount(0);
moduleResult.setIssuesCount(0);
moduleResult.setModuleId(rootNodeId);
}
moduleResult.setCaseCount(moduleResult.getCaseCount() + 1);
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Pass.name())) {
moduleResult.setPassCount(moduleResult.getPassCount() + 1);
}
if (StringUtils.isNotBlank(testCase.getIssues())) {
if (JSON.parseObject(testCase.getIssues()).getBoolean("hasIssues")) {
moduleResult.setIssuesCount(moduleResult.getIssuesCount() + 1);
};
}
moduleResultMap.put(rootNodeId, moduleResult);
return;
}
});
}
}
package io.metersphere.track.dto;
import io.metersphere.track.domain.ReportBaseInfoComponent;
import io.metersphere.track.domain.ReportFailureResultComponent;
import io.metersphere.track.domain.ReportResultChartComponent;
import io.metersphere.track.domain.ReportResultComponent;
import lombok.Getter;
import lombok.Setter;
......
......@@ -2,6 +2,8 @@ package io.metersphere.track.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtProjectMapper;
......@@ -11,10 +13,14 @@ import io.metersphere.commons.constants.TestPlanStatus;
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.user.SessionUser;
import io.metersphere.commons.utils.MathUtils;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.ProjectRequest;
import io.metersphere.controller.request.member.QueryMemberRequest;
import io.metersphere.dto.ProjectDTO;
import io.metersphere.track.Factory.ReportComponentFactory;
import io.metersphere.track.domain.ReportComponent;
import io.metersphere.track.dto.*;
import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
......@@ -24,6 +30,7 @@ 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.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -55,11 +62,9 @@ public class TestPlanService {
@Resource
SqlSessionFactory sqlSessionFactory;
@Lazy
@Resource
TestCaseNodeMapper testCaseNodeMapper;
@Resource
TestCaseNodeService testCaseNodeService;
TestPlanTestCaseService testPlanTestCaseService;
@Resource
ExtProjectMapper extProjectMapper;
......@@ -226,23 +231,17 @@ public class TestPlanService {
}
});
}
testPlan.setPassRate(getPercentWithTwoDecimals(testPlan.getTested() == 0 ? 0 : testPlan.getPassed()*1.0/testPlan.getTested()));
testPlan.setTestRate(getPercentWithTwoDecimals(testPlan.getTotal() == 0 ? 0 : testPlan.getTested()*1.0/testPlan.getTotal()));
testPlan.setPassRate(MathUtils.getPercentWithDecimal(testPlan.getTested() == 0 ? 0 : testPlan.getPassed()*1.0/testPlan.getTested()));
testPlan.setTestRate(MathUtils.getPercentWithDecimal(testPlan.getTotal() == 0 ? 0 : testPlan.getTested()*1.0/testPlan.getTotal()));
});
return testPlans;
}
private double getPercentWithTwoDecimals(double value) {
return new BigDecimal(value * 100)
.setScale(1, BigDecimal.ROUND_HALF_UP)
.doubleValue();
}
public List<TestPlanCaseDTO> listTestCaseByPlanId(String planId) {
QueryTestPlanCaseRequest request = new QueryTestPlanCaseRequest();
request.setPlanId(planId);
return extTestPlanTestCaseMapper.list(request);
return testPlanTestCaseService.list(request);
}
public List<TestPlanCaseDTO> listTestCaseByProjectIds(List<String> projectIds) {
......@@ -255,118 +254,26 @@ public class TestPlanService {
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
queryTestPlanRequest.setId(planId);
TestPlanDTO testPlan = extTestPlanMapper.list(queryTestPlanRequest).get(0);
TestCaseReport testCaseReport = testCaseReportMapper.selectByPrimaryKey(testPlan.getReportId());
// testCaseReport.get
Set<String> executors = new HashSet<>();
Map<String, TestCaseReportStatusResultDTO> reportStatusResultMap = new HashMap<>();
TestCaseNodeExample testCaseNodeExample = new TestCaseNodeExample();
testCaseNodeExample.createCriteria().andProjectIdEqualTo(testPlan.getProjectId());
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(testCaseNodeExample);
JSONObject content = JSONObject.parseObject(testCaseReport.getContent());
JSONArray componentIds = content.getJSONArray("components");
List<TestCaseNodeDTO> nodeTrees = testCaseNodeService.getNodeTrees(nodes);
Map<String, Set<String>> childIdMap = new HashMap<>();
nodeTrees.forEach(item -> {
Set<String> childIds = new HashSet<>();
getChildIds(item, childIds);
childIdMap.put(item.getId(), childIds);
});
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
List<TestPlanCaseDTO> testPlanTestCases = listTestCaseByPlanId(planId);
List<TestPlanCaseDTO> failureTestCases = new ArrayList<>();
Map<String, TestCaseReportModuleResultDTO> moduleResultMap = new HashMap<>();
for (TestPlanCaseDTO testCase: testPlanTestCases) {
executors.add(testCase.getExecutor());
getStatusResultMap(reportStatusResultMap, testCase);
getModuleResultMap(childIdMap, moduleResultMap, testCase, nodeTrees);
getFailureTestCases(failureTestCases, testCase);
}
nodeTrees.forEach(rootNode -> {
TestCaseReportModuleResultDTO moduleResult = moduleResultMap.get(rootNode.getId());
if (moduleResult != null) {
moduleResult.setModuleName(rootNode.getName());
}
});
for (TestCaseReportModuleResultDTO moduleResult : moduleResultMap.values()) {
moduleResult.setPassRate(getPercentWithTwoDecimals(moduleResult.getPassCount()*1.0f/moduleResult.getCaseCount()));
if (moduleResult.getCaseCount() <= 0) {
moduleResultMap.remove(moduleResult.getModuleId());
}
components.forEach(component -> {
component.readRecord(testCase);
});
}
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
testCaseReportMetricDTO.setProjectName(testPlan.getProjectName());
testCaseReportMetricDTO.setPrincipal(testPlan.getPrincipal());
testCaseReportMetricDTO.setExecutors(new ArrayList<>(executors));
testCaseReportMetricDTO.setExecuteResult(new ArrayList<>(reportStatusResultMap.values()));
testCaseReportMetricDTO.setModuleExecuteResult(new ArrayList<>(moduleResultMap.values()));
testCaseReportMetricDTO.setFailureTestCases(failureTestCases);
return testCaseReportMetricDTO;
}
private void getFailureTestCases(List<TestPlanCaseDTO> failureTestCases, TestPlanCaseDTO testCase) {
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Failure.name())) {
failureTestCases.add(testCase);
}
}
private void getStatusResultMap(Map<String, TestCaseReportStatusResultDTO> reportStatusResultMap, TestPlanCaseDTO testCase) {
TestCaseReportStatusResultDTO statusResult = reportStatusResultMap.get(testCase.getStatus());
if (statusResult == null) {
statusResult = new TestCaseReportStatusResultDTO();
statusResult.setStatus(testCase.getStatus());
statusResult.setCount(0);
}
statusResult.setCount(statusResult.getCount() + 1);
reportStatusResultMap.put(testCase.getStatus(), statusResult);
}
private void getModuleResultMap(Map<String, Set<String>> childIdMap, Map<String, TestCaseReportModuleResultDTO> moduleResultMap, TestPlanCaseDTO testCase, List<TestCaseNodeDTO> nodeTrees) {
childIdMap.forEach((rootNodeId, childIds) -> {
if (childIds.contains(testCase.getNodeId())) {
TestCaseReportModuleResultDTO moduleResult = moduleResultMap.get(rootNodeId);
if (moduleResult == null) {
moduleResult = new TestCaseReportModuleResultDTO();
moduleResult.setCaseCount(0);
moduleResult.setPassCount(0);
moduleResult.setIssuesCount(0);
moduleResult.setModuleId(rootNodeId);
}
moduleResult.setCaseCount(moduleResult.getCaseCount() + 1);
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Pass.name())) {
moduleResult.setPassCount(moduleResult.getPassCount() + 1);
}
if (StringUtils.isNotBlank(testCase.getIssues())) {
if (JSON.parseObject(testCase.getIssues()).getBoolean("hasIssues")) {
moduleResult.setIssuesCount(moduleResult.getIssuesCount() + 1);
};
}
moduleResultMap.put(rootNodeId, moduleResult);
return;
}
components.forEach(component -> {
component.afterBuild(testCaseReportMetricDTO);
});
}
private void getChildIds(TestCaseNodeDTO rootNode, Set<String> childIds) {
childIds.add(rootNode.getId());
List<TestCaseNodeDTO> children = rootNode.getChildren();
if(children != null) {
Iterator<TestCaseNodeDTO> iterator = children.iterator();
while(iterator.hasNext()){
getChildIds(iterator.next(), childIds);
}
}
return testCaseReportMetricDTO;
}
public List<TestPlan> getTestPlanByIds(List<String> planIds) {
......
......@@ -60,7 +60,6 @@
</el-table-column>
<el-table-column
sortable
prop="updateTime"
:label="$t('commons.update_time')"
show-overflow-tooltip>
......@@ -90,22 +89,24 @@
default() {
return [
{
moduleName: this.$t('test_track.module.module') + '1',
caseCount: '14',
passRate: 10.8,
issuesCount: 3
name: 'testCase1',
priority: 'P1',
type: 'api',
method: 'auto',
nodePath: '/module1/module2',
executorName: "Tom",
status: "Failure",
updateTime: new Date(),
},
{
moduleName: this.$t('test_track.module.module') + '2',
caseCount: '24',
passRate: 40,
issuesCount: 6
},
{
moduleName: this.$t('test_track.module.module') + '3',
caseCount: '50',
passRate: 76.9,
issuesCount: 8
name: 'testCase2',
priority: 'P0',
type: 'functional',
method: 'manual',
nodePath: '/module1',
executorName: "Micheal",
status: "Failure",
updateTime: new Date(),
}
]
}
......
......@@ -6,8 +6,8 @@
<base-info-component :is-report="false" v-if="preview.id == 1"/>
<test-result-component v-if="preview.id == 2"/>
<test-result-chart-component v-if="preview.id == 3"/>
<failure-result-component v-if="preview.id == 4"/>
<rich-text-component :preview="preview" v-if="preview.type != 'system'"/>
<failure-result-component/>
</div>
<!--报告-->
......@@ -15,8 +15,8 @@
<base-info-component :report-info="metric" v-if="preview.id == 1"/>
<test-result-component :test-results="metric.moduleExecuteResult" v-if="preview.id == 2"/>
<test-result-chart-component :execute-result="metric.executeResult" v-if="preview.id == 3"/>
<failure-result-component :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>
<rich-text-component :is-report-view="isReportView" :preview="preview" v-if="preview.type != 'system'"/>
<failure-result-component :failure-test-cases="metric.failureTestCases"/>
</div>
</div>
......
......@@ -76,10 +76,11 @@
[1, { name: this.$t('test_track.plan_view.base_info'), id: 1 , type: 'system'}],
[2, { name: this.$t('test_track.plan_view.test_result'), id: 2 , type: 'system'}],
[3, { name: this.$t('test_track.plan_view.result_distribution'), id: 3 ,type: 'system'}],
[4, { name: this.$t('test_track.plan_view.custom_component'), id: 4 ,type: 'custom'}]
[4, { name: '失败用例', id: 4 ,type: 'system'}],
[5, { name: this.$t('test_track.plan_view.custom_component'), id: 5 ,type: 'custom'}]
]
),
components: [4],
components: [5],
previews: [],
template: {},
isReport: false
......@@ -107,13 +108,13 @@
}
this.template = {
name: '',
content: {
components: [1,2,3,4],
customComponent: new Map()
content: {
components: [1,2,3,4,5],
customComponent: new Map()
}
};
this.previews = [];
this.components = [4];
this.components = [5];
if (id) {
this.type = 'edit';
this.getTemplateById(id);
......
......@@ -68,7 +68,8 @@
[1, { name: this.$t('test_track.plan_view.base_info'), id: 1 , type: 'system'}],
[2, { name: this.$t('test_track.plan_view.test_result'), id: 2 , type: 'system'}],
[3, { name: this.$t('test_track.plan_view.result_distribution'), id: 3 ,type: 'system'}],
[4, { name: this.$t('test_track.plan_view.custom_component'), id: 4 ,type: 'custom'}]
[4, { name: '失败用例', id: 4 ,type: 'system'}],
[5, { name: this.$t('test_track.plan_view.custom_component'), id: 5 ,type: 'custom'}]
]
),
isTestManagerOrTestUser: false
......@@ -165,6 +166,15 @@
getMetric() {
this.result = this.$get('/test/plan/get/metric/' + this.planId, response => {
this.metric = response.data;
if (!this.metric.failureTestCases) {
this.metric.failureTestCases = [];
}
if (!this.metric.executeResult) {
this.metric.executeResult = [];
}
if (!this.metric.moduleExecuteResult) {
this.metric.moduleExecuteResult = [];
}
if (this.report.startTime) {
this.metric.startTime = new Date(this.report.startTime);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册