mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-11-30 11:08:38 +08:00
Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
cb6b5844e9
@ -15,9 +15,11 @@ public class ReportComponentFactory {
|
|||||||
} else if (StringUtils.equals("2", componentId)) {
|
} else if (StringUtils.equals("2", componentId)) {
|
||||||
return new ReportResultComponent(testPlan);
|
return new ReportResultComponent(testPlan);
|
||||||
} else if (StringUtils.equals("3", componentId)) {
|
} else if (StringUtils.equals("3", componentId)) {
|
||||||
return new ReportResultChartComponent(testPlan);
|
return new ReportResultAdvancedChartComponent(testPlan);
|
||||||
|
// return new ReportResultChartComponent(testPlan);
|
||||||
} else if (StringUtils.equals("4", componentId)) {
|
} else if (StringUtils.equals("4", componentId)) {
|
||||||
return new ReportFailureResultComponent(testPlan);
|
// return new ReportFailureResultComponent(testPlan);
|
||||||
|
return new ReportFailureAdvanceResultComponent(testPlan);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,11 @@ public class TestPlanController {
|
|||||||
return testPlanService.getMetric(planId);
|
return testPlanService.getMetric(planId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get/statistics/metric/{planId}")
|
||||||
|
public TestCaseReportMetricDTO getStatisticsMetric(@PathVariable String planId) {
|
||||||
|
return testPlanService.getStatisticsMetric(planId);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/project/name/{planId}")
|
@GetMapping("/project/name/{planId}")
|
||||||
public String getProjectNameByPlanId(@PathVariable String planId) {
|
public String getProjectNameByPlanId(@PathVariable String planId) {
|
||||||
return testPlanService.getProjectNameByPlanId(planId);
|
return testPlanService.getProjectNameByPlanId(planId);
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package io.metersphere.track.domain;
|
package io.metersphere.track.domain;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||||
|
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||||
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
||||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||||
import io.metersphere.track.dto.TestPlanDTO;
|
import io.metersphere.track.dto.TestPlanDTO;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
public abstract class ReportComponent {
|
public abstract class ReportComponent {
|
||||||
protected String componentId;
|
protected String componentId;
|
||||||
@ -15,4 +19,11 @@ public abstract class ReportComponent {
|
|||||||
public abstract void readRecord(TestPlanCaseDTO testCase);
|
public abstract void readRecord(TestPlanCaseDTO testCase);
|
||||||
|
|
||||||
public abstract void afterBuild(TestCaseReportMetricDTO testCaseReportMetric);
|
public abstract void afterBuild(TestCaseReportMetricDTO testCaseReportMetric);
|
||||||
|
|
||||||
|
public void readRecord(TestPlanApiCaseDTO testCase) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readRecord(ApiScenarioDTO testCase) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package io.metersphere.track.domain;
|
||||||
|
|
||||||
|
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 org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ReportFailureAdvanceResultComponent extends ReportComponent {
|
||||||
|
private List<TestPlanCaseDTO> functionalTestCases = new ArrayList<>();
|
||||||
|
private List<TestPlanApiCaseDTO> apiTestCases = new ArrayList<>();
|
||||||
|
private List<ApiScenarioDTO> scenarioTestCases = new ArrayList<>();
|
||||||
|
|
||||||
|
public ReportFailureAdvanceResultComponent(TestPlanDTO testPlan) {
|
||||||
|
super(testPlan);
|
||||||
|
componentId = "4";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readRecord(TestPlanCaseDTO testCase) {
|
||||||
|
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Failure.name())) {
|
||||||
|
this.functionalTestCases.add(testCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readRecord(TestPlanApiCaseDTO testCase) {
|
||||||
|
if (StringUtils.equals(testCase.getExecResult(), "error")) {
|
||||||
|
this.apiTestCases.add(testCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readRecord(ApiScenarioDTO testCase) {
|
||||||
|
if (StringUtils.equals(testCase.getLastResult(), ScenarioStatus.Fail.name())) {
|
||||||
|
this.scenarioTestCases.add(testCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||||
|
FailureTestCasesAdvanceDTO failureTestCasesAdvanceDTO = new FailureTestCasesAdvanceDTO();
|
||||||
|
failureTestCasesAdvanceDTO.setFunctionalTestCases(functionalTestCases);
|
||||||
|
failureTestCasesAdvanceDTO.setApiTestCases(apiTestCases);
|
||||||
|
failureTestCasesAdvanceDTO.setScenarioTestCases(scenarioTestCases);
|
||||||
|
testCaseReportMetric.setFailureTestCases(failureTestCasesAdvanceDTO);
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,6 @@ public class ReportFailureResultComponent extends ReportComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||||
testCaseReportMetric.setFailureTestCases(failureTestCases);
|
// testCaseReportMetric.setFailureTestCases(failureTestCases);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
package io.metersphere.track.domain;
|
||||||
|
|
||||||
|
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.*;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ReportResultAdvancedChartComponent extends ReportComponent {
|
||||||
|
Map<String, TestCaseReportStatusResultDTO> functionalStatusResultMap = new HashMap<>();
|
||||||
|
Map<String, TestCaseReportStatusResultDTO> apiStatusResultMap = new HashMap<>();
|
||||||
|
Map<String, TestCaseReportStatusResultDTO> scenarioStatusResultMap = new HashMap<>();
|
||||||
|
|
||||||
|
private static Map<String, String> apiResultMap = new HashMap<>();
|
||||||
|
private static Map<String, String> scenarioResultMap = 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReportResultAdvancedChartComponent(TestPlanDTO testPlan) {
|
||||||
|
super(testPlan);
|
||||||
|
componentId = "3";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readRecord(TestPlanCaseDTO testCase) {
|
||||||
|
getStatusResultMap(functionalStatusResultMap, testCase.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readRecord(TestPlanApiCaseDTO testCase) {
|
||||||
|
getStatusResultMap(apiStatusResultMap, apiResultMap.get(testCase.getExecResult()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readRecord(ApiScenarioDTO testCase) {
|
||||||
|
getStatusResultMap(scenarioStatusResultMap, scenarioResultMap.get(testCase.getLastResult()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||||
|
testCaseReportMetric.setExecuteResult(getReportStatusResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
private TestCaseReportAdvanceStatusResultDTO getReportStatusResult() {
|
||||||
|
TestCaseReportAdvanceStatusResultDTO reportStatusResult = new TestCaseReportAdvanceStatusResultDTO();
|
||||||
|
buildFunctionalStatusResult(reportStatusResult);
|
||||||
|
buildApiStatusResult(reportStatusResult);
|
||||||
|
buildScenarioStatusResult(reportStatusResult);
|
||||||
|
return reportStatusResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildFunctionalStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) {
|
||||||
|
List<TestCaseReportStatusResultDTO> functionalStatusResult = new ArrayList<>();
|
||||||
|
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Pass.name());
|
||||||
|
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Failure.name());
|
||||||
|
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Blocking.name());
|
||||||
|
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Skip.name());
|
||||||
|
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Underway.name());
|
||||||
|
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Prepare.name());
|
||||||
|
reportStatusResult.setFunctionalResult(functionalStatusResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildApiStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) {
|
||||||
|
List<TestCaseReportStatusResultDTO> apiStatusResult = new ArrayList<>();
|
||||||
|
addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Pass.name());
|
||||||
|
addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Failure.name());
|
||||||
|
addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Underway.name());
|
||||||
|
reportStatusResult.setApiResult(apiStatusResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildScenarioStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) {
|
||||||
|
List<TestCaseReportStatusResultDTO> scenarioStatusResult = new ArrayList<>();
|
||||||
|
addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Pass.name());
|
||||||
|
addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Failure.name());
|
||||||
|
addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Underway.name());
|
||||||
|
reportStatusResult.setScenarioResult(scenarioStatusResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToReportStatusResultList(Map<String, TestCaseReportStatusResultDTO> resultMap, List<TestCaseReportStatusResultDTO> reportStatusResultList, String status) {
|
||||||
|
if (resultMap.get(status) != null) {
|
||||||
|
reportStatusResultList.add(resultMap.get(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getStatusResultMap(Map<String, TestCaseReportStatusResultDTO> reportStatusResultMap, String result) {
|
||||||
|
if (StringUtils.isBlank(result)) {
|
||||||
|
result = TestPlanTestCaseStatus.Underway.name();
|
||||||
|
}
|
||||||
|
TestCaseReportStatusResultDTO statusResult = reportStatusResultMap.get(result);
|
||||||
|
if (statusResult == null) {
|
||||||
|
statusResult = new TestCaseReportStatusResultDTO();
|
||||||
|
statusResult.setStatus(result);
|
||||||
|
statusResult.setCount(0);
|
||||||
|
}
|
||||||
|
statusResult.setCount(statusResult.getCount() + 1);
|
||||||
|
reportStatusResultMap.put(result, statusResult);
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,7 @@ public class ReportResultChartComponent extends ReportComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||||
testCaseReportMetric.setExecuteResult(getReportStatusResult());
|
// testCaseReportMetric.setExecuteResult(getReportStatusResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TestCaseReportStatusResultDTO> getReportStatusResult() {
|
private List<TestCaseReportStatusResultDTO> getReportStatusResult() {
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.metersphere.track.dto;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||||
|
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class FailureTestCasesAdvanceDTO {
|
||||||
|
private List<TestPlanCaseDTO> functionalTestCases;
|
||||||
|
private List<TestPlanApiCaseDTO> apiTestCases;
|
||||||
|
private List<ApiScenarioDTO> scenarioTestCases;
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package io.metersphere.track.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TestCaseReportAdvanceStatusResultDTO {
|
||||||
|
private List<TestCaseReportStatusResultDTO> functionalResult;
|
||||||
|
private List<TestCaseReportStatusResultDTO> apiResult;
|
||||||
|
private List<TestCaseReportStatusResultDTO> scenarioResult;
|
||||||
|
}
|
||||||
|
|
@ -10,9 +10,11 @@ import java.util.List;
|
|||||||
@Setter
|
@Setter
|
||||||
public class TestCaseReportMetricDTO {
|
public class TestCaseReportMetricDTO {
|
||||||
|
|
||||||
private List<TestCaseReportStatusResultDTO> executeResult;
|
// private List<TestCaseReportStatusResultDTO> executeResult;
|
||||||
|
private TestCaseReportAdvanceStatusResultDTO executeResult;
|
||||||
private List<TestCaseReportModuleResultDTO> moduleExecuteResult;
|
private List<TestCaseReportModuleResultDTO> moduleExecuteResult;
|
||||||
private List<TestPlanCaseDTO> failureTestCases;
|
private FailureTestCasesAdvanceDTO failureTestCases;
|
||||||
|
// private List<TestPlanCaseDTO> failureTestCases;
|
||||||
private List<Issues> Issues;
|
private List<Issues> Issues;
|
||||||
private List<String> executors;
|
private List<String> executors;
|
||||||
private String principal;
|
private String principal;
|
||||||
|
@ -3,6 +3,10 @@ package io.metersphere.track.service;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||||
|
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
|
||||||
|
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||||
|
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.*;
|
import io.metersphere.base.mapper.*;
|
||||||
import io.metersphere.base.mapper.ext.ExtProjectMapper;
|
import io.metersphere.base.mapper.ext.ExtProjectMapper;
|
||||||
@ -22,6 +26,7 @@ import io.metersphere.notice.service.NoticeSendService;
|
|||||||
import io.metersphere.service.SystemParameterService;
|
import io.metersphere.service.SystemParameterService;
|
||||||
import io.metersphere.track.Factory.ReportComponentFactory;
|
import io.metersphere.track.Factory.ReportComponentFactory;
|
||||||
import io.metersphere.track.domain.ReportComponent;
|
import io.metersphere.track.domain.ReportComponent;
|
||||||
|
|
||||||
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
||||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||||
import io.metersphere.track.dto.TestPlanDTO;
|
import io.metersphere.track.dto.TestPlanDTO;
|
||||||
@ -80,6 +85,10 @@ public class TestPlanService {
|
|||||||
private NoticeSendService noticeSendService;
|
private NoticeSendService noticeSendService;
|
||||||
@Resource
|
@Resource
|
||||||
private SystemParameterService systemParameterService;
|
private SystemParameterService systemParameterService;
|
||||||
|
@Resource
|
||||||
|
private TestPlanApiCaseService testPlanApiCaseService;
|
||||||
|
@Resource
|
||||||
|
private TestPlanScenarioCaseService testPlanScenarioCaseService;
|
||||||
|
|
||||||
public synchronized void addTestPlan(AddTestPlanRequest testPlan) {
|
public synchronized void addTestPlan(AddTestPlanRequest testPlan) {
|
||||||
if (getTestPlanByName(testPlan.getName()).size() > 0) {
|
if (getTestPlanByName(testPlan.getName()).size() > 0) {
|
||||||
@ -459,7 +468,6 @@ public class TestPlanService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TestCaseReportMetricDTO getMetric(String planId) {
|
public TestCaseReportMetricDTO getMetric(String planId) {
|
||||||
IssuesService issuesService = (IssuesService) CommonBeanFactory.getBean("issuesService");
|
|
||||||
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
|
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
|
||||||
queryTestPlanRequest.setId(planId);
|
queryTestPlanRequest.setId(planId);
|
||||||
|
|
||||||
@ -472,31 +480,8 @@ public class TestPlanService {
|
|||||||
JSONArray componentIds = content.getJSONArray("components");
|
JSONArray componentIds = content.getJSONArray("components");
|
||||||
|
|
||||||
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
|
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
|
||||||
|
List<Issues> issues = buildFunctionalCaseReport(planId, components);
|
||||||
|
|
||||||
List<TestPlanCaseDTO> testPlanTestCases = listTestCaseByPlanId(planId);
|
|
||||||
List<Issues> issues = new ArrayList<>();
|
|
||||||
for (TestPlanCaseDTO testCase : testPlanTestCases) {
|
|
||||||
List<Issues> issue = issuesService.getIssues(testCase.getCaseId());
|
|
||||||
if (issue.size() > 0) {
|
|
||||||
for (Issues i : issue) {
|
|
||||||
i.setModel(testCase.getNodePath());
|
|
||||||
i.setProjectName(testCase.getProjectName());
|
|
||||||
String des = i.getDescription().replaceAll("<p>", "").replaceAll("</p>", "");
|
|
||||||
i.setDescription(des);
|
|
||||||
if (i.getLastmodify() == null || i.getLastmodify() == "") {
|
|
||||||
if (i.getReporter() != null || i.getReporter() != "") {
|
|
||||||
i.setLastmodify(i.getReporter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
issues.addAll(issue);
|
|
||||||
Collections.sort(issues, Comparator.comparing(Issues::getCreateTime, (t1, t2) -> t2.compareTo(t1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
components.forEach(component -> {
|
|
||||||
component.readRecord(testCase);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
|
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
|
||||||
components.forEach(component -> {
|
components.forEach(component -> {
|
||||||
component.afterBuild(testCaseReportMetricDTO);
|
component.afterBuild(testCaseReportMetricDTO);
|
||||||
@ -609,4 +594,78 @@ public class TestPlanService {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TestCaseReportMetricDTO getStatisticsMetric(String planId) {
|
||||||
|
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
|
||||||
|
queryTestPlanRequest.setId(planId);
|
||||||
|
|
||||||
|
TestPlanDTO testPlan = extTestPlanMapper.list(queryTestPlanRequest).get(0);
|
||||||
|
String projectName = getProjectNameByPlanId(planId);
|
||||||
|
testPlan.setProjectName(projectName);
|
||||||
|
|
||||||
|
TestCaseReport testCaseReport = testCaseReportMapper.selectByPrimaryKey(testPlan.getReportId());
|
||||||
|
JSONObject content = JSONObject.parseObject(testCaseReport.getContent());
|
||||||
|
JSONArray componentIds = content.getJSONArray("components");
|
||||||
|
|
||||||
|
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
|
||||||
|
List<Issues> issues = buildFunctionalCaseReport(planId, components);
|
||||||
|
buildApiCaseReport(planId, components);
|
||||||
|
buildScenarioCaseReport(planId, components);
|
||||||
|
|
||||||
|
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
|
||||||
|
components.forEach(component -> {
|
||||||
|
component.afterBuild(testCaseReportMetricDTO);
|
||||||
|
});
|
||||||
|
testCaseReportMetricDTO.setIssues(issues);
|
||||||
|
return testCaseReportMetricDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buildApiCaseReport(String planId, List<ReportComponent> components) {
|
||||||
|
ApiTestCaseRequest request = new ApiTestCaseRequest();
|
||||||
|
request.setPlanId(planId);
|
||||||
|
List<TestPlanApiCaseDTO> apiCaseDTOS = testPlanApiCaseService.list(request);
|
||||||
|
for (TestPlanApiCaseDTO item : apiCaseDTOS) {
|
||||||
|
for (ReportComponent component : components) {
|
||||||
|
component.readRecord(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buildScenarioCaseReport(String planId, List<ReportComponent> components) {
|
||||||
|
TestPlanScenarioRequest request = new TestPlanScenarioRequest();
|
||||||
|
request.setPlanId(planId);
|
||||||
|
List<ApiScenarioDTO> scenarioDTOS = testPlanScenarioCaseService.list(request);
|
||||||
|
for (ApiScenarioDTO item : scenarioDTOS) {
|
||||||
|
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);
|
||||||
|
List<Issues> issues = new ArrayList<>();
|
||||||
|
for (TestPlanCaseDTO testCase : testPlanTestCases) {
|
||||||
|
List<Issues> issue = issuesService.getIssues(testCase.getCaseId());
|
||||||
|
if (issue.size() > 0) {
|
||||||
|
for (Issues i : issue) {
|
||||||
|
i.setModel(testCase.getNodePath());
|
||||||
|
i.setProjectName(testCase.getProjectName());
|
||||||
|
String des = i.getDescription().replaceAll("<p>", "").replaceAll("</p>", "");
|
||||||
|
i.setDescription(des);
|
||||||
|
if (i.getLastmodify() == null || i.getLastmodify() == "") {
|
||||||
|
if (i.getReporter() != null || i.getReporter() != "") {
|
||||||
|
i.setLastmodify(i.getReporter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
issues.addAll(issue);
|
||||||
|
Collections.sort(issues, Comparator.comparing(Issues::getCreateTime, (t1, t2) -> t2.compareTo(t1)));
|
||||||
|
}
|
||||||
|
components.forEach(component -> {
|
||||||
|
component.readRecord(testCase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return issues;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,13 @@
|
|||||||
class="el-menu-demo header-menu" mode="horizontal" @select="handleSelect">
|
class="el-menu-demo header-menu" mode="horizontal" @select="handleSelect">
|
||||||
<el-menu-item index="functional">功能测试用例</el-menu-item>
|
<el-menu-item index="functional">功能测试用例</el-menu-item>
|
||||||
<el-menu-item index="api">接口测试用例</el-menu-item>
|
<el-menu-item index="api">接口测试用例</el-menu-item>
|
||||||
|
<el-menu-item index="report">报告统计</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</template>
|
</template>
|
||||||
</ms-test-plan-header-bar>
|
</ms-test-plan-header-bar>
|
||||||
<test-plan-functional v-if="activeIndex === 'functional'" :plan-id="planId"/>
|
<test-plan-functional v-if="activeIndex === 'functional'" :plan-id="planId"/>
|
||||||
<test-plan-api v-if="activeIndex === 'api'" :plan-id="planId"/>
|
<test-plan-api v-if="activeIndex === 'api'" :plan-id="planId"/>
|
||||||
|
<test-case-statistics-report-view :test-plan="currentPlan" v-if="activeIndex === 'report'"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@ -35,10 +37,12 @@
|
|||||||
import MsTestPlanHeaderBar from "./comonents/head/TestPlanHeaderBar";
|
import MsTestPlanHeaderBar from "./comonents/head/TestPlanHeaderBar";
|
||||||
import TestPlanFunctional from "./comonents/functional/TestPlanFunctional";
|
import TestPlanFunctional from "./comonents/functional/TestPlanFunctional";
|
||||||
import TestPlanApi from "./comonents/api/TestPlanApi";
|
import TestPlanApi from "./comonents/api/TestPlanApi";
|
||||||
|
import TestCaseStatisticsReportView from "./comonents/report/statistics/TestCaseStatisticsReportView";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TestPlanView",
|
name: "TestPlanView",
|
||||||
components: {
|
components: {
|
||||||
|
TestCaseStatisticsReportView,
|
||||||
TestPlanApi,
|
TestPlanApi,
|
||||||
TestPlanFunctional,
|
TestPlanFunctional,
|
||||||
MsTestPlanHeaderBar,
|
MsTestPlanHeaderBar,
|
||||||
|
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<common-component :title="$t('test_track.plan_view.failure_case')">
|
||||||
|
<template>
|
||||||
|
<functional-failure-cases-list :functional-test-cases="failureTestCases.functionalTestCases"/>
|
||||||
|
<api-failure-cases-list :api-test-cases="failureTestCases.apiTestCases"/>
|
||||||
|
<scenario-failure-cases-list :scenario-test-cases="failureTestCases.scenarioTestCases"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</common-component>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CommonComponent from "./CommonComponent";
|
||||||
|
import PriorityTableItem from "../../../../../common/tableItems/planview/PriorityTableItem";
|
||||||
|
import TypeTableItem from "../../../../../common/tableItems/planview/TypeTableItem";
|
||||||
|
import MethodTableItem from "../../../../../common/tableItems/planview/MethodTableItem";
|
||||||
|
import StatusTableItem from "../../../../../common/tableItems/planview/StatusTableItem";
|
||||||
|
import {hub} from "@/business/components/track/plan/event-bus";
|
||||||
|
import FunctionalFailureCasesList from "./component/FunctionalFailureCasesList";
|
||||||
|
import ApiFailureCasesList from "./component/ApiFailureCasesList";
|
||||||
|
import ScenarioFailureCasesList from "./component/ScenarioFailureCasesList";
|
||||||
|
export default {
|
||||||
|
name: "FailureResultAdvanceComponent",
|
||||||
|
components: {
|
||||||
|
ScenarioFailureCasesList,
|
||||||
|
ApiFailureCasesList,
|
||||||
|
FunctionalFailureCasesList,
|
||||||
|
StatusTableItem, MethodTableItem, TypeTableItem, PriorityTableItem, CommonComponent},
|
||||||
|
props: {
|
||||||
|
failureTestCases: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
functionalTestCases: [
|
||||||
|
{
|
||||||
|
name: 'testCase1',
|
||||||
|
priority: 'P1',
|
||||||
|
type: 'api',
|
||||||
|
method: 'auto',
|
||||||
|
nodePath: '/module1/module2',
|
||||||
|
executorName: "Tom",
|
||||||
|
status: "Failure",
|
||||||
|
updateTime: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'testCase2',
|
||||||
|
priority: 'P0',
|
||||||
|
type: 'functional',
|
||||||
|
method: 'manual',
|
||||||
|
nodePath: '/module1',
|
||||||
|
executorName: "Micheal",
|
||||||
|
status: "Failure",
|
||||||
|
updateTime: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
apiTestCases: [
|
||||||
|
{
|
||||||
|
name: 'testCase3',
|
||||||
|
priority: 'P2',
|
||||||
|
path: '/module1/module2',
|
||||||
|
createUser: "Tom",
|
||||||
|
lastResult: "Failure",
|
||||||
|
updateTime: new Date(),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
scenarioTestCases: [
|
||||||
|
{
|
||||||
|
name: 'testCase4',
|
||||||
|
level: 'P3',
|
||||||
|
modulePath: '/module1/module2',
|
||||||
|
stepTotal: 10,
|
||||||
|
passRate: '80%',
|
||||||
|
userId: "Tom",
|
||||||
|
lastResult: "Failure",
|
||||||
|
updateTime: new Date(),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
goFailureTestCase(row) {
|
||||||
|
hub.$emit("openFailureTestCase", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
/deep/ .failure-cases-list-header {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.failure-cases-list {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -5,8 +5,10 @@
|
|||||||
<div v-if="!metric">
|
<div v-if="!metric">
|
||||||
<base-info-component :is-report="false" v-if="preview.id == 1"/>
|
<base-info-component :is-report="false" v-if="preview.id == 1"/>
|
||||||
<test-result-component v-if="preview.id == 2"/>
|
<test-result-component v-if="preview.id == 2"/>
|
||||||
<test-result-chart-component v-if="preview.id == 3"/>
|
<!--<test-result-chart-component v-if="preview.id == 3"/>-->
|
||||||
<failure-result-component v-if="preview.id == 4"/>
|
<test-result-advance-chart-component v-if="preview.id == 3"/>
|
||||||
|
<!--<failure-result-component v-if="preview.id == 4"/>-->
|
||||||
|
<failure-result-advance-component v-if="preview.id == 4"/>
|
||||||
<defect-list-component v-if="preview.id == 5"/>
|
<defect-list-component v-if="preview.id == 5"/>
|
||||||
<rich-text-component :preview="preview" v-if="preview.type != 'system'"/>
|
<rich-text-component :preview="preview" v-if="preview.type != 'system'"/>
|
||||||
</div>
|
</div>
|
||||||
@ -15,8 +17,10 @@
|
|||||||
<div v-if="metric">
|
<div v-if="metric">
|
||||||
<base-info-component id="baseInfoComponent" :report-info="metric" v-if="preview.id == 1"/>
|
<base-info-component id="baseInfoComponent" :report-info="metric" v-if="preview.id == 1"/>
|
||||||
<test-result-component id="testResultComponent" :test-results="metric.moduleExecuteResult" v-if="preview.id == 2"/>
|
<test-result-component id="testResultComponent" :test-results="metric.moduleExecuteResult" v-if="preview.id == 2"/>
|
||||||
<test-result-chart-component id="resultChartComponent" :execute-result="metric.executeResult" v-if="preview.id == 3"/>
|
<!--<test-result-chart-component id="resultChartComponent" :execute-result="metric.executeResult" v-if="preview.id == 3"/>-->
|
||||||
<failure-result-component id="failureResultComponent" :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>
|
<test-result-advance-chart-component id="resultChartComponent" :execute-result="metric.executeResult" v-if="preview.id == 3"/>
|
||||||
|
<!--<failure-result-component id="failureResultComponent" :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>-->
|
||||||
|
<failure-result-advance-component id="failureResultComponent" :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>
|
||||||
<defect-list-component id="defectListComponent" :defect-list="metric.issues" v-if="preview.id == 5"/>
|
<defect-list-component id="defectListComponent" :defect-list="metric.issues" v-if="preview.id == 5"/>
|
||||||
<rich-text-component id="richTextComponent" :is-report-view="isReportView" :preview="preview" v-if="preview.type != 'system'"/>
|
<rich-text-component id="richTextComponent" :is-report-view="isReportView" :preview="preview" v-if="preview.type != 'system'"/>
|
||||||
</div>
|
</div>
|
||||||
@ -32,10 +36,14 @@
|
|||||||
import FailureResultComponent from "./FailureResultComponent";
|
import FailureResultComponent from "./FailureResultComponent";
|
||||||
import DefectListComponent from "./DefectListComponent";
|
import DefectListComponent from "./DefectListComponent";
|
||||||
import html2canvas from 'html2canvas';
|
import html2canvas from 'html2canvas';
|
||||||
|
import TestResultAdvanceChartComponent from "./TestResultAdvanceChartComponent";
|
||||||
|
import FailureResultAdvanceComponent from "./FailureResultAdvanceComponent";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TemplateComponent",
|
name: "TemplateComponent",
|
||||||
components: {
|
components: {
|
||||||
|
FailureResultAdvanceComponent,
|
||||||
|
TestResultAdvanceChartComponent,
|
||||||
FailureResultComponent,DefectListComponent,
|
FailureResultComponent,DefectListComponent,
|
||||||
RichTextComponent, TestResultChartComponent, TestResultComponent, BaseInfoComponent},
|
RichTextComponent, TestResultChartComponent, TestResultComponent, BaseInfoComponent},
|
||||||
props: {
|
props: {
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<common-component :title="$t('test_track.plan_view.result_statistics')">
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div class="char-item">
|
||||||
|
<ms-pie-chart v-if="isShow" :text="'功能测试用例'"
|
||||||
|
:name="$t('test_track.plan_view.test_result')" :data="functionalCharData"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="char-item">
|
||||||
|
<ms-pie-chart v-if="isShow" :text="'接口测试用例'"
|
||||||
|
:name="$t('test_track.plan_view.test_result')" :data="apiCharData"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="char-item">
|
||||||
|
<ms-pie-chart v-if="isShow" :text="'场景测试用例'"
|
||||||
|
:name="$t('test_track.plan_view.test_result')" :data="scenarioCharData"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</common-component>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CommonComponent from "./CommonComponent";
|
||||||
|
import MsPieChart from "../../../../../../common/components/MsPieChart";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestResultAdvanceChartComponent",
|
||||||
|
components: {MsPieChart, CommonComponent},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dataMap: new Map([
|
||||||
|
["Pass", {name: this.$t('test_track.plan_view.pass'), itemStyle: {color: '#67C23A'}}],
|
||||||
|
["Failure", {name: this.$t('test_track.plan_view.failure'), itemStyle: {color: '#F56C6C'}}],
|
||||||
|
["Blocking", {name: this.$t('test_track.plan_view.blocking'), itemStyle: {color: '#E6A23C'}}],
|
||||||
|
["Skip", {name: this.$t('test_track.plan_view.skip'), itemStyle: {color: '#909399'}}],
|
||||||
|
["Underway", {name: this.$t('test_track.plan.plan_status_running'), itemStyle: {color: 'lightskyblue'}}],
|
||||||
|
["Prepare", {name: this.$t('test_track.plan.plan_status_prepare'), itemStyle: {color: '#DEDE10'}}]
|
||||||
|
]),
|
||||||
|
functionalCharData: [],
|
||||||
|
apiCharData: [],
|
||||||
|
scenarioCharData: [],
|
||||||
|
isShow: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
executeResult: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
functionalResult: [
|
||||||
|
{status: 'Pass', count: '235'},
|
||||||
|
{status: 'Failure', count: '310'},
|
||||||
|
{status: 'Blocking', count: '274'},
|
||||||
|
{status: 'Skip', count: '335'},
|
||||||
|
{status: 'Underway', count: '245'},
|
||||||
|
{status: 'Prepare', count: '265'},
|
||||||
|
],
|
||||||
|
apiResult: [
|
||||||
|
{status: 'Pass', count: '235'},
|
||||||
|
{status: 'Failure', count: '310'},
|
||||||
|
{status: 'Underway', count: '245'},
|
||||||
|
],
|
||||||
|
scenarioResult: [
|
||||||
|
{status: 'Pass', count: '205'},
|
||||||
|
{status: 'Failure', count: '350'},
|
||||||
|
{status: 'Underway', count: '110'},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
executeResult() {
|
||||||
|
this.getCharData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getCharData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getCharData() {
|
||||||
|
this.getFunctionalCharData();
|
||||||
|
this.getApiCharData();
|
||||||
|
this.getScenarioCharData();
|
||||||
|
this.reload();
|
||||||
|
},
|
||||||
|
getFunctionalCharData() {
|
||||||
|
this.functionalCharData = [];
|
||||||
|
if (this.executeResult.functionalResult) {
|
||||||
|
this.executeResult.functionalResult.forEach(item => {
|
||||||
|
let data = this.dataMap.get(item.status);
|
||||||
|
data.value = item.count;
|
||||||
|
this.functionalCharData.push(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getApiCharData() {
|
||||||
|
this.apiCharData = [];
|
||||||
|
if (this.executeResult.apiResult) {
|
||||||
|
this.executeResult.apiResult.forEach(item => {
|
||||||
|
let data = this.dataMap.get(item.status);
|
||||||
|
data.value = item.count;
|
||||||
|
this.apiCharData.push(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getScenarioCharData() {
|
||||||
|
this.scenarioCharData = [];
|
||||||
|
if (this.executeResult.apiResult) {
|
||||||
|
this.executeResult.scenarioResult.forEach(item => {
|
||||||
|
let data = this.dataMap.get(item.status);
|
||||||
|
data.value = item.count;
|
||||||
|
this.scenarioCharData.push(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reload() {
|
||||||
|
this.isShow = false;
|
||||||
|
this.$nextTick(function () {
|
||||||
|
this.isShow = true;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.echarts {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.char-item {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<div class="failure-cases-list">
|
||||||
|
<div class="failure-cases-list-header">
|
||||||
|
接口测试用例
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
row-key="id"
|
||||||
|
@row-click="goFailureTestCase"
|
||||||
|
:data="apiTestCases">
|
||||||
|
|
||||||
|
<el-table-column prop="name" :label="$t('api_test.definition.api_name')" show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="priority"
|
||||||
|
column-key="priority"
|
||||||
|
:label="$t('test_track.case.priority')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<priority-table-item :value="scope.row.priority"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="path"
|
||||||
|
:label="$t('test_track.case.module')"
|
||||||
|
show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="createUser"
|
||||||
|
:label="'创建人'"
|
||||||
|
show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column prop="lastResult" :label="$t('api_test.automation.last_result')">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<ms-tag type="danger" :content="$t('test_track.plan_view.failure')"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
width="160"
|
||||||
|
:label="$t('api_test.definition.api_last_time')"
|
||||||
|
prop="updateTime">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import StatusTableItem from "../../../../../../common/tableItems/planview/StatusTableItem";
|
||||||
|
import MethodTableItem from "../../../../../../common/tableItems/planview/MethodTableItem";
|
||||||
|
import TypeTableItem from "../../../../../../common/tableItems/planview/TypeTableItem";
|
||||||
|
import PriorityTableItem from "../../../../../../common/tableItems/planview/PriorityTableItem";
|
||||||
|
import MsTag from "../../../../../../../common/components/MsTag";
|
||||||
|
export default {
|
||||||
|
name: "ApiFailureCasesList",
|
||||||
|
components: {MsTag, PriorityTableItem, TypeTableItem, MethodTableItem, StatusTableItem},
|
||||||
|
props: ['apiTestCases'],
|
||||||
|
methods: {
|
||||||
|
goFailureTestCase(row) {
|
||||||
|
this.$emit("openFailureTestCase", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<div class="failure-cases-list">
|
||||||
|
<div class="failure-cases-list-header">
|
||||||
|
功能测试用例
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
row-key="id"
|
||||||
|
@row-click="goFailureTestCase"
|
||||||
|
:data="functionalTestCases">
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="num"
|
||||||
|
:label="$t('commons.id')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
:label="$t('commons.name')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="priority"
|
||||||
|
column-key="priority"
|
||||||
|
:label="$t('test_track.case.priority')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<priority-table-item :value="scope.row.priority" ref="priority"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="type"
|
||||||
|
column-key="type"
|
||||||
|
:label="$t('test_track.case.type')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<type-table-item :value="scope.row.type"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="method"
|
||||||
|
column-key="method"
|
||||||
|
:label="$t('test_track.case.method')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<method-table-item :value="scope.row.method"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="nodePath"
|
||||||
|
:label="$t('test_track.case.module')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="projectName"
|
||||||
|
:label="$t('test_track.case.project_name')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="executorName"
|
||||||
|
:label="$t('test_track.plan_view.executor')">
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
column-key="status"
|
||||||
|
:label="$t('test_track.plan_view.execute_result')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<status-table-item :value="scope.row.status"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="updateTime"
|
||||||
|
:label="$t('api_test.automation.update_time')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import StatusTableItem from "../../../../../../common/tableItems/planview/StatusTableItem";
|
||||||
|
import MethodTableItem from "../../../../../../common/tableItems/planview/MethodTableItem";
|
||||||
|
import TypeTableItem from "../../../../../../common/tableItems/planview/TypeTableItem";
|
||||||
|
import PriorityTableItem from "../../../../../../common/tableItems/planview/PriorityTableItem";
|
||||||
|
export default {
|
||||||
|
name: "FunctionalFailureCasesList",
|
||||||
|
components: {PriorityTableItem, TypeTableItem, MethodTableItem, StatusTableItem},
|
||||||
|
props: ['functionalTestCases'],
|
||||||
|
methods: {
|
||||||
|
goFailureTestCase(row) {
|
||||||
|
this.$emit("openFailureTestCase", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<div class="failure-cases-list">
|
||||||
|
<div class="failure-cases-list-header">
|
||||||
|
场景测试用例
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
row-key="id"
|
||||||
|
@row-click="goFailureTestCase"
|
||||||
|
:data="scenarioTestCases">
|
||||||
|
|
||||||
|
<el-table-column prop="name" :label="$t('api_test.automation.scenario_name')" show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column prop="level" :label="$t('api_test.automation.case_level')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<priority-table-item :value="scope.row.level" ref="priority"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="tags" :label="$t('api_test.automation.tag')" width="200px">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<div v-for="(itemName,index) in scope.row.tags" :key="index">
|
||||||
|
<ms-tag type="success" effect="plain" :content="itemName"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="modulePath"
|
||||||
|
:label="$t('test_track.case.module')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="stepTotal" :label="$t('api_test.automation.step')" show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column prop="passRate" :label="$t('api_test.automation.passing_rate')" show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column prop="userId" :label="$t('api_test.automation.creator')" show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column prop="lastResult" :label="$t('api_test.automation.last_result')">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<ms-tag type="danger" :content="$t('test_track.plan_view.failure')"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="updateTime" :label="$t('api_test.automation.update_time')" width="180">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import StatusTableItem from "../../../../../../common/tableItems/planview/StatusTableItem";
|
||||||
|
import MethodTableItem from "../../../../../../common/tableItems/planview/MethodTableItem";
|
||||||
|
import TypeTableItem from "../../../../../../common/tableItems/planview/TypeTableItem";
|
||||||
|
import PriorityTableItem from "../../../../../../common/tableItems/planview/PriorityTableItem";
|
||||||
|
import MsTag from "../../../../../../../common/components/MsTag";
|
||||||
|
export default {
|
||||||
|
name: "ScenarioFailureCasesList",
|
||||||
|
components: {MsTag, PriorityTableItem, TypeTableItem, MethodTableItem, StatusTableItem},
|
||||||
|
props: ['scenarioTestCases'],
|
||||||
|
methods: {
|
||||||
|
goFailureTestCase(row) {
|
||||||
|
this.$emit("openFailureTestCase", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,252 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<el-row type="flex" class="head-bar">
|
||||||
|
<el-col :span="12">
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col v-if="!reportId" :span="12" class="head-right">
|
||||||
|
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="openTemplateReport">
|
||||||
|
{{$t('test_track.plan_view.create_report')}}
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col v-else :span="12" class="head-right">
|
||||||
|
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleSave">
|
||||||
|
{{$t('commons.save')}}
|
||||||
|
</el-button>
|
||||||
|
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleEdit">
|
||||||
|
{{$t('test_track.plan_view.edit_component')}}
|
||||||
|
</el-button>
|
||||||
|
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleExport(report.name)">
|
||||||
|
{{$t('test_track.plan_view.export_report')}}
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<div class="container" ref="resume" id="app">
|
||||||
|
<el-main>
|
||||||
|
<div v-for="(item, index) in previews" :key="item.id">
|
||||||
|
<template-component :isReportView="true" :metric="metric" :preview="item" :index="index" ref="templateComponent"/>
|
||||||
|
</div>
|
||||||
|
</el-main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<test-report-template-list @openReport="openReport" ref="testReportTemplateList"/>
|
||||||
|
|
||||||
|
<ms-test-case-report-export v-if="reportExportVisible" id="testCaseReportExport" :title="report.name" :metric="metric" :previews="previews"/>
|
||||||
|
<test-case-report-template-edit :metric="metric" ref="templateEdit" @refresh="getReport"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {checkoutTestManagerOrTestUser, exportPdf, jsonToMap, mapToJson} from "../../../../../../../../common/js/utils";
|
||||||
|
import BaseInfoComponent from "../TemplateComponent/BaseInfoComponent";
|
||||||
|
import TestResultChartComponent from "../TemplateComponent/TestResultChartComponent";
|
||||||
|
import TestResultComponent from "../TemplateComponent/TestResultComponent";
|
||||||
|
import RichTextComponent from "../TemplateComponent/RichTextComponent";
|
||||||
|
import TestCaseReportTemplateEdit from "../TestCaseReportTemplateEdit";
|
||||||
|
import TemplateComponent from "../TemplateComponent/TemplateComponent";
|
||||||
|
import html2canvas from "html2canvas";
|
||||||
|
import MsTestCaseReportExport from "../../TestCaseReportExport";
|
||||||
|
import TestReportTemplateList from "../../TestReportTemplateList";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TestCaseStatisticsReportView",
|
||||||
|
components: {
|
||||||
|
TestReportTemplateList,
|
||||||
|
MsTestCaseReportExport,
|
||||||
|
TemplateComponent,
|
||||||
|
TestCaseReportTemplateEdit,
|
||||||
|
RichTextComponent, TestResultComponent, TestResultChartComponent, BaseInfoComponent
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: {},
|
||||||
|
imgUrl: "",
|
||||||
|
previews: [],
|
||||||
|
report: {},
|
||||||
|
metric: {},
|
||||||
|
reportExportVisible: false,
|
||||||
|
componentMap: new Map(
|
||||||
|
[
|
||||||
|
[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.failure_case'), id: 4, type: 'system'}],
|
||||||
|
[5, {name: this.$t('test_track.plan_view.defect_list'), id: 5, type: 'system'}],
|
||||||
|
[6, {name: this.$t('test_track.plan_view.custom_component'), id: 6, type: 'custom'}]
|
||||||
|
]
|
||||||
|
),
|
||||||
|
isTestManagerOrTestUser: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||||
|
this.getReport();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
reportId() {
|
||||||
|
this.getReport();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
planId() {
|
||||||
|
return this.testPlan.id;
|
||||||
|
},
|
||||||
|
reportId() {
|
||||||
|
return this.testPlan.reportId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: ['testPlan'],
|
||||||
|
methods: {
|
||||||
|
openTemplateReport() {
|
||||||
|
this.$refs.testReportTemplateList.open(this.planId);
|
||||||
|
},
|
||||||
|
openReport(planId, id) {
|
||||||
|
this.testPlan.reportId = id;
|
||||||
|
},
|
||||||
|
getReport() {
|
||||||
|
if (this.reportId) {
|
||||||
|
this.result = this.$get('/case/report/get/' + this.reportId, response => {
|
||||||
|
this.report = response.data;
|
||||||
|
this.report.content = JSON.parse(response.data.content);
|
||||||
|
if (this.report.content.customComponent) {
|
||||||
|
this.report.content.customComponent = jsonToMap(this.report.content.customComponent);
|
||||||
|
}
|
||||||
|
this.getMetric();
|
||||||
|
this.initPreviews();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initPreviews() {
|
||||||
|
this.previews = [];
|
||||||
|
this.report.content.components.forEach(item => {
|
||||||
|
let preview = this.componentMap.get(item);
|
||||||
|
if (preview && preview.type != 'custom') {
|
||||||
|
this.previews.push(preview);
|
||||||
|
} else {
|
||||||
|
if (this.report.content.customComponent) {
|
||||||
|
let customComponent = this.report.content.customComponent.get(item.toString());
|
||||||
|
if (customComponent) {
|
||||||
|
this.previews.push({id: item, title: customComponent.title, content: customComponent.content});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleEdit() {
|
||||||
|
this.$refs.templateEdit.open(this.reportId, true);
|
||||||
|
},
|
||||||
|
handleSave() {
|
||||||
|
let param = {};
|
||||||
|
this.buildParam(param);
|
||||||
|
this.result = this.$post('/case/report/edit', param, () => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
buildParam(param) {
|
||||||
|
let content = {};
|
||||||
|
content.components = [];
|
||||||
|
this.previews.forEach(item => {
|
||||||
|
content.components.push(item.id);
|
||||||
|
if (!this.componentMap.get(item.id)) {
|
||||||
|
content.customComponent = new Map();
|
||||||
|
content.customComponent.set(item.id, {title: item.title, content: item.content})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
param.name = this.report.name;
|
||||||
|
if (content.customComponent) {
|
||||||
|
content.customComponent = mapToJson(content.customComponent);
|
||||||
|
}
|
||||||
|
param.content = JSON.stringify(content);
|
||||||
|
param.id = this.report.id;
|
||||||
|
if (this.metric.startTime) {
|
||||||
|
param.startTime = this.metric.startTime.getTime();
|
||||||
|
}
|
||||||
|
if (this.metric.endTime) {
|
||||||
|
param.endTime = this.metric.endTime.getTime();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getMetric() {
|
||||||
|
this.result = this.$get('/test/plan/get/statistics/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.metric.issues) {
|
||||||
|
this.metric.issues = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (this.report.startTime) {
|
||||||
|
this.metric.startTime = new Date(this.report.startTime);
|
||||||
|
}
|
||||||
|
if (this.report.endTime) {
|
||||||
|
this.metric.endTime = new Date(this.report.endTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleExport(name) {
|
||||||
|
this.result.loading = true;
|
||||||
|
this.reportExportVisible = true;
|
||||||
|
let reset = this.exportReportReset;
|
||||||
|
|
||||||
|
this.$nextTick(function () {
|
||||||
|
setTimeout(() => {
|
||||||
|
html2canvas(document.getElementById('testCaseReportExport'), {
|
||||||
|
scale: 2
|
||||||
|
}).then(function(canvas) {
|
||||||
|
exportPdf(name, [canvas]);
|
||||||
|
reset();
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
exportReportReset() {
|
||||||
|
this.reportExportVisible = false;
|
||||||
|
this.result.loading = false;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>cd
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.el-main {
|
||||||
|
height: calc(100vh - 70px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-bar {
|
||||||
|
background: white;
|
||||||
|
height: 45px;
|
||||||
|
line-height: 45px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
box-shadow: 0 0 2px 0 rgba(31, 31, 31, 0.15), 0 1px 2px 0 rgba(31, 31, 31, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
height: 100vh;
|
||||||
|
/*background: #F5F5F5;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-card {
|
||||||
|
width: 70%;
|
||||||
|
margin: 5px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user