feat(接口测试): 接口测试样式优化
--story=1007743 --user=宋天阳 接口测试首页数据统计优化 https://www.tapd.cn/55049933/s/1193399
This commit is contained in:
parent
74b0d0493e
commit
83b8b90669
|
@ -6,13 +6,15 @@ import io.metersphere.api.dto.*;
|
|||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
|
||||
import io.metersphere.api.dto.datacount.request.ScheduleInfoRequest;
|
||||
import io.metersphere.api.dto.datacount.response.ApiDataCountDTO;
|
||||
import io.metersphere.api.dto.datacount.response.ExecutedCaseInfoDTO;
|
||||
import io.metersphere.api.dto.datacount.response.TaskInfoResult;
|
||||
import io.metersphere.api.dto.datacount.response.*;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
|
||||
import io.metersphere.api.service.*;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.domain.ApiDefinition;
|
||||
import io.metersphere.base.domain.ApiDefinitionExecResultExpand;
|
||||
import io.metersphere.base.domain.ApiTest;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.ExecuteResult;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.BaseQueryRequest;
|
||||
|
@ -22,6 +24,7 @@ import io.metersphere.dto.ScheduleDao;
|
|||
import io.metersphere.notice.annotation.SendNotice;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -229,6 +232,36 @@ public class APITestController {
|
|||
apiCountResult.setTcpCountStr("TCP <br/><br/>" + apiCountResult.getTcpApiDataCountNumber());
|
||||
apiCountResult.setSqlCountStr("SQL <br/><br/>" + apiCountResult.getSqlApiDataCountNumber());
|
||||
|
||||
//计算用例的通过率
|
||||
List<ExecuteResultCountDTO> apiCaseExecResultList = apiTestCaseService.selectExecuteResultByProjectId(projectId);
|
||||
long unexecuteCount = 0;
|
||||
long executionFailedCount = 0;
|
||||
long executionPassCount = 0;
|
||||
long fakeErrorCount = 0;
|
||||
for (ExecuteResultCountDTO execResult : apiCaseExecResultList) {
|
||||
if (StringUtils.isEmpty(execResult.getExecResult())) {
|
||||
unexecuteCount += execResult.getCount();
|
||||
} else if (StringUtils.equalsIgnoreCase(execResult.getExecResult(), ExecuteResult.API_SUCCESS.toString())) {
|
||||
executionPassCount += execResult.getCount();
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(execResult.getExecResult(), ExecuteResult.ERROR_REPORT_RESULT.toString(), ExecuteResult.ERROR_REPORT.toString())) {
|
||||
fakeErrorCount += execResult.getCount();
|
||||
} else {
|
||||
executionFailedCount += execResult.getCount();
|
||||
}
|
||||
}
|
||||
apiCountResult.setUnexecuteCount(unexecuteCount);
|
||||
apiCountResult.setExecutionFailedCount(executionFailedCount);
|
||||
apiCountResult.setExecutionPassCount(executionPassCount);
|
||||
apiCountResult.setFakeErrorCount(fakeErrorCount);
|
||||
|
||||
if (unexecuteCount + executedCountNumber + executionPassCount > 0) {
|
||||
//通过率
|
||||
float coverageRageNumber = (float) executionPassCount * 100 / (unexecuteCount + executedCountNumber + executionPassCount);
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
apiCountResult.setPassRage(df.format(coverageRageNumber) + "%");
|
||||
} else {
|
||||
apiCountResult.setPassRage("0%");
|
||||
}
|
||||
return apiCountResult;
|
||||
}
|
||||
|
||||
|
@ -263,9 +296,15 @@ public class APITestController {
|
|||
return apiCountResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口覆盖率统计
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/countApiCoverage/{projectId}")
|
||||
public String countApiCoverage(@PathVariable String projectId) {
|
||||
String returnStr = "0%";
|
||||
public CoverageDTO countApiCoverage(@PathVariable String projectId) {
|
||||
CoverageDTO coverage = new CoverageDTO();
|
||||
/**
|
||||
* 接口覆盖率
|
||||
* 接口有案例/被场景引用 : 所有的接口
|
||||
|
@ -273,34 +312,40 @@ public class APITestController {
|
|||
long effectiveApiCount = apiDefinitionService.countEffectiveByProjectId(projectId);
|
||||
long sourceIdCount = apiDefinitionService.countQuotedApiByProjectId(projectId);
|
||||
try {
|
||||
if(sourceIdCount != 0){
|
||||
if (sourceIdCount != 0) {
|
||||
coverage.setCoverate(sourceIdCount);
|
||||
coverage.setNotCoverate(effectiveApiCount - sourceIdCount);
|
||||
float coverageRageNumber = (float) sourceIdCount * 100 / effectiveApiCount;
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
returnStr = df.format(coverageRageNumber) + "%";
|
||||
coverage.setRateOfCoverage(df.format(coverageRageNumber) + "%");
|
||||
}
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
return returnStr;
|
||||
return coverage;
|
||||
}
|
||||
|
||||
@GetMapping("/countInterfaceCoverage/{projectId}")
|
||||
public String countInterfaceCoverage(@PathVariable String projectId) {
|
||||
String returnStr = "0%";
|
||||
/**
|
||||
* 场景覆盖率统计
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/countScenarioCoverage/{projectId}")
|
||||
public CoverageDTO countScenarioCoverage(@PathVariable String projectId) {
|
||||
CoverageDTO coverage = new CoverageDTO();
|
||||
/**
|
||||
* 接口覆盖率
|
||||
* 复制的接口定义/复制或引用的单接口用例/ 添加的自定义请求 url 路径与现有的接口定义一致的请求
|
||||
*/
|
||||
Map<String,List<String>> scenarioUrlList = apiAutomationService.selectScenarioUseUrlByProjectId(projectId);
|
||||
Map<String, Map<String, String>> scenarioUrlList = apiAutomationService.selectScenarioUseUrlByProjectId(projectId);
|
||||
List<ApiDefinition> allEffectiveApiIdList = apiDefinitionService.selectEffectiveIdByProjectId(projectId);
|
||||
try {
|
||||
float intetfaceCoverageRageNumber = apiAutomationService.countInterfaceCoverage(scenarioUrlList, allEffectiveApiIdList);
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
returnStr = df.format(intetfaceCoverageRageNumber) + "%";
|
||||
}catch (Exception e){
|
||||
coverage = apiAutomationService.countInterfaceCoverage(projectId, scenarioUrlList, allEffectiveApiIdList);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
return returnStr;
|
||||
return coverage;
|
||||
}
|
||||
|
||||
@GetMapping("/scheduleTaskInfoCount/{projectId}")
|
||||
|
@ -348,6 +393,7 @@ public class APITestController {
|
|||
dataDTO.setCaseName(selectData.getCaseName());
|
||||
dataDTO.setTestPlan(selectData.getTestPlan());
|
||||
dataDTO.setFailureTimes(selectData.getFailureTimes());
|
||||
dataDTO.setTestPlanId(selectData.getTestPlanId());
|
||||
dataDTO.setCaseType(selectData.getCaseType());
|
||||
dataDTO.setId(selectData.getId());
|
||||
dataDTO.setTestPlanDTOList(selectData.getTestPlanDTOList());
|
||||
|
@ -361,7 +407,7 @@ public class APITestController {
|
|||
}
|
||||
|
||||
@PostMapping("/runningTask/{projectID}")
|
||||
public List<TaskInfoResult> runningTask(@PathVariable String projectID,@RequestBody BaseQueryRequest request) {
|
||||
public List<TaskInfoResult> runningTask(@PathVariable String projectID, @RequestBody BaseQueryRequest request) {
|
||||
List<TaskInfoResult> resultList = scheduleService.findRunningTaskInfoByProjectID(projectID, request);
|
||||
int dataIndex = 1;
|
||||
for (TaskInfoResult taskInfo :
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package io.metersphere.api.dto.automation;
|
||||
|
||||
import io.metersphere.controller.request.BaseQueryRequest;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ApiScenarioRequest extends BaseQueryRequest {
|
||||
|
@ -20,7 +16,9 @@ public class ApiScenarioRequest extends BaseQueryRequest {
|
|||
private boolean recent = false;
|
||||
private boolean isSelectThisWeedData;
|
||||
private long createTime = 0;
|
||||
private long scheduleCreateTime = 0;
|
||||
private String executeStatus;
|
||||
private String selectDataType;
|
||||
private boolean notInTestPlan;
|
||||
private String reviewId;
|
||||
private String versionId;
|
||||
|
|
|
@ -18,6 +18,7 @@ public class ExecutedCaseInfoResult {
|
|||
private String caseName;
|
||||
//所属测试计划
|
||||
private String testPlan;
|
||||
private String testPlanId;
|
||||
//失败次数
|
||||
private Long failureTimes;
|
||||
//案例类型
|
||||
|
|
|
@ -2,8 +2,10 @@ package io.metersphere.api.dto.datacount.response;
|
|||
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.commons.constants.ExecuteResult;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -85,6 +87,10 @@ public class ApiDataCountDTO {
|
|||
* 执行通过
|
||||
*/
|
||||
private long executionPassCount = 0;
|
||||
/**
|
||||
* 执行误报
|
||||
*/
|
||||
private long fakeErrorCount = 0;
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
|
@ -116,16 +122,15 @@ public class ApiDataCountDTO {
|
|||
*/
|
||||
private String interfaceCoverage = " 0%";
|
||||
|
||||
public ApiDataCountDTO(){}
|
||||
|
||||
/**
|
||||
* 对Protocal视角对查询结果进行统计
|
||||
*
|
||||
* @param countResultList 查询参数
|
||||
*/
|
||||
public void countProtocal(List<ApiDataCountResult> countResultList){
|
||||
public void countProtocal(List<ApiDataCountResult> countResultList) {
|
||||
for (ApiDataCountResult countResult :
|
||||
countResultList) {
|
||||
switch (countResult.getGroupField().toUpperCase()){
|
||||
switch (countResult.getGroupField().toUpperCase()) {
|
||||
case RequestType.DUBBO:
|
||||
this.rpcApiDataCountNumber += countResult.getCountNumber();
|
||||
break;
|
||||
|
@ -148,19 +153,20 @@ public class ApiDataCountDTO {
|
|||
|
||||
/**
|
||||
* 对Status视角对查询结果进行统计
|
||||
*
|
||||
* @param countResultList 查询参数
|
||||
*/
|
||||
public void countStatus(List<ApiDataCountResult> countResultList){
|
||||
public void countStatus(List<ApiDataCountResult> countResultList) {
|
||||
for (ApiDataCountResult countResult :
|
||||
countResultList) {
|
||||
if("Underway".equals(countResult.getGroupField())){
|
||||
if (StringUtils.equalsIgnoreCase(countResult.getGroupField(), "Underway")) {
|
||||
//运行中
|
||||
this.runningCount+= countResult.getCountNumber();
|
||||
}else if("Completed".equals(countResult.getGroupField())){
|
||||
this.runningCount += countResult.getCountNumber();
|
||||
} else if (StringUtils.equalsIgnoreCase(countResult.getGroupField(), "Completed")) {
|
||||
//已完成
|
||||
this.finishedCount+= countResult.getCountNumber();
|
||||
}else if("Prepare".equals(countResult.getGroupField())){
|
||||
this.notStartedCount+= countResult.getCountNumber();
|
||||
this.finishedCount += countResult.getCountNumber();
|
||||
} else if (StringUtils.equalsIgnoreCase(countResult.getGroupField(), "Prepare")) {
|
||||
this.notStartedCount += countResult.getCountNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,35 +174,39 @@ public class ApiDataCountDTO {
|
|||
public void countApiCoverage(List<ApiDataCountResult> countResultList) {
|
||||
|
||||
for (ApiDataCountResult countResult : countResultList) {
|
||||
if("coverage".equals(countResult.getGroupField())){
|
||||
this.coverageCount+= countResult.getCountNumber();
|
||||
}else if("uncoverage".equals(countResult.getGroupField())){
|
||||
this.uncoverageCount+= countResult.getCountNumber();
|
||||
if (StringUtils.equalsIgnoreCase(countResult.getGroupField(), "coverage")) {
|
||||
this.coverageCount += countResult.getCountNumber();
|
||||
} else if (StringUtils.equalsIgnoreCase(countResult.getGroupField(), "uncoverage")) {
|
||||
this.uncoverageCount += countResult.getCountNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void countRunResult(List<ApiDataCountResult> countResultByRunResult) {
|
||||
|
||||
for (ApiDataCountResult countResult : countResultByRunResult) {
|
||||
if("notRun".equals(countResult.getGroupField())){
|
||||
this.unexecuteCount+= countResult.getCountNumber();
|
||||
}else if("Fail".equals(countResult.getGroupField())){
|
||||
this.executionFailedCount+= countResult.getCountNumber();
|
||||
}else {
|
||||
this.executionPassCount+= countResult.getCountNumber();
|
||||
if ("notRun".equals(countResult.getGroupField())) {
|
||||
this.unexecuteCount += countResult.getCountNumber();
|
||||
} else if ("Fail".equals(countResult.getGroupField())) {
|
||||
this.executionFailedCount += countResult.getCountNumber();
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(countResult.getGroupField(), ExecuteResult.ERROR_REPORT_RESULT.toString(), ExecuteResult.ERROR_REPORT.toString())) {
|
||||
this.fakeErrorCount += countResult.getCountNumber();
|
||||
} else {
|
||||
this.executionPassCount += countResult.getCountNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void countScheduleExecute(List<ApiDataCountResult> allExecuteResult) {
|
||||
for (ApiDataCountResult countResult : allExecuteResult) {
|
||||
if("Success".equals(countResult.getGroupField())){
|
||||
this.successCount+= countResult.getCountNumber();
|
||||
this.executedCount+= countResult.getCountNumber();
|
||||
}else if("Error".equals(countResult.getGroupField())||"Fail".equals(countResult.getGroupField())){
|
||||
this.failedCount+= countResult.getCountNumber();
|
||||
this.executedCount+= countResult.getCountNumber();
|
||||
if (StringUtils.equalsIgnoreCase(countResult.getGroupField(), "success")) {
|
||||
this.successCount += countResult.getCountNumber();
|
||||
this.executedCount += countResult.getCountNumber();
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(countResult.getGroupField(), ExecuteResult.SCENARIO_ERROR.toString(), "Fail")) {
|
||||
this.failedCount += countResult.getCountNumber();
|
||||
this.executedCount += countResult.getCountNumber();
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(countResult.getGroupField(), ExecuteResult.ERROR_REPORT_RESULT.toString())) {
|
||||
this.fakeErrorCount += countResult.getCountNumber();
|
||||
this.executedCount += countResult.getCountNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.api.dto.datacount.response;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class CoverageDTO {
|
||||
public String rateOfCoverage = "0%";
|
||||
public long coverate = 0;
|
||||
public long notCoverate = 0;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package io.metersphere.api.dto.datacount.response;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ExecuteResultCountDTO {
|
||||
private String execResult;
|
||||
private long count;
|
||||
}
|
|
@ -18,6 +18,7 @@ public class ExecutedCaseInfoDTO {
|
|||
private String caseName;
|
||||
//所属测试计划
|
||||
private String testPlan;
|
||||
private String testPlanId;
|
||||
//失败次数
|
||||
private Long failureTimes;
|
||||
//案例类型
|
||||
|
|
|
@ -20,7 +20,9 @@ public class ApiDefinitionRequest extends BaseQueryRequest {
|
|||
private boolean isSelectThisWeedData = false;
|
||||
private long createTime = 0;
|
||||
private String status;
|
||||
private String apiCoverage;
|
||||
private String apiCaseCoverage;
|
||||
private String scenarioCoverage;
|
||||
private String reviewId;
|
||||
private String refId;
|
||||
private String versionId;
|
||||
|
|
|
@ -50,4 +50,7 @@ public class ApiTestCaseRequest extends BaseQueryRequest {
|
|||
* 查询排除一些接口
|
||||
*/
|
||||
private List<String> notInIds;
|
||||
|
||||
//页面跳转时附带的过滤条件
|
||||
private String redirectFilter;
|
||||
}
|
||||
|
|
|
@ -703,7 +703,46 @@ public class MockApiUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean isUrlInList(String url, List<String> urlList) {
|
||||
public static boolean isUrlMatch(String url, String compareUrl) {
|
||||
String urlSuffix = url;
|
||||
if (urlSuffix.startsWith("/")) {
|
||||
urlSuffix = urlSuffix.substring(1);
|
||||
}
|
||||
String[] urlParams = urlSuffix.split("/");
|
||||
if (StringUtils.equalsAny(compareUrl, url, "/" + url)) {
|
||||
return true;
|
||||
} else {
|
||||
if (StringUtils.isEmpty(compareUrl)) {
|
||||
return false;
|
||||
}
|
||||
if (compareUrl.startsWith("/")) {
|
||||
compareUrl = compareUrl.substring(1);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(compareUrl)) {
|
||||
String[] pathArr = compareUrl.split("/");
|
||||
if (pathArr.length == urlParams.length) {
|
||||
boolean isFetch = true;
|
||||
for (int i = 0; i < urlParams.length; i++) {
|
||||
String pathItem = pathArr[i];
|
||||
String urlItem = urlParams[i];
|
||||
if (!(pathItem.startsWith("{") && pathItem.endsWith("}")) && !(urlItem.startsWith("{") && urlItem.endsWith("}"))) {
|
||||
if (!StringUtils.equals(pathArr[i], urlParams[i])) {
|
||||
isFetch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (isFetch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isUrlInList(String url, Collection<String> urlList) {
|
||||
if (CollectionUtils.isEmpty(urlList)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.api.dto.automation.parse.ApiScenarioImportUtil;
|
|||
import io.metersphere.api.dto.automation.parse.ScenarioImport;
|
||||
import io.metersphere.api.dto.automation.parse.ScenarioImportParserFactory;
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.dto.datacount.response.CoverageDTO;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseInfo;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.request.*;
|
||||
|
@ -74,6 +75,7 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -234,7 +236,11 @@ public class ApiAutomationService {
|
|||
Map<String, Date> weekFirstTimeAndLastTime = DateUtils.getWeedFirstTimeAndLastTime(new Date());
|
||||
Date weekFirstTime = weekFirstTimeAndLastTime.get("firstTime");
|
||||
if (weekFirstTime != null) {
|
||||
request.setCreateTime(weekFirstTime.getTime());
|
||||
if (StringUtils.equalsIgnoreCase(request.getSelectDataType(), "SCHEDULE")) {
|
||||
request.setScheduleCreateTime(weekFirstTime.getTime());
|
||||
} else {
|
||||
request.setCreateTime(weekFirstTime.getTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1684,20 +1690,51 @@ public class ApiAutomationService {
|
|||
* @param allEffectiveApiList 接口集合(id / path 必须有数据)
|
||||
* @return
|
||||
*/
|
||||
public float countInterfaceCoverage(Map<String, List<String>> scenarioUrlMap, List<ApiDefinition> allEffectiveApiList) {
|
||||
public CoverageDTO countInterfaceCoverage(String projectId, Map<String, Map<String, String>> scenarioUrlMap, List<ApiDefinition> allEffectiveApiList) {
|
||||
CoverageDTO coverage = new CoverageDTO();
|
||||
|
||||
if (MapUtils.isEmpty(scenarioUrlMap) || CollectionUtils.isEmpty(allEffectiveApiList)) {
|
||||
return 0;
|
||||
return coverage;
|
||||
}
|
||||
|
||||
ProjectApplication urlRepeatableConfig = projectApplicationService.getProjectApplication(projectId, ProjectApplicationType.URL_REPEATABLE.name());
|
||||
boolean isUrlRepeatable = BooleanUtils.toBoolean(urlRepeatableConfig.getTypeValue());
|
||||
|
||||
int containsCount = 0;
|
||||
for (ApiDefinition model : allEffectiveApiList) {
|
||||
List<String> scenarioUrlList = scenarioUrlMap.get(model.getMethod());
|
||||
boolean matchedUrl = MockApiUtils.isUrlInList(model.getPath(), scenarioUrlList);
|
||||
if (matchedUrl) {
|
||||
containsCount++;
|
||||
if (StringUtils.equalsIgnoreCase(model.getProtocol(), "http")) {
|
||||
Map<String, String> stepIdAndUrlMap = scenarioUrlMap.get(model.getMethod());
|
||||
if (stepIdAndUrlMap != null) {
|
||||
if (isUrlRepeatable) {
|
||||
String url = stepIdAndUrlMap.get(model.getId());
|
||||
if (StringUtils.isNotEmpty(url)) {
|
||||
boolean matchedUrl = MockApiUtils.isUrlMatch(model.getPath(), url);
|
||||
if (matchedUrl) {
|
||||
containsCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<String> scenarioUrlList = scenarioUrlMap.get(model.getMethod()).values();
|
||||
boolean matchedUrl = MockApiUtils.isUrlInList(model.getPath(), scenarioUrlList);
|
||||
if (matchedUrl) {
|
||||
containsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Map<String, String> stepIdAndUrlMap = scenarioUrlMap.get("MS_NOT_HTTP");
|
||||
if (stepIdAndUrlMap != null && stepIdAndUrlMap.containsKey(model.getId())) {
|
||||
containsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
coverage.setCoverate(containsCount);
|
||||
coverage.setNotCoverate(allEffectiveApiList.size() - containsCount);
|
||||
float coverageRageNumber = (float) containsCount * 100 / allEffectiveApiList.size();
|
||||
return coverageRageNumber;
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
coverage.setRateOfCoverage(df.format(coverageRageNumber) + "%");
|
||||
|
||||
return coverage;
|
||||
}
|
||||
|
||||
public ScenarioEnv getApiScenarioProjectId(String id) {
|
||||
|
@ -2157,17 +2194,25 @@ public class ApiAutomationService {
|
|||
}
|
||||
}
|
||||
|
||||
public Map<String, List<String>> selectScenarioUseUrlByProjectId(String projectId) {
|
||||
/**
|
||||
* 获取当前项目的场景下引用的接口路径和id
|
||||
*
|
||||
* @param projectId
|
||||
* @return <get/post, <step-id,url>>
|
||||
*/
|
||||
public Map<String, Map<String, String>> selectScenarioUseUrlByProjectId(String projectId) {
|
||||
List<ApiScenarioReferenceId> list = apiScenarioReferenceIdService.selectUrlByProjectId(projectId);
|
||||
Map<String, List<String>> returnMap = new HashMap<>();
|
||||
Map<String, Map<String, String>> returnMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
list.forEach(item -> {
|
||||
if (returnMap.containsKey(item.getMethod())) {
|
||||
returnMap.get(item.getMethod()).add(item.getUrl());
|
||||
String method = item.getMethod() == null ? "MS_NOT_HTTP" : item.getMethod();
|
||||
if (returnMap.containsKey(method)) {
|
||||
returnMap.get(method).put(item.getReferenceId(), item.getUrl());
|
||||
} else {
|
||||
List<String> urlList = new ArrayList<>();
|
||||
urlList.add(item.getUrl());
|
||||
returnMap.put(item.getMethod(), urlList);
|
||||
Map<String, String> urlMap = new HashMap() {{
|
||||
this.put(item.getReferenceId(), item.getUrl());
|
||||
}};
|
||||
returnMap.put(method, urlMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ import io.metersphere.notice.service.NoticeSendService;
|
|||
import io.metersphere.service.ApiCaseExecutionInfoService;
|
||||
import io.metersphere.service.ApiExecutionInfoService;
|
||||
import io.metersphere.track.dto.PlanReportCaseDTO;
|
||||
import io.metersphere.track.dto.TestPlanDTO;
|
||||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||
import io.metersphere.track.request.testcase.TrackCount;
|
||||
import io.metersphere.track.service.TestCaseReviewApiCaseService;
|
||||
import io.metersphere.track.service.TestPlanTestCaseService;
|
||||
|
@ -325,16 +323,19 @@ public class ApiDefinitionExecResultService {
|
|||
reportResult.setUserId(String.valueOf(dto.getExtendedParameters().get("userId")));
|
||||
}
|
||||
String status = item.isSuccess() ? "success" : "error";
|
||||
String triggerMode = "";
|
||||
if (reportResult != null) {
|
||||
status = reportResult.getStatus();
|
||||
triggerMode = reportResult.getTriggerMode();
|
||||
}
|
||||
|
||||
if (MapUtils.isNotEmpty(expandDTO.getAttachInfoMap())) {
|
||||
status = expandDTO.getStatus();
|
||||
}
|
||||
if (StringUtils.equalsAny(dto.getRunMode(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
|
||||
TestPlanApiCase apiCase = testPlanApiCaseMapper.selectByPrimaryKey(dto.getTestId());
|
||||
if (apiCase != null) {
|
||||
apiCaseExecutionInfoService.insertExecutionInfo(apiCase.getApiCaseId(), status);
|
||||
apiCaseExecutionInfoService.insertExecutionInfo(apiCase.getId(), status, triggerMode);
|
||||
apiCase.setStatus(status);
|
||||
apiCase.setUpdateTime(System.currentTimeMillis());
|
||||
testPlanApiCaseMapper.updateByPrimaryKeySelective(apiCase);
|
||||
|
@ -414,7 +415,7 @@ public class ApiDefinitionExecResultService {
|
|||
if (startTime == null) {
|
||||
return new ArrayList<>(0);
|
||||
} else {
|
||||
List<ExecutedCaseInfoResult> list = extApiDefinitionExecResultMapper.findFaliureCaseInfoByProjectIDAndExecuteTimeAndLimitNumber(projectId, startTime.getTime());
|
||||
List<ExecutedCaseInfoResult> list = extApiDefinitionExecResultMapper.findFaliureCaseInTestPlanByProjectIDAndExecuteTimeAndLimitNumber(projectId, startTime.getTime());
|
||||
|
||||
List<ExecutedCaseInfoResult> returnList = new ArrayList<>(limitNumber);
|
||||
|
||||
|
@ -423,17 +424,17 @@ public class ApiDefinitionExecResultService {
|
|||
//开始遍历查询TestPlan信息 --> 提供前台做超链接
|
||||
ExecutedCaseInfoResult item = list.get(i);
|
||||
|
||||
QueryTestPlanRequest planRequest = new QueryTestPlanRequest();
|
||||
planRequest.setProjectId(projectId);
|
||||
if ("scenario".equals(item.getCaseType())) {
|
||||
planRequest.setScenarioId(item.getTestCaseID());
|
||||
} else if ("apiCase".equals(item.getCaseType())) {
|
||||
planRequest.setApiId(item.getTestCaseID());
|
||||
} else if ("load".equals(item.getCaseType())) {
|
||||
planRequest.setLoadId(item.getTestCaseID());
|
||||
}
|
||||
List<TestPlanDTO> dtoList = extTestPlanMapper.selectTestPlanByRelevancy(planRequest);
|
||||
item.setTestPlanDTOList(dtoList);
|
||||
// QueryTestPlanRequest planRequest = new QueryTestPlanRequest();
|
||||
// planRequest.setProjectId(projectId);
|
||||
// if ("scenario".equals(item.getCaseType())) {
|
||||
// planRequest.setScenarioId(item.getTestCaseID());
|
||||
// } else if ("apiCase".equals(item.getCaseType())) {
|
||||
// planRequest.setApiId(item.getTestCaseID());
|
||||
// } else if ("load".equals(item.getCaseType())) {
|
||||
// planRequest.setLoadId(item.getTestCaseID());
|
||||
// }
|
||||
// List<TestPlanDTO> dtoList = extTestPlanMapper.selectTestPlanByRelevancy(planRequest);
|
||||
// item.setTestPlanDTOList(dtoList);
|
||||
returnList.add(item);
|
||||
} else {
|
||||
break;
|
||||
|
|
|
@ -310,7 +310,7 @@ public class ApiScenarioReportService {
|
|||
testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario);
|
||||
|
||||
//增加场景的运行记录
|
||||
scenarioExecutionInfoService.insertExecutionInfo(testPlanApiScenario.getApiScenarioId(), status);
|
||||
scenarioExecutionInfoService.insertExecutionInfo(testPlanApiScenario.getId(), status, report.getTriggerMode());
|
||||
|
||||
// 更新场景状态
|
||||
ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
|
||||
|
@ -434,7 +434,7 @@ public class ApiScenarioReportService {
|
|||
// 更新报告
|
||||
apiScenarioReportMapper.updateByPrimaryKey(report);
|
||||
//场景集合报告,按照集合报告的结果作为场景的最后执行结果
|
||||
scenarioExecutionInfoService.insertExecutionInfoByScenarioIds(report.getScenarioId(), report.getStatus());
|
||||
scenarioExecutionInfoService.insertExecutionInfoByScenarioIds(report.getScenarioId(), report.getStatus(), report.getTriggerMode());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.api.dto.ApiCaseEditRequest;
|
|||
import io.metersphere.api.dto.DeleteCheckResult;
|
||||
import io.metersphere.api.dto.JmxInfoDTO;
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.dto.datacount.response.ExecuteResultCountDTO;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.api.dto.definition.request.ElementUtil;
|
||||
import io.metersphere.api.dto.definition.request.MsTestPlan;
|
||||
|
@ -1186,4 +1187,7 @@ public class ApiTestCaseService {
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<ExecuteResultCountDTO> selectExecuteResultByProjectId(String projectId) {
|
||||
return extApiTestCaseMapper.selectExecuteResultByProjectId(projectId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ public class TestResultService {
|
|||
} else {
|
||||
ApiScenarioWithBLOBs apiScenario = apiScenarioMapper.selectByPrimaryKey(scenarioReport.getScenarioId());
|
||||
if (apiScenario != null) {
|
||||
scenarioExecutionInfoService.insertExecutionInfo(scenarioReport.getScenarioId(), scenarioReport.getStatus());
|
||||
scenarioExecutionInfoService.insertExecutionInfo(scenarioReport.getScenarioId(), scenarioReport.getStatus(), scenarioReport.getTriggerMode());
|
||||
environment = apiScenarioReportService.getEnvironment(apiScenario);
|
||||
userName = apiAutomationService.getUser(apiScenario.getUserId());
|
||||
principal = apiAutomationService.getUser(apiScenario.getPrincipal());
|
||||
|
|
|
@ -11,6 +11,8 @@ public class ApiCaseExecutionInfo implements Serializable {
|
|||
|
||||
private String result;
|
||||
|
||||
private String triggerMode;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
|
@ -314,6 +314,76 @@ public class ApiCaseExecutionInfoExample {
|
|||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeIsNull() {
|
||||
addCriterion("trigger_mode is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeIsNotNull() {
|
||||
addCriterion("trigger_mode is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeEqualTo(String value) {
|
||||
addCriterion("trigger_mode =", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotEqualTo(String value) {
|
||||
addCriterion("trigger_mode <>", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeGreaterThan(String value) {
|
||||
addCriterion("trigger_mode >", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("trigger_mode >=", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeLessThan(String value) {
|
||||
addCriterion("trigger_mode <", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeLessThanOrEqualTo(String value) {
|
||||
addCriterion("trigger_mode <=", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeLike(String value) {
|
||||
addCriterion("trigger_mode like", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotLike(String value) {
|
||||
addCriterion("trigger_mode not like", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeIn(List<String> values) {
|
||||
addCriterion("trigger_mode in", values, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotIn(List<String> values) {
|
||||
addCriterion("trigger_mode not in", values, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeBetween(String value1, String value2) {
|
||||
addCriterion("trigger_mode between", value1, value2, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotBetween(String value1, String value2) {
|
||||
addCriterion("trigger_mode not between", value1, value2, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIsNull() {
|
||||
addCriterion("create_time is null");
|
||||
return (Criteria) this;
|
||||
|
|
|
@ -11,6 +11,8 @@ public class ScenarioExecutionInfo implements Serializable {
|
|||
|
||||
private String result;
|
||||
|
||||
private String triggerMode;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
|
@ -314,6 +314,76 @@ public class ScenarioExecutionInfoExample {
|
|||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeIsNull() {
|
||||
addCriterion("trigger_mode is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeIsNotNull() {
|
||||
addCriterion("trigger_mode is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeEqualTo(String value) {
|
||||
addCriterion("trigger_mode =", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotEqualTo(String value) {
|
||||
addCriterion("trigger_mode <>", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeGreaterThan(String value) {
|
||||
addCriterion("trigger_mode >", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("trigger_mode >=", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeLessThan(String value) {
|
||||
addCriterion("trigger_mode <", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeLessThanOrEqualTo(String value) {
|
||||
addCriterion("trigger_mode <=", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeLike(String value) {
|
||||
addCriterion("trigger_mode like", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotLike(String value) {
|
||||
addCriterion("trigger_mode not like", value, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeIn(List<String> values) {
|
||||
addCriterion("trigger_mode in", values, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotIn(List<String> values) {
|
||||
addCriterion("trigger_mode not in", values, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeBetween(String value1, String value2) {
|
||||
addCriterion("trigger_mode between", value1, value2, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTriggerModeNotBetween(String value1, String value2) {
|
||||
addCriterion("trigger_mode not between", value1, value2, "triggerMode");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andCreateTimeIsNull() {
|
||||
addCriterion("create_time is null");
|
||||
return (Criteria) this;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||
<result column="source_id" jdbcType="VARCHAR" property="sourceId" />
|
||||
<result column="result" jdbcType="VARCHAR" property="result" />
|
||||
<result column="trigger_mode" jdbcType="VARCHAR" property="triggerMode" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
|
@ -66,7 +67,7 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, source_id, `result`, create_time
|
||||
id, source_id, `result`, trigger_mode, create_time
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.ApiCaseExecutionInfoExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -100,9 +101,9 @@
|
|||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.ApiCaseExecutionInfo">
|
||||
insert into api_case_execution_info (id, source_id, `result`,
|
||||
create_time)
|
||||
trigger_mode, create_time)
|
||||
values (#{id,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR}, #{result,jdbcType=VARCHAR},
|
||||
#{createTime,jdbcType=BIGINT})
|
||||
#{triggerMode,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiCaseExecutionInfo">
|
||||
insert into api_case_execution_info
|
||||
|
@ -116,6 +117,9 @@
|
|||
<if test="result != null">
|
||||
`result`,
|
||||
</if>
|
||||
<if test="triggerMode != null">
|
||||
trigger_mode,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
</if>
|
||||
|
@ -130,6 +134,9 @@
|
|||
<if test="result != null">
|
||||
#{result,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="triggerMode != null">
|
||||
#{triggerMode,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -153,6 +160,9 @@
|
|||
<if test="record.result != null">
|
||||
`result` = #{record.result,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.triggerMode != null">
|
||||
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -166,6 +176,7 @@
|
|||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
source_id = #{record.sourceId,jdbcType=VARCHAR},
|
||||
`result` = #{record.result,jdbcType=VARCHAR},
|
||||
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -180,6 +191,9 @@
|
|||
<if test="result != null">
|
||||
`result` = #{result,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="triggerMode != null">
|
||||
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -190,6 +204,7 @@
|
|||
update api_case_execution_info
|
||||
set source_id = #{sourceId,jdbcType=VARCHAR},
|
||||
`result` = #{result,jdbcType=VARCHAR},
|
||||
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
|
||||
create_time = #{createTime,jdbcType=BIGINT}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||
<result column="source_id" jdbcType="VARCHAR" property="sourceId" />
|
||||
<result column="result" jdbcType="VARCHAR" property="result" />
|
||||
<result column="trigger_mode" jdbcType="VARCHAR" property="triggerMode" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
|
@ -66,7 +67,7 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, source_id, `result`, create_time
|
||||
id, source_id, `result`, trigger_mode, create_time
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.ScenarioExecutionInfoExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -100,9 +101,9 @@
|
|||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.ScenarioExecutionInfo">
|
||||
insert into scenario_execution_info (id, source_id, `result`,
|
||||
create_time)
|
||||
trigger_mode, create_time)
|
||||
values (#{id,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR}, #{result,jdbcType=VARCHAR},
|
||||
#{createTime,jdbcType=BIGINT})
|
||||
#{triggerMode,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ScenarioExecutionInfo">
|
||||
insert into scenario_execution_info
|
||||
|
@ -116,6 +117,9 @@
|
|||
<if test="result != null">
|
||||
`result`,
|
||||
</if>
|
||||
<if test="triggerMode != null">
|
||||
trigger_mode,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
</if>
|
||||
|
@ -130,6 +134,9 @@
|
|||
<if test="result != null">
|
||||
#{result,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="triggerMode != null">
|
||||
#{triggerMode,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -153,6 +160,9 @@
|
|||
<if test="record.result != null">
|
||||
`result` = #{record.result,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.triggerMode != null">
|
||||
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -166,6 +176,7 @@
|
|||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
source_id = #{record.sourceId,jdbcType=VARCHAR},
|
||||
`result` = #{record.result,jdbcType=VARCHAR},
|
||||
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -180,6 +191,9 @@
|
|||
<if test="result != null">
|
||||
`result` = #{result,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="triggerMode != null">
|
||||
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
|
@ -190,6 +204,7 @@
|
|||
update scenario_execution_info
|
||||
set source_id = #{sourceId,jdbcType=VARCHAR},
|
||||
`result` = #{result,jdbcType=VARCHAR},
|
||||
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
|
||||
create_time = #{createTime,jdbcType=BIGINT}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
|
|
@ -30,6 +30,8 @@ public interface ExtApiDefinitionExecResultMapper {
|
|||
|
||||
List<ExecutedCaseInfoResult> findFaliureCaseInfoByProjectIDAndExecuteTimeAndLimitNumber(@Param("projectId") String projectId, @Param("startTimestamp") long startTimestamp);
|
||||
|
||||
List<ExecutedCaseInfoResult> findFaliureCaseInTestPlanByProjectIDAndExecuteTimeAndLimitNumber(@Param("projectId") String projectId, @Param("startTimestamp") long startTimestamp);
|
||||
|
||||
String selectExecResult(String resourceId);
|
||||
|
||||
ApiDefinitionExecResultWithBLOBs selectPlanApiMaxResultByTestIdAndType(String resourceId, String type);
|
||||
|
|
|
@ -46,6 +46,64 @@
|
|||
WHERE integrated_report_id = #{0}
|
||||
</select>
|
||||
|
||||
<select id="findFaliureCaseInTestPlanByProjectIDAndExecuteTimeAndLimitNumber"
|
||||
resultType="io.metersphere.api.dto.datacount.ExecutedCaseInfoResult">
|
||||
SELECT *
|
||||
FROM (SELECT testCase.testPlanCaseID AS testPlanCaseID,
|
||||
testCase.id AS id,
|
||||
testCase.testCaseName AS caseName,
|
||||
testCase.testPlanName AS testPlan,
|
||||
testCase.testPlanId AS testPlanId,
|
||||
caseErrorCountData.dataCountNumber AS failureTimes,
|
||||
'apiCase' AS caseType
|
||||
FROM (SELECT testPlanCase.id AS testPlanCaseID,
|
||||
apiCase.id AS id,
|
||||
apiCase.`name` AS testCaseName,
|
||||
testPlan.id AS testPlanId,
|
||||
testPlan.`name` AS testPlanName
|
||||
FROM api_test_case apiCase
|
||||
INNER JOIN test_plan_api_case testPlanCase ON testPlanCase.api_case_id = apiCase.id
|
||||
INNER JOIN test_plan testPlan ON testPlan.id = testPlanCase.test_plan_id
|
||||
WHERE (
|
||||
apiCase.`status` IS NULL
|
||||
OR apiCase.`status` != 'Trash'
|
||||
AND apiCase.project_id = #{projectId})) testCase
|
||||
INNER JOIN (SELECT executionInfo.source_id AS sourceId,
|
||||
COUNT(executionInfo.id) AS dataCountNumber
|
||||
FROM api_case_execution_info executionInfo
|
||||
INNER JOIN test_plan_api_case testPlanCase
|
||||
ON executionInfo.source_id = testPlanCase.id
|
||||
WHERE executionInfo.`result` = 'error'
|
||||
AND executionInfo.create_time > #{startTimestamp}
|
||||
GROUP BY source_id) caseErrorCountData
|
||||
ON caseErrorCountData.sourceId = testCase.testPlanCaseID
|
||||
UNION
|
||||
|
||||
SELECT scene.id AS testCaseID,
|
||||
scene.id AS id,
|
||||
scene.`name` AS caseName,
|
||||
apiScene.testPlanName AS testPlan,
|
||||
apiScene.testPlanId AS testPlanId,
|
||||
count(executionInfo.id) AS failureTimes,
|
||||
'scenario' AS caseType
|
||||
FROM scenario_execution_info executionInfo
|
||||
INNER JOIN (SELECT testPlanScenario.id,
|
||||
testPlanScenario.api_scenario_id,
|
||||
testPlan.id AS testPlanId,
|
||||
testPlan.`name` AS testPlanName
|
||||
FROM test_plan_api_scenario testPlanScenario
|
||||
INNER JOIN test_plan testPlan ON testPlan.id = testPlanScenario.test_plan_id) apiScene
|
||||
ON apiScene.id = executionInfo.source_id
|
||||
INNER JOIN api_scenario scene ON scene.id = apiScene.api_scenario_id
|
||||
|
||||
WHERE scene.project_id = #{projectId}
|
||||
AND scene.`status` != 'Trash'
|
||||
AND ( executionInfo.result = 'Error' OR executionInfo.result = 'Fail' )
|
||||
AND executionInfo.create_time >= #{startTimestamp}
|
||||
GROUP BY
|
||||
scene.id) showTable
|
||||
ORDER BY showTable.failureTimes DESC
|
||||
</select>
|
||||
<select id="findFaliureCaseInfoByProjectIDAndExecuteTimeAndLimitNumber"
|
||||
resultType="io.metersphere.api.dto.datacount.ExecutedCaseInfoResult">
|
||||
SELECT *
|
||||
|
|
|
@ -646,10 +646,10 @@
|
|||
</select>
|
||||
|
||||
<select id="selectEffectiveIdByProjectId" resultType="io.metersphere.base.domain.ApiDefinition">
|
||||
select id, path, method
|
||||
select id, path, method, protocol
|
||||
from api_definition
|
||||
WHERE project_id = #{0}
|
||||
AND status != 'Trash' AND protocol = 'HTTP' AND latest = 1
|
||||
AND status != 'Trash' AND latest = 1
|
||||
</select>
|
||||
|
||||
<select id="moduleCount" resultType="java.lang.Integer">
|
||||
|
@ -766,6 +766,27 @@
|
|||
</when>
|
||||
</choose>
|
||||
<include refid="filter"/>
|
||||
|
||||
<if test="request.apiCoverage == 'uncoverage' ">
|
||||
and
|
||||
api_definition.id not in (SELECT api_definition_id FROM api_test_case)
|
||||
and
|
||||
api_definition.id not in (
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash') AND reference_id is not null
|
||||
)
|
||||
</if>
|
||||
<if test="request.apiCoverage == 'coverage' ">
|
||||
and
|
||||
(
|
||||
api_definition.id in (SELECT api_definition_id FROM api_test_case)
|
||||
or
|
||||
api_definition.id in (
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash') and reference_id is not null
|
||||
)
|
||||
)
|
||||
</if>
|
||||
<if test="request.apiCaseCoverage == 'uncoverage' ">
|
||||
and api_definition.id not in
|
||||
(SELECT api_definition_id FROM api_test_case)
|
||||
|
@ -774,6 +795,20 @@
|
|||
and api_definition.id in
|
||||
(SELECT api_definition_id FROM api_test_case)
|
||||
</if>
|
||||
<if test="request.scenarioCoverage == 'uncoverage' ">
|
||||
and api_definition.id not in
|
||||
(
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash') and reference_id is not null
|
||||
)
|
||||
</if>
|
||||
<if test="request.scenarioCoverage == 'coverage' ">
|
||||
and api_definition.id in
|
||||
(
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash') and reference_id is not null
|
||||
)
|
||||
</if>
|
||||
<include refid="queryVersionCondition">
|
||||
<property name="versionTable" value="api_definition"/>
|
||||
</include>
|
||||
|
@ -836,6 +871,26 @@
|
|||
</when>
|
||||
</choose>
|
||||
<include refid="filter"/>
|
||||
<if test="request.apiCoverage == 'uncoverage' ">
|
||||
and
|
||||
api_definition.id not in (SELECT api_definition_id FROM api_test_case)
|
||||
and
|
||||
api_definition.id not in (
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash') AND reference_id is not null
|
||||
)
|
||||
</if>
|
||||
<if test="request.apiCoverage == 'coverage' ">
|
||||
and
|
||||
(
|
||||
api_definition.id in (SELECT api_definition_id FROM api_test_case)
|
||||
or
|
||||
api_definition.id in (
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash')
|
||||
)
|
||||
)
|
||||
</if>
|
||||
<if test="request.apiCaseCoverage == 'uncoverage' ">
|
||||
and api_definition.id not in
|
||||
(SELECT api_definition_id FROM api_test_case)
|
||||
|
@ -844,6 +899,20 @@
|
|||
and api_definition.id in
|
||||
(SELECT api_definition_id FROM api_test_case)
|
||||
</if>
|
||||
<if test="request.scenarioCoverage == 'uncoverage' ">
|
||||
and api_definition.id not in
|
||||
(
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash') and reference_id is not null
|
||||
)
|
||||
</if>
|
||||
<if test="request.scenarioCoverage == 'coverage' ">
|
||||
and api_definition.id in
|
||||
(
|
||||
SELECT reference_id FROM api_scenario_reference_id WHERE api_scenario_id in
|
||||
(SELECT id FROM api_scenario WHERE `status` is null or `status` != 'Trash') and reference_id is not null
|
||||
)
|
||||
</if>
|
||||
<include refid="queryVersionCondition">
|
||||
<property name="versionTable" value="api_definition"/>
|
||||
</include>
|
||||
|
|
|
@ -244,6 +244,14 @@
|
|||
<if test="request.createTime >0 ">
|
||||
AND api_scenario.create_time >= #{request.createTime}
|
||||
</if>
|
||||
<if test="request.scheduleCreateTime >0 ">
|
||||
AND api_scenario.id IN
|
||||
(
|
||||
SELECT resource_id FROM `schedule`
|
||||
WHERE `group` = 'API_SCENARIO_TEST'
|
||||
AND create_time >= #{request.scheduleCreateTime}
|
||||
)
|
||||
</if>
|
||||
<if test="request.ids != null and request.ids.size() > 0">
|
||||
AND api_scenario.id in
|
||||
<foreach collection="request.ids" item="itemId" separator="," open="(" close=")">
|
||||
|
@ -330,15 +338,39 @@
|
|||
<if test="request.filters == null || request.filters.size() == 0 ">
|
||||
and (api_scenario.status is null or api_scenario.status != 'Trash')
|
||||
</if>
|
||||
<if test="request.executeStatus == 'unExecute'">
|
||||
<if test="request.executeStatus == 'unExecute' and request.selectDataType != 'schedule' ">
|
||||
and api_scenario.last_result IS NULL
|
||||
</if>
|
||||
<if test="request.executeStatus == 'executeFailed'">
|
||||
<if test="request.executeStatus == 'executeFailed' and request.selectDataType != 'schedule' ">
|
||||
and api_scenario.last_result = 'Fail'
|
||||
</if>
|
||||
<if test="request.executeStatus == 'executePass'">
|
||||
<if test="request.executeStatus == 'executePass' and request.selectDataType != 'schedule' ">
|
||||
and api_scenario.last_result = 'Success'
|
||||
</if>
|
||||
<if test="request.executeStatus == 'fakeError' and request.selectDataType != 'schedule' ">
|
||||
and api_scenario.last_result = 'errorReportResult'
|
||||
</if>
|
||||
<if test="request.executeStatus == 'notSuccess' and request.selectDataType != 'schedule' ">
|
||||
and api_scenario.last_result IN ('Fail','errorReportResult')
|
||||
</if>
|
||||
<if test="request.executeStatus == 'executeFailed' and request.selectDataType == 'schedule' ">
|
||||
AND api_scenario.id IN
|
||||
(SELECT source_id FROM scenario_execution_info WHERE trigger_mode = 'SCHEDULE' AND result = 'Error')
|
||||
</if>
|
||||
<if test="request.executeStatus == 'executePass' and request.selectDataType == 'schedule' ">
|
||||
AND api_scenario.id IN
|
||||
(SELECT source_id FROM scenario_execution_info WHERE trigger_mode = 'SCHEDULE' AND result = 'Success')
|
||||
</if>
|
||||
<if test="request.executeStatus == 'fakeError' and request.selectDataType == 'schedule' ">
|
||||
AND api_scenario.id IN
|
||||
(SELECT source_id FROM scenario_execution_info WHERE trigger_mode = 'SCHEDULE' AND result =
|
||||
'errorReportResult')
|
||||
</if>
|
||||
<if test="request.executeStatus == 'notSuccess' and request.selectDataType == 'schedule' ">
|
||||
AND api_scenario.id IN
|
||||
(SELECT source_id FROM scenario_execution_info WHERE trigger_mode = 'SCHEDULE' AND result IN
|
||||
('errorReportResult','Error'))
|
||||
</if>
|
||||
<if test="request.notInTestPlan">
|
||||
and api_scenario.id not in (
|
||||
select pc.api_scenario_id
|
||||
|
@ -679,6 +711,12 @@
|
|||
<if test="request.executeStatus == 'executePass'">
|
||||
and api_scenario.last_result = 'Success'
|
||||
</if>
|
||||
<if test="request.executeStatus == 'fakeError'">
|
||||
and api_scenario.last_result = 'errorReportResult'
|
||||
</if>
|
||||
<if test="request.executeStatus == 'notSuccess'">
|
||||
and api_scenario.last_result IN ('Fail','errorReportResult')
|
||||
</if>
|
||||
<if test="request.notInTestPlan == true ">
|
||||
and api_scenario.id not in (
|
||||
select pc.api_scenario_id
|
||||
|
|
|
@ -2,9 +2,13 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtApiScenarioReferenceIdMapper">
|
||||
<select id="selectUrlByProjectId" resultType="io.metersphere.base.domain.ApiScenarioReferenceId">
|
||||
SELECT method,url from api_scenario_reference_id WHERE api_scenario_id in (
|
||||
SELECT id from api_scenario WHERE project_id = #{0}
|
||||
) AND url IS NOT NULL AND method IS NOT NULL;
|
||||
SELECT method, url, reference_id
|
||||
from api_scenario_reference_id
|
||||
WHERE api_scenario_id in (SELECT id
|
||||
from api_scenario
|
||||
WHERE project_id = #{0}
|
||||
AND latest = 1)
|
||||
AND reference_id IS NOT NULL;
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -169,7 +169,7 @@
|
|||
s_r.trigger_mode,
|
||||
s_r.execute_type,
|
||||
s_r.report_type
|
||||
FROM api_scenario_report s_r
|
||||
FROM api_scenario_report s_r
|
||||
<where>
|
||||
<if test="request.combine != null">
|
||||
<include refid="listCombine">
|
||||
|
@ -241,32 +241,32 @@
|
|||
|
||||
<select id="idList" resultType="java.lang.String">
|
||||
select r.id from (
|
||||
SELECT s_r.name AS test_name,
|
||||
s_r.end_time,
|
||||
s_r.user_id,
|
||||
s_r.name,
|
||||
s_r.id,
|
||||
s_r.project_id,
|
||||
s_r.create_time,
|
||||
s_r.update_time,
|
||||
s_r.status,
|
||||
s_r.trigger_mode,
|
||||
s_r.execute_type,
|
||||
s_r.report_type
|
||||
SELECT s_r.name AS test_name,
|
||||
s_r.end_time,
|
||||
s_r.user_id,
|
||||
s_r.name,
|
||||
s_r.id,
|
||||
s_r.project_id,
|
||||
s_r.create_time,
|
||||
s_r.update_time,
|
||||
s_r.status,
|
||||
s_r.trigger_mode,
|
||||
s_r.execute_type,
|
||||
s_r.report_type
|
||||
FROM api_scenario_report s_r
|
||||
union all
|
||||
select a_r.name as test_name,
|
||||
a_r.end_time,
|
||||
a_r.user_id,
|
||||
a_r.name,
|
||||
a_r.id,
|
||||
a_r.project_id,
|
||||
a_r.create_time,
|
||||
a_r.create_time as update_time,
|
||||
a_r.status,
|
||||
a_r.trigger_mode,
|
||||
'Saved' as execute_type,
|
||||
'API_INDEPENDENT' as report_type
|
||||
a_r.end_time,
|
||||
a_r.user_id,
|
||||
a_r.name,
|
||||
a_r.id,
|
||||
a_r.project_id,
|
||||
a_r.create_time,
|
||||
a_r.create_time as update_time,
|
||||
a_r.status,
|
||||
a_r.trigger_mode,
|
||||
'Saved' as execute_type,
|
||||
'API_INDEPENDENT' as report_type
|
||||
from api_definition_exec_result a_r
|
||||
where a_r.integrated_report_id is null or a_r.integrated_report_id = 'null'
|
||||
) r
|
||||
|
@ -357,27 +357,24 @@
|
|||
|
||||
<select id="countByProjectIdAndCreateAndByScheduleInThisWeek" resultType="java.lang.Long">
|
||||
SELECT count(ar.id) AS countNumber
|
||||
FROM api_scenario_report ar
|
||||
INNER JOIN (
|
||||
SELECT acitem.`name`, acitem.id
|
||||
FROM api_scenario acitem
|
||||
INNER JOIN `schedule` sc ON acitem.id = sc.resource_id and latest = 1
|
||||
) ac on ar.scenario_id = ac.id
|
||||
WHERE ar.project_id = #{projectId}
|
||||
AND ar.trigger_mode = 'SCHEDULE'
|
||||
AND ar.create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
||||
FROM scenario_execution_info ar
|
||||
WHERE trigger_mode = 'SCHEDULE'
|
||||
AND source_id IN (SELECT id
|
||||
FROM api_scenario
|
||||
WHERE project_id = #{projectId}
|
||||
AND latest = 1)
|
||||
AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
||||
|
||||
</select>
|
||||
|
||||
<select id="countByProjectIdGroupByExecuteResult" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
|
||||
SELECT count(ar.id) AS countNumber, ar.status AS groupField
|
||||
FROM api_scenario_report ar
|
||||
INNER JOIN (
|
||||
SELECT acitem.`name`, acitem.id
|
||||
FROM api_scenario acitem
|
||||
INNER JOIN `schedule` sc ON acitem.id = sc.resource_id and latest = 1
|
||||
) ac on ar.scenario_id = ac.id
|
||||
WHERE ar.project_id = #{projectId}
|
||||
AND ar.trigger_mode = 'SCHEDULE'
|
||||
SELECT count(id) AS countNumber, result AS groupField
|
||||
FROM scenario_execution_info ar
|
||||
WHERE trigger_mode = 'SCHEDULE'
|
||||
AND source_id IN (SELECT id
|
||||
FROM api_scenario
|
||||
WHERE project_id = #{projectId}
|
||||
AND latest = 1)
|
||||
GROUP BY groupField;
|
||||
</select>
|
||||
<select id="selectLastReportByIds" resultType="io.metersphere.base.domain.ApiScenarioReport">
|
||||
|
@ -410,7 +407,7 @@
|
|||
and scenario_id = #{scenarioId}
|
||||
and id != #{nowId}
|
||||
ORDER BY create_time desc
|
||||
LIMIT 5, 1
|
||||
LIMIT 5, 1
|
||||
</select>
|
||||
|
||||
<select id="countByApiScenarioId" resultType="io.metersphere.dto.ApiReportCountDTO">
|
||||
|
@ -429,7 +426,8 @@
|
|||
and t.execute_type != 'Debug'
|
||||
and t.execute_type != 'Marge'
|
||||
and t.project_id = #{projectId}
|
||||
and t.`STATUS` in ('running', 'waiting')
|
||||
and t.`STATUS` in ('running'
|
||||
, 'waiting')
|
||||
|
||||
</select>
|
||||
|
||||
|
@ -455,8 +453,9 @@
|
|||
</foreach>
|
||||
</update>
|
||||
|
||||
<select id="findByProjectIds" resultType="io.metersphere.base.domain.ApiScenarioReport" parameterType="java.lang.String">
|
||||
select actuator ,id from api_scenario_report where status in ("running","starting","waiting") and project_id in
|
||||
<select id="findByProjectIds" resultType="io.metersphere.base.domain.ApiScenarioReport"
|
||||
parameterType="java.lang.String">
|
||||
select actuator ,id from api_scenario_report where status in ("running","starting","waiting") and project_id in
|
||||
<foreach collection="request.projects" item="id" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.dto.datacount.response.ExecuteResultCountDTO;
|
||||
import io.metersphere.api.dto.definition.*;
|
||||
import io.metersphere.base.domain.ApiDefinition;
|
||||
import io.metersphere.base.domain.ApiTestCase;
|
||||
|
@ -80,4 +81,6 @@ public interface ExtApiTestCaseMapper {
|
|||
int toBeUpdateCase(@Param("ids") List<String> ids, @Param("toBeUpdate") Boolean toBeUpdate);
|
||||
|
||||
int countById(String resourceID);
|
||||
|
||||
List<ExecuteResultCountDTO> selectExecuteResultByProjectId(String projectId);
|
||||
}
|
||||
|
|
|
@ -428,6 +428,21 @@
|
|||
#{nodeId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="request.redirectFilter == 'unexecuteCount' ">
|
||||
and (t1.status IS NULL or t1.status = '')
|
||||
</if>
|
||||
<if test="request.redirectFilter == 'executionPassCount' ">
|
||||
and t1.status = 'success'
|
||||
</if>
|
||||
<if test="request.redirectFilter == 'executionFailedCount' ">
|
||||
and t1.status = 'error'
|
||||
</if>
|
||||
<if test="request.redirectFilter == 'fakeErrorCount' ">
|
||||
and t1.status = 'errorReportResult'
|
||||
</if>
|
||||
<if test="request.redirectFilter == 'notSuccessCount' ">
|
||||
and t1.status IN ('error','errorReportResult')
|
||||
</if>
|
||||
<if test="request.filters != null and request.filters.size() > 0">
|
||||
<foreach collection="request.filters.entrySet()" index="key" item="values">
|
||||
<if test="values != null and values.size() > 0">
|
||||
|
@ -913,4 +928,17 @@
|
|||
from api_test_case
|
||||
where id = #{0}
|
||||
</select>
|
||||
|
||||
<select id="selectExecuteResultByProjectId"
|
||||
resultType="io.metersphere.api.dto.datacount.response.ExecuteResultCountDTO">
|
||||
SELECT status AS execResult, count(id) AS `count`
|
||||
FROM api_test_case
|
||||
WHERE project_id = #{0}
|
||||
AND (`status` IS NULL OR `status` != 'Trash')
|
||||
AND api_definition_id IN (SELECT id
|
||||
FROM api_definition
|
||||
WHERE project_id = #{0}
|
||||
AND latest = 1)
|
||||
GROUP BY `status`
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -2,7 +2,7 @@ package io.metersphere.commons.constants;
|
|||
|
||||
public enum ExecuteResult {
|
||||
//误报状态
|
||||
ERROR_REPORT_RESULT("errorReportResult"),
|
||||
ERROR_REPORT_RESULT("errorReportResult"), ERROR_REPORT("errorReport"),
|
||||
//停止状态
|
||||
STOP("STOP"),
|
||||
//接口执行状态(兼容旧数据)
|
||||
|
|
|
@ -30,8 +30,8 @@ public class ProjectApplicationController {
|
|||
}
|
||||
|
||||
@GetMapping("/get/{projectId}/{type}")
|
||||
public ProjectApplication getProjectApplication(@PathVariable String projectId,@PathVariable String type) {
|
||||
return projectApplicationService.getProjectApplication(projectId,type);
|
||||
public ProjectApplication getProjectApplication(@PathVariable String projectId, @PathVariable String type) {
|
||||
return projectApplicationService.getProjectApplication(projectId, type);
|
||||
}
|
||||
|
||||
@GetMapping("/get/config/{projectId}")
|
||||
|
|
|
@ -23,13 +23,14 @@ public class ApiCaseExecutionInfoService {
|
|||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
|
||||
@Lazy
|
||||
public void insertExecutionInfo(String apiCaseId, String result) {
|
||||
public void insertExecutionInfo(String apiCaseId, String result, String triggerMode) {
|
||||
if (StringUtils.isNotEmpty(apiCaseId) && StringUtils.isNotEmpty(result)) {
|
||||
ApiCaseExecutionInfo executionInfo = new ApiCaseExecutionInfo();
|
||||
executionInfo.setResult(result);
|
||||
executionInfo.setSourceId(apiCaseId);
|
||||
executionInfo.setId(UUID.randomUUID().toString());
|
||||
executionInfo.setCreateTime(System.currentTimeMillis());
|
||||
executionInfo.setTriggerMode(triggerMode);
|
||||
apiCaseExecutionInfoMapper.insert(executionInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,23 +50,24 @@ public class ApiExecutionInfoService {
|
|||
} else {
|
||||
boolean isApiCase = extApiTestCaseMapper.countById(resourceID) > 0;
|
||||
if (isApiCase) {
|
||||
this.insertApiCaseExecutionInfo(resourceID, result.getStatus());
|
||||
this.insertApiCaseExecutionInfo(resourceID, result.getStatus(), result.getTriggerMode());
|
||||
} else {
|
||||
String apiCaseIdInTestPlan = extTestPlanApiCaseMapper.getApiTestCaseIdById(resourceID);
|
||||
if (StringUtils.isNotEmpty(apiCaseIdInTestPlan)) {
|
||||
this.insertApiCaseExecutionInfo(apiCaseIdInTestPlan, result.getStatus());
|
||||
this.insertApiCaseExecutionInfo(resourceID, result.getStatus(), result.getTriggerMode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void insertApiCaseExecutionInfo(String resourceID, String status) {
|
||||
private void insertApiCaseExecutionInfo(String resourceID, String status, String triggerMode) {
|
||||
ApiCaseExecutionInfo info = new ApiCaseExecutionInfo();
|
||||
info.setId(UUID.randomUUID().toString());
|
||||
info.setSourceId(resourceID);
|
||||
info.setCreateTime(System.currentTimeMillis());
|
||||
info.setResult(status);
|
||||
info.setTriggerMode(triggerMode);
|
||||
apiCaseExecutionInfoMapper.insert(info);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,34 +22,29 @@ public class ScenarioExecutionInfoService {
|
|||
private ScenarioExecutionInfoMapper scenarioExecutionInfoMapper;
|
||||
|
||||
@Lazy
|
||||
public void insertExecutionInfo(String scenarioId, String result) {
|
||||
public void insertExecutionInfo(String scenarioId, String result, String triggerMode) {
|
||||
if (StringUtils.isNotEmpty(scenarioId) && StringUtils.isNotEmpty(result)) {
|
||||
ScenarioExecutionInfo executionInfo = new ScenarioExecutionInfo();
|
||||
executionInfo.setResult(result);
|
||||
executionInfo.setSourceId(scenarioId);
|
||||
executionInfo.setId(UUID.randomUUID().toString());
|
||||
executionInfo.setCreateTime(System.currentTimeMillis());
|
||||
executionInfo.setTriggerMode(triggerMode);
|
||||
scenarioExecutionInfoMapper.insert(executionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public void insertExecutionInfoByScenarioIds(String scenarioIdJsonString, String status) {
|
||||
public void insertExecutionInfoByScenarioIds(String scenarioIdJsonString, String status, String triggerMode) {
|
||||
try {
|
||||
List<String> scenarioIdList = JSONArray.parseArray(scenarioIdJsonString, String.class);
|
||||
for (String scenarioId : scenarioIdList) {
|
||||
this.insertExecutionInfo(scenarioId, status);
|
||||
this.insertExecutionInfo(scenarioId, status, triggerMode);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("解析场景ID的JSON" + scenarioIdJsonString + "失败!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteByScenarioId(String resourceId) {
|
||||
ScenarioExecutionInfoExample example = new ScenarioExecutionInfoExample();
|
||||
example.createCriteria().andSourceIdEqualTo(resourceId);
|
||||
scenarioExecutionInfoMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public void deleteByScenarioIdList(List<String> resourceIdList) {
|
||||
if (CollectionUtils.isNotEmpty(resourceIdList)) {
|
||||
ScenarioExecutionInfoExample example = new ScenarioExecutionInfoExample();
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
<!-- 此处指定生成针对MyBatis3的DAO -->
|
||||
<context id="mysql" targetRuntime="MyBatis3">
|
||||
<!-- 字段带`,解决列表跟关键字冲突问题 -->
|
||||
<property name="autoDelimitKeywords" value="true" />
|
||||
<property name="beginningDelimiter" value="`" />
|
||||
<property name="endingDelimiter" value="`" />
|
||||
<property name="autoDelimitKeywords" value="true"/>
|
||||
<property name="beginningDelimiter" value="`"/>
|
||||
<property name="endingDelimiter" value="`"/>
|
||||
|
||||
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
|
||||
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
|
||||
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
|
||||
<!-- Lombok插件 -->
|
||||
<plugin type="com.itfsw.mybatis.generator.plugins.LombokPlugin">
|
||||
<!-- @Data 默认开启,同时插件会对子类自动附加@EqualsAndHashCode(callSuper = true),@ToString(callSuper = true) -->
|
||||
|
@ -71,22 +71,23 @@
|
|||
<!--<table tableName="test_plan"/>-->
|
||||
<!--<table tableName="api_scenario_report"/>-->
|
||||
<!--<table tableName="test_case_review"/>-->
|
||||
<!-- <table tableName="project">-->
|
||||
<!-- <ignoreColumn column="custom_num"/>-->
|
||||
<!-- <ignoreColumn column="scenario_custom_num"/>-->
|
||||
<!-- <ignoreColumn column="mock_tcp_port"/>-->
|
||||
<!-- <ignoreColumn column="is_mock_tcp_open"/>-->
|
||||
<!-- <ignoreColumn column="api_quick"/>-->
|
||||
<!-- <ignoreColumn column="case_public"/>-->
|
||||
<!-- <ignoreColumn column="clean_track_report"/>-->
|
||||
<!-- <ignoreColumn column="clean_track_report_expr"/>-->
|
||||
<!-- <ignoreColumn column="clean_api_report"/>-->
|
||||
<!-- <ignoreColumn column="clean_api_report_expr"/>-->
|
||||
<!-- <ignoreColumn column="clean_load_report"/>-->
|
||||
<!-- <ignoreColumn column="clean_load_report_expr"/>-->
|
||||
<!-- <ignoreColumn column="repeatable"/>-->
|
||||
<!-- </table>-->
|
||||
<table tableName="api_test_case"/>
|
||||
<!-- <table tableName="project">-->
|
||||
<!-- <ignoreColumn column="custom_num"/>-->
|
||||
<!-- <ignoreColumn column="scenario_custom_num"/>-->
|
||||
<!-- <ignoreColumn column="mock_tcp_port"/>-->
|
||||
<!-- <ignoreColumn column="is_mock_tcp_open"/>-->
|
||||
<!-- <ignoreColumn column="api_quick"/>-->
|
||||
<!-- <ignoreColumn column="case_public"/>-->
|
||||
<!-- <ignoreColumn column="clean_track_report"/>-->
|
||||
<!-- <ignoreColumn column="clean_track_report_expr"/>-->
|
||||
<!-- <ignoreColumn column="clean_api_report"/>-->
|
||||
<!-- <ignoreColumn column="clean_api_report_expr"/>-->
|
||||
<!-- <ignoreColumn column="clean_load_report"/>-->
|
||||
<!-- <ignoreColumn column="clean_load_report_expr"/>-->
|
||||
<!-- <ignoreColumn column="repeatable"/>-->
|
||||
<!-- </table>-->
|
||||
<table tableName="api_case_execution_info"/>
|
||||
<table tableName="scenario_execution_info"/>
|
||||
<!--<table tableName="enterprise_test_report_send_record"/>-->
|
||||
<!--<table tableName="test_case_review_api_case"/>
|
||||
<table tableName="test_case_review_load"/>
|
||||
|
@ -110,7 +111,7 @@
|
|||
|
||||
|
||||
<!-- 表名和关键字冲突-->
|
||||
<!-- <table tableName="group" delimitIdentifiers="true"></table>-->
|
||||
<!-- <table tableName="group" delimitIdentifiers="true"></table>-->
|
||||
|
||||
</context>
|
||||
</generatorConfiguration>
|
||||
|
|
|
@ -176,6 +176,9 @@ export default {
|
|||
sessionStorage.setItem(PROJECT_ID, projectId);
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.selectNodeIds = [];
|
||||
},
|
||||
mounted() {
|
||||
this.getProject();
|
||||
this.getTrashCase();
|
||||
|
@ -707,7 +710,13 @@ export default {
|
|||
gotoTurn(resource, workspaceId, isTurnSpace) {
|
||||
let automationData = this.$router.resolve({
|
||||
name: 'ApiAutomation',
|
||||
params: {redirectID: getUUID(), dataType: "scenario", dataSelectRange: 'edit:' + resource.id, projectId: resource.projectId, workspaceId: workspaceId}
|
||||
params: {
|
||||
redirectID: getUUID(),
|
||||
dataType: "scenario",
|
||||
dataSelectRange: 'edit:' + resource.id,
|
||||
projectId: resource.projectId,
|
||||
workspaceId: workspaceId
|
||||
}
|
||||
});
|
||||
if (isTurnSpace) {
|
||||
window.open(automationData.href, '_blank');
|
||||
|
|
|
@ -310,7 +310,15 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {downloadFile, getCurrentProjectID, getUUID, hasLicense, hasPermission, objToStrMap, strMapToObj} from "@/common/js/utils";
|
||||
import {
|
||||
downloadFile,
|
||||
getCurrentProjectID,
|
||||
getUUID,
|
||||
hasLicense,
|
||||
hasPermission,
|
||||
objToStrMap,
|
||||
strMapToObj
|
||||
} from "@/common/js/utils";
|
||||
import {API_SCENARIO_CONFIGS} from "@/business/components/common/components/search/search-components";
|
||||
import {API_SCENARIO_LIST} from "../../../../../common/js/constants";
|
||||
|
||||
|
@ -430,6 +438,7 @@ export default {
|
|||
schedule: {},
|
||||
tableData: [],
|
||||
selectDataRange: 'all',
|
||||
selectDataType: 'all',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
|
@ -722,20 +731,27 @@ export default {
|
|||
//检查是否只查询本周数据
|
||||
this.condition.selectThisWeedData = false;
|
||||
this.condition.executeStatus = null;
|
||||
this.isSelectThissWeekData();
|
||||
this.condition.selectDataType = this.selectDataType;
|
||||
this.isRedirectFilter();
|
||||
switch (this.selectDataRange) {
|
||||
case 'thisWeekCount':
|
||||
this.condition.selectThisWeedData = true;
|
||||
break;
|
||||
case 'unExecute':
|
||||
case 'unexecuteCount':
|
||||
this.condition.executeStatus = 'unExecute';
|
||||
break;
|
||||
case 'executeFailed':
|
||||
case 'executionFailedCount':
|
||||
this.condition.executeStatus = 'executeFailed';
|
||||
break;
|
||||
case 'executePass':
|
||||
case 'fakeErrorCount':
|
||||
this.condition.executeStatus = 'fakeError';
|
||||
break;
|
||||
case 'executionPassCount':
|
||||
this.condition.executeStatus = 'executePass';
|
||||
break;
|
||||
case 'notSuccessCount':
|
||||
this.condition.executeStatus = 'notSuccess';
|
||||
break;
|
||||
}
|
||||
if (this.selectDataRange != null) {
|
||||
let selectParamArr = this.selectDataRange.split(":");
|
||||
|
@ -1153,9 +1169,16 @@ export default {
|
|||
this.showReportId = row.reportId;
|
||||
},
|
||||
//判断是否只显示本周的数据。 从首页跳转过来的请求会带有相关参数
|
||||
isSelectThissWeekData() {
|
||||
let dataRange = this.$route.params.dataSelectRange;
|
||||
this.selectDataRange = dataRange;
|
||||
isRedirectFilter() {
|
||||
this.selectDataRange = "all";
|
||||
this.selectDataType = "all";
|
||||
let routeParamObj = this.$route.params.paramObj;
|
||||
if (routeParamObj) {
|
||||
let dataRange = routeParamObj.dataSelectRange;
|
||||
let dataType = routeParamObj.dataType;
|
||||
this.selectDataRange = dataRange;
|
||||
this.selectDataType = dataType;
|
||||
}
|
||||
},
|
||||
changeSelectDataRangeAll() {
|
||||
this.$emit("changeSelectDataRangeAll");
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="true"
|
||||
:queryDataType="queryDataType"
|
||||
:selectDataRange="selectDataRange"
|
||||
:is-read-only="isReadOnly"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
|
@ -81,7 +80,6 @@
|
|||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="true"
|
||||
:queryDataType="queryDataType"
|
||||
:is-read-only="isReadOnly"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
@handleCase="handleCase"
|
||||
|
@ -122,7 +120,6 @@
|
|||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="false"
|
||||
:queryDataType="queryDataType"
|
||||
:selectDataRange="selectDataRange"
|
||||
:is-read-only="isReadOnly"
|
||||
@runTest="runTest"
|
||||
|
@ -146,7 +143,6 @@
|
|||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="false"
|
||||
:queryDataType="queryDataType"
|
||||
:is-read-only="isReadOnly"
|
||||
@changeSelectDataRangeAll="changeSelectDataRangeAll"
|
||||
@handleCase="handleCase"
|
||||
|
@ -271,20 +267,12 @@ import MsEditCompleteContainer from "./components/EditCompleteContainer";
|
|||
import MsEnvironmentSelect from "./components/case/MsEnvironmentSelect";
|
||||
import {PROJECT_ID, WORKSPACE_ID} from "@/common/js/constants";
|
||||
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const VersionSelect = requireComponent.keys().length > 0 ? requireComponent("./version/VersionSelect.vue") : {};
|
||||
|
||||
|
||||
export default {
|
||||
name: "ApiDefinition",
|
||||
computed: {
|
||||
queryDataType: function () {
|
||||
let routeParam = this.$route.params.dataType;
|
||||
let redirectIDParam = this.$route.params.redirectID;
|
||||
this.changeRedirectParam(redirectIDParam);
|
||||
return routeParam;
|
||||
},
|
||||
isReadOnly() {
|
||||
return false;
|
||||
},
|
||||
|
@ -367,29 +355,31 @@ export default {
|
|||
},
|
||||
activated() {
|
||||
this.selectNodeIds = [];
|
||||
let dataRange = this.$route.params.dataSelectRange;
|
||||
if (dataRange && dataRange.length > 0) {
|
||||
this.activeDom = 'middle';
|
||||
}
|
||||
let dataType = this.$route.params.dataType;
|
||||
if (dataType) {
|
||||
if (dataType === "api") {
|
||||
this.activeDom = 'left';
|
||||
} else {
|
||||
let routeParamObj = this.$route.params.paramObj;
|
||||
if (routeParamObj) {
|
||||
let dataRange = routeParamObj.dataSelectRange;
|
||||
if (dataRange && dataRange.length > 0) {
|
||||
this.activeDom = 'middle';
|
||||
}
|
||||
}
|
||||
|
||||
if (this.$route.params.dataSelectRange) {
|
||||
let item = JSON.parse(JSON.stringify(this.$route.params.dataSelectRange)).param;
|
||||
if (item !== undefined) {
|
||||
let type = item.taskGroup.toString();
|
||||
if (type === "SWAGGER_IMPORT") {
|
||||
this.handleTabsEdit(this.$t('api_test.api_import.timing_synchronization'), 'SCHEDULE');
|
||||
this.param = item;
|
||||
let dataType = routeParamObj.dataType;
|
||||
if (dataType) {
|
||||
if (dataType === "api") {
|
||||
this.activeDom = 'left';
|
||||
} else {
|
||||
this.activeDom = 'middle';
|
||||
}
|
||||
}
|
||||
if (routeParamObj.dataSelectRange) {
|
||||
let item = JSON.parse(JSON.stringify(routeParamObj.dataSelectRange)).param;
|
||||
if (item !== undefined) {
|
||||
let type = item.taskGroup.toString();
|
||||
if (type === "SWAGGER_IMPORT") {
|
||||
this.handleTabsEdit(this.$t('api_test.api_import.timing_synchronization'), 'SCHEDULE');
|
||||
this.param = item;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -420,22 +410,29 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
let workspaceId = this.$route.params.workspaceId;
|
||||
if (workspaceId) {
|
||||
sessionStorage.setItem(WORKSPACE_ID, workspaceId);
|
||||
} else {
|
||||
if (this.$route.query.workspaceId) {
|
||||
workspaceId = this.$route.query.workspaceId;
|
||||
let routeParamObj = this.$route.params.paramObj;
|
||||
if (routeParamObj) {
|
||||
let workspaceId = routeParamObj.workspaceId;
|
||||
if (workspaceId) {
|
||||
sessionStorage.setItem(WORKSPACE_ID, workspaceId);
|
||||
} else {
|
||||
if (this.$route.query.workspaceId) {
|
||||
workspaceId = this.$route.query.workspaceId;
|
||||
sessionStorage.setItem(WORKSPACE_ID, workspaceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
let projectId = this.$route.params.projectId;
|
||||
if (projectId) {
|
||||
sessionStorage.setItem(PROJECT_ID, projectId);
|
||||
} else {
|
||||
if (this.$route.query.projectId) {
|
||||
projectId = this.$route.query.projectId;
|
||||
sessionStorage.setItem(PROJECT_ID, this.$route.query.projectId);
|
||||
let projectId = routeParamObj.projectId;
|
||||
if (projectId) {
|
||||
sessionStorage.setItem(PROJECT_ID, projectId);
|
||||
} else {
|
||||
if (this.$route.query.projectId) {
|
||||
projectId = this.$route.query.projectId;
|
||||
sessionStorage.setItem(PROJECT_ID, projectId);
|
||||
}
|
||||
}
|
||||
// 通知过来的数据跳转到编辑
|
||||
if (this.routeParamObj.caseId) {
|
||||
this.activeDom = 'middle';
|
||||
}
|
||||
}
|
||||
this.getEnv();
|
||||
|
@ -714,16 +711,19 @@ export default {
|
|||
this.handleTabsEdit(this.$t('api_test.definition.request.fast_debug'), "debug", id);
|
||||
},
|
||||
init() {
|
||||
let dataRange = this.$route.params.dataSelectRange;
|
||||
let dataType = this.$route.params.dataType;
|
||||
if (dataRange) {
|
||||
let selectParamArr = dataRange.split("edit:");
|
||||
if (selectParamArr.length === 2) {
|
||||
let scenarioId = selectParamArr[1];
|
||||
if (dataType === 'api') {
|
||||
this.$get('/api/definition/get/' + scenarioId, (response) => {
|
||||
this.editApi(response.data);
|
||||
});
|
||||
let routeParamObj = this.$route.params.paramObj;
|
||||
if (routeParamObj) {
|
||||
let dataRange = routeParamObj.dataSelectRange;
|
||||
let dataType = routeParamObj.dataType;
|
||||
if (dataRange) {
|
||||
let selectParamArr = dataRange.split("edit:");
|
||||
if (selectParamArr.length === 2) {
|
||||
let scenarioId = selectParamArr[1];
|
||||
if (dataType === 'api') {
|
||||
this.$get('/api/definition/get/' + scenarioId, (response) => {
|
||||
this.editApi(response.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +872,9 @@ export default {
|
|||
this.nodeTree = data;
|
||||
},
|
||||
changeSelectDataRangeAll(tableType) {
|
||||
this.$route.params.dataSelectRange = 'all';
|
||||
if (this.$route.params.paramObj) {
|
||||
this.$route.params.paramObj.dataSelectRange = 'all';
|
||||
}
|
||||
},
|
||||
enableTrash(data) {
|
||||
this.initApiTableOpretion = "trashEnable";
|
||||
|
|
|
@ -758,12 +758,15 @@ export default {
|
|||
if (this.currentProtocol != null) {
|
||||
this.condition.protocol = this.currentProtocol;
|
||||
}
|
||||
//检查是否只查询本周数据
|
||||
this.isSelectThisWeekData();
|
||||
//检查是否有跳转数据筛选
|
||||
this.isRedirectFilter();
|
||||
this.condition.selectThisWeedData = false;
|
||||
this.condition.id = null;
|
||||
this.condition.redirectFilter = null;
|
||||
if (this.selectDataRange == 'thisWeekCount') {
|
||||
this.condition.selectThisWeedData = true;
|
||||
} else if (this.selectDataRange === 'executionPassCount' || this.selectDataRange === 'unexecuteCount' || this.selectDataRange === 'executionFailedCount' || this.selectDataRange === 'fakeErrorCount' || this.selectDataRange === 'notSuccessCount') {
|
||||
this.condition.redirectFilter = this.selectDataRange;
|
||||
} else if (this.selectDataRange != null) {
|
||||
let selectParamArr = this.selectDataRange.split(":");
|
||||
if (selectParamArr.length === 2) {
|
||||
|
@ -1124,12 +1127,15 @@ export default {
|
|||
}
|
||||
},
|
||||
//判断是否只显示本周的数据。 从首页跳转过来的请求会带有相关参数
|
||||
isSelectThisWeekData() {
|
||||
isRedirectFilter() {
|
||||
this.selectDataRange = "all";
|
||||
let routeParam = this.$route.params.dataSelectRange;
|
||||
let dataType = this.$route.params.dataType;
|
||||
if (dataType === 'apiTestCase') {
|
||||
this.selectDataRange = routeParam;
|
||||
let routeParamObj = this.$route.params.paramObj;
|
||||
if (routeParamObj) {
|
||||
let routeParam = routeParamObj.dataSelectRange;
|
||||
let dataType = routeParamObj.dataType;
|
||||
if (dataType === 'apiTestCase') {
|
||||
this.selectDataRange = routeParam;
|
||||
}
|
||||
}
|
||||
},
|
||||
changeSelectDataRangeAll() {
|
||||
|
|
|
@ -617,16 +617,29 @@ export default {
|
|||
this.getSelectDataRange();
|
||||
this.condition.selectThisWeedData = false;
|
||||
this.condition.apiCaseCoverage = null;
|
||||
this.condition.apiCoverage = null;
|
||||
switch (this.selectDataRange) {
|
||||
case 'thisWeekCount':
|
||||
this.condition.selectThisWeedData = true;
|
||||
break;
|
||||
case 'uncoverage':
|
||||
case 'notCoverate':
|
||||
this.condition.apiCoverage = 'uncoverage';
|
||||
break;
|
||||
case 'coverate':
|
||||
this.condition.apiCoverage = 'coverage';
|
||||
break;
|
||||
case 'unCoverageTestCase':
|
||||
this.condition.apiCaseCoverage = 'uncoverage';
|
||||
break;
|
||||
case 'coverage':
|
||||
case 'coverageTestCase':
|
||||
this.condition.apiCaseCoverage = 'coverage';
|
||||
break;
|
||||
case 'coverageScenario':
|
||||
this.condition.scenarioCoverage = 'coverage';
|
||||
break;
|
||||
case 'unCoverageScenario':
|
||||
this.condition.scenarioCoverage = 'uncoverage';
|
||||
break;
|
||||
case 'Prepare':
|
||||
this.condition.filters.status = [this.selectDataRange];
|
||||
break;
|
||||
|
@ -895,16 +908,19 @@ export default {
|
|||
},
|
||||
//判断是否只显示本周的数据。 从首页跳转过来的请求会带有相关参数
|
||||
getSelectDataRange() {
|
||||
let dataRange = this.$route.params.dataSelectRange;
|
||||
let dataType = this.$route.params.dataType;
|
||||
this.selectDataRange = dataType === 'api' ? dataRange : "all";
|
||||
if (this.selectDataRange &&
|
||||
Object.prototype.toString.call(this.selectDataRange).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object'
|
||||
&& this.selectDataRange.indexOf(":") !== -1) {
|
||||
let selectParamArr = this.selectDataRange.split(":");
|
||||
if (selectParamArr.length === 2) {
|
||||
if (selectParamArr[0] === "apiList") {
|
||||
this.condition.name = selectParamArr[1];
|
||||
let routeParamObj = this.$route.params.paramObj;
|
||||
if (routeParamObj) {
|
||||
let dataRange = routeParamObj.dataSelectRange;
|
||||
let dataType = routeParamObj.dataType;
|
||||
this.selectDataRange = dataType === 'api' ? dataRange : "all";
|
||||
if (this.selectDataRange &&
|
||||
Object.prototype.toString.call(this.selectDataRange).match(/\[object (\w+)\]/)[1].toLowerCase() !== 'object'
|
||||
&& this.selectDataRange.indexOf(":") !== -1) {
|
||||
let selectParamArr = this.selectDataRange.split(":");
|
||||
if (selectParamArr.length === 2) {
|
||||
if (selectParamArr[0] === "apiList") {
|
||||
this.condition.name = selectParamArr[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,20 @@
|
|||
<ms-main-container v-loading="result.loading">
|
||||
<el-row :gutter="10" style="margin-bottom: 5px; margin-top: -5px;">
|
||||
<el-col :span="6" style="padding-left: 5px;padding-right: 0px">
|
||||
<ms-api-info-card @redirectPage="redirectPage" :api-count-data="apiCountData"
|
||||
:interface-coverage="apiCoverage"/>
|
||||
<api-count-card @redirectPage="redirectPage" :api-count-data="apiCountData"
|
||||
:api-coverage="apiCoverage"/>
|
||||
</el-col>
|
||||
<el-col :span="6" style="padding-left: 5px;padding-right: 0px">
|
||||
<ms-test-case-info-card @redirectPage="redirectPage" :test-case-count-data="testCaseCountData"/>
|
||||
<api-case-count-card @redirectPage="redirectPage" :test-case-count-data="testCaseCountData"
|
||||
:is-xpack="isXpack"/>
|
||||
</el-col>
|
||||
<el-col :span="6" style="padding-left: 5px;padding-right: 0px">
|
||||
<ms-scene-info-card @redirectPage="redirectPage" :scene-count-data="sceneCountData"
|
||||
:interface-coverage="interfaceCoverage"/>
|
||||
<scenario-count-card @redirectPage="redirectPage" :scene-count-data="sceneCountData" :is-xpack="isXpack"
|
||||
:scenario-coverage="scenarioCoverage"/>
|
||||
</el-col>
|
||||
<el-col :span="6" style="padding-left: 5px;padding-right: 5px">
|
||||
<ms-schedule-task-info-card :schedule-task-count-data="scheduleTaskCountData"/>
|
||||
<schedule-task-count-card @redirectPage="redirectPage" :schedule-task-count-data="scheduleTaskCountData"
|
||||
:is-xpack="isXpack"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
@ -36,7 +38,8 @@
|
|||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="caseTitle">
|
||||
<el-radio v-model="testTitleFirst" label="caseTitle">{{
|
||||
$t('api_test.home_page.failed_case_list.title')}}
|
||||
$t('api_test.home_page.failed_case_list.title')
|
||||
}}
|
||||
</el-radio>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="taskTitle">
|
||||
|
@ -67,7 +70,7 @@
|
|||
<el-col :span="12" style="padding-left: 5px;padding-right: 5px">
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:10px;">
|
||||
<div v-if="testTitleSecond === 'caseTitle'">
|
||||
<ms-api-failure-test-case-list @redirectPage="redirectPage" />
|
||||
<ms-api-failure-test-case-list @redirectPage="redirectPage"/>
|
||||
</div>
|
||||
<div v-if="testTitleSecond === 'taskTitle'">
|
||||
<ms-api-running-task-list :call-from="'api_test'" @redirectPage="redirectPage"/>
|
||||
|
@ -128,27 +131,38 @@ import MsApiFailureTestCaseList from "./components/ApiFailureTestCaseList";
|
|||
import MsFailureTestCaseList from "./components/FailureTestCaseList";
|
||||
import MsRunningTaskList from "./components/RunningTaskList";
|
||||
import MsApiRunningTaskList from "./components/ApiRunningTaskList";
|
||||
import {getCurrentProjectID, getUUID} from "@/common/js/utils";
|
||||
import {getCurrentProjectID, getUUID, hasLicense} from "@/common/js/utils";
|
||||
import MsApiNewTestCaseList from "./components/ApiNewTestCaseList";
|
||||
|
||||
import ApiCountCard from "@/business/components/api/homepage/components/card/ApiCountCard";
|
||||
import ApiCaseCountCard from "@/business/components/api/homepage/components/card/ApiCaseCountCard";
|
||||
import ScenarioCountCard from "@/business/components/api/homepage/components/card/ScenarioCountCard";
|
||||
import ScheduleTaskCountCard from "@/business/components/api/homepage/components/card/ScheduleTaskCountCard";
|
||||
|
||||
export default {
|
||||
name: "ApiTestHomePage",
|
||||
|
||||
components: {
|
||||
MsApiInfoCard, MsSceneInfoCard, MsScheduleTaskInfoCard, MsTestCaseInfoCard,
|
||||
MsApiFailureTestCaseList, MsRunningTaskList,
|
||||
MsMainContainer, MsContainer,MsFailureTestCaseList,MsApiRunningTaskList,MsApiNewTestCaseList
|
||||
MsMainContainer, MsContainer, MsFailureTestCaseList, MsApiRunningTaskList, MsApiNewTestCaseList,
|
||||
ApiCountCard, ApiCaseCountCard, ScenarioCountCard, ScheduleTaskCountCard
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isXpack: false,
|
||||
values: [],
|
||||
apiCountData: {},
|
||||
sceneCountData: {},
|
||||
testCaseCountData: {},
|
||||
scheduleTaskCountData: {},
|
||||
interfaceCoverage: "waitting...",
|
||||
apiCoverage: "waitting...",
|
||||
apiCoverage: {
|
||||
rateOfCoverage: "waitting...",
|
||||
},
|
||||
scenarioCoverage: {
|
||||
rateOfCoverage: "waitting...",
|
||||
},
|
||||
result: {},
|
||||
testTitleFirst: " ",
|
||||
testTitleSecond: " ",
|
||||
|
@ -166,8 +180,8 @@ export default {
|
|||
this.testTitleFirst = localStorage.getItem("titleFirst");
|
||||
}
|
||||
this.cardTitle.name = localStorage.getItem("cardTitle");
|
||||
} else{
|
||||
this.cardTitle.name=this.$t('api_test.home_page.failed_case_list.title');
|
||||
} else {
|
||||
this.cardTitle.name = this.$t('api_test.home_page.failed_case_list.title');
|
||||
}
|
||||
this.testTitleSecond = "taskTitle";
|
||||
if (localStorage.getItem("cardTitleSecond")) {
|
||||
|
@ -175,50 +189,50 @@ export default {
|
|||
this.testTitleSecond = localStorage.getItem("titleSecond");
|
||||
}
|
||||
this.cardTitleSecond.name = localStorage.getItem("cardTitleSecond");
|
||||
} else{
|
||||
this.cardTitleSecond.name=this.$t('api_test.home_page.running_task_list.title');
|
||||
} else {
|
||||
this.cardTitleSecond.name = this.$t('api_test.home_page.running_task_list.title');
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
handleCommand(cmd) {
|
||||
if(cmd){
|
||||
if (cmd) {
|
||||
switch (cmd) {
|
||||
case "caseTitle":
|
||||
this.cardTitle.name=this.$t('api_test.home_page.failed_case_list.title');
|
||||
localStorage.setItem("cardTitle" , this.cardTitle.name);
|
||||
localStorage.setItem("titleFirst" , "caseTitle");
|
||||
this.cardTitle.name = this.$t('api_test.home_page.failed_case_list.title');
|
||||
localStorage.setItem("cardTitle", this.cardTitle.name);
|
||||
localStorage.setItem("titleFirst", "caseTitle");
|
||||
break;
|
||||
case "taskTitle":
|
||||
this.cardTitle.name = this.$t('api_test.home_page.running_task_list.title');
|
||||
localStorage.setItem("cardTitle" , this.cardTitle.name);
|
||||
localStorage.setItem("titleFirst" , "taskTitle");
|
||||
localStorage.setItem("cardTitle", this.cardTitle.name);
|
||||
localStorage.setItem("titleFirst", "taskTitle");
|
||||
break;
|
||||
case "newApiTitle":
|
||||
this.cardTitle.name = this.$t('api_test.home_page.new_case_list.title');
|
||||
localStorage.setItem("cardTitle" , this.cardTitle.name);
|
||||
localStorage.setItem("titleFirst" , "newApiTitle");
|
||||
localStorage.setItem("cardTitle", this.cardTitle.name);
|
||||
localStorage.setItem("titleFirst", "newApiTitle");
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
handleCommandSecond(cmd) {
|
||||
if(cmd){
|
||||
if (cmd) {
|
||||
switch (cmd) {
|
||||
case "caseTitle":
|
||||
this.cardTitleSecond.name=this.$t('api_test.home_page.failed_case_list.title');
|
||||
localStorage.setItem("cardTitleSecond" , this.cardTitleSecond.name);
|
||||
localStorage.setItem("titleSecond" , "caseTitle");
|
||||
this.cardTitleSecond.name = this.$t('api_test.home_page.failed_case_list.title');
|
||||
localStorage.setItem("cardTitleSecond", this.cardTitleSecond.name);
|
||||
localStorage.setItem("titleSecond", "caseTitle");
|
||||
break;
|
||||
case "taskTitle":
|
||||
this.cardTitleSecond.name = this.$t('api_test.home_page.running_task_list.title');
|
||||
localStorage.setItem("cardTitleSecond" , this.cardTitleSecond.name);
|
||||
localStorage.setItem("titleSecond" , "taskTitle");
|
||||
localStorage.setItem("cardTitleSecond", this.cardTitleSecond.name);
|
||||
localStorage.setItem("titleSecond", "taskTitle");
|
||||
break;
|
||||
case "newApiTitle":
|
||||
this.cardTitleSecond.name = this.$t('api_test.home_page.new_case_list.title');
|
||||
localStorage.setItem("cardTitleSecond" , this.cardTitleSecond.name);
|
||||
localStorage.setItem("titleSecond" , "newApiTitle");
|
||||
localStorage.setItem("cardTitleSecond", this.cardTitleSecond.name);
|
||||
localStorage.setItem("titleSecond", "newApiTitle");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -230,6 +244,10 @@ export default {
|
|||
});
|
||||
},
|
||||
search() {
|
||||
this.isXpack = hasLicense();
|
||||
this.searchData();
|
||||
},
|
||||
searchData() {
|
||||
let selectProjectId = getCurrentProjectID();
|
||||
this.$get("/api/apiCount/" + selectProjectId, response => {
|
||||
this.apiCountData = response.data;
|
||||
|
@ -238,14 +256,22 @@ export default {
|
|||
this.$get("/api/testSceneInfoCount/" + selectProjectId, response => {
|
||||
this.sceneCountData = response.data;
|
||||
});
|
||||
this.apiCoverage = "waitting...",
|
||||
this.interfaceCoverage = "waitting...";
|
||||
this.$get("/api/countInterfaceCoverage/" + selectProjectId, response => {
|
||||
this.interfaceCoverage = response.data;
|
||||
|
||||
this.apiCoverage.rateOfCoverage = "waitting...";
|
||||
this.scenarioCoverage.rateOfCoverage = "waitting...";
|
||||
|
||||
this.$get("/api/countScenarioCoverage/" + selectProjectId, response => {
|
||||
let respData = response.data;
|
||||
this.scenarioCoverage.rateOfCoverage = respData.rateOfCoverage;
|
||||
this.scenarioCoverage.coverate = respData.coverate;
|
||||
this.scenarioCoverage.notCoverate = respData.notCoverate;
|
||||
});
|
||||
|
||||
this.$get("/api/countApiCoverage/" + selectProjectId, response => {
|
||||
this.apiCoverage = response.data;
|
||||
let respData = response.data;
|
||||
this.apiCoverage.rateOfCoverage = respData.rateOfCoverage;
|
||||
this.apiCoverage.coverate = respData.coverate;
|
||||
this.apiCoverage.notCoverate = respData.notCoverate;
|
||||
});
|
||||
|
||||
this.$get("/api/testCaseInfoCount/" + selectProjectId, response => {
|
||||
|
@ -260,17 +286,20 @@ export default {
|
|||
//api页面跳转
|
||||
//传入UUID是为了进行页面重新加载判断
|
||||
let uuid = getUUID();
|
||||
let redirectObj = {
|
||||
redirectID: uuid, dataType: dataType, dataSelectRange: selectType
|
||||
};
|
||||
switch (page) {
|
||||
case "api":
|
||||
this.$router.push({
|
||||
name: 'ApiDefinition',
|
||||
params: {redirectID: uuid, dataType: dataType, dataSelectRange: selectType}
|
||||
params: {paramObj: redirectObj}
|
||||
});
|
||||
break;
|
||||
case "scenario":
|
||||
this.$router.push({
|
||||
name: 'ApiAutomation',
|
||||
params: {redirectID: uuid, dataType: dataType, dataSelectRange: selectType}
|
||||
params: {paramObj: redirectObj}
|
||||
});
|
||||
break;
|
||||
case "testPlanEdit":
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
</el-table-column>
|
||||
<el-table-column prop="testPlan" :label="$t('api_test.home_page.failed_case_list.table_coloum.test_plan')">
|
||||
<template v-slot:default="{row}">
|
||||
<div v-for="(testPlan, index) in row.testPlanDTOList" :key="index">
|
||||
<el-link type="info" @click="redirect('testPlanEdit',testPlan.id)"
|
||||
v-if="testPlan.name === row.testPlan || row.caseType !== 'apiCase'">
|
||||
{{ testPlan.name }};
|
||||
<div>
|
||||
<el-link type="info" @click="redirect('testPlanEdit',row.testPlanId)">
|
||||
{{ row.testPlan }}
|
||||
</el-link>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 5px;"
|
||||
style="height: 350px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.test_case_count_card.title') }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- 数量统计 -->
|
||||
<el-container>
|
||||
<el-aside width="34%">
|
||||
<count-rectangle-chart :content="testCaseCountData.allApiDataCountNumber"/>
|
||||
</el-aside>
|
||||
<el-main style="padding-left: 0px;padding-right: 0px">
|
||||
<div style="width: 185px; float:right;margin:0 auto">
|
||||
<el-row align="center" class="hidden-lg-and-down">
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.httpCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.rpcCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.tcpCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6" style="padding: 5px;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.sqlCountStr"></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row align="right" class="hidden-xl-only">
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.httpCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.rpcCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.tcpCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6" style="padding: 5px;">
|
||||
<div class="count-info-div" v-html="testCaseCountData.sqlCountStr"></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<!-- 本周新增 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 0px;">
|
||||
<el-row>
|
||||
<el-col>
|
||||
{{ $t('api_test.home_page.test_case_details_card.this_week_add') }}
|
||||
<el-link type="info" @click="redirectPage('thisWeekCount')" target="_blank" style="color: #000000">
|
||||
{{ testCaseCountData.thisWeekAddedCount }}
|
||||
</el-link>
|
||||
{{ $t('api_test.home_page.unit_of_measurement') }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{
|
||||
$t('api_test.home_page.test_case_details_card.this_week_execute', [testCaseCountData.thisWeekExecutedCount])
|
||||
}}
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property">
|
||||
{{ $t('api_test.home_page.test_case_details_card.executed', [testCaseCountData.executedCount]) }}
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<!-- 用例通过率 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 5px;">
|
||||
<el-row>
|
||||
<span style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.rate.case_pase') + ":" }}
|
||||
</span>
|
||||
<span class="rows-count-number" style="font-size: 14px">
|
||||
<b>
|
||||
{{ testCaseCountData.passRage }}
|
||||
</b>
|
||||
<el-tooltip placement="top" class="info-tool-tip">
|
||||
<div slot="content">{{ $t('api_test.home_page.formula.api_case_pass') }}</div>
|
||||
<el-button icon="el-icon-info" style="padding:0px;border: 0px"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row v-if="isXpack">
|
||||
<el-col :span="6">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('unexecuteCount')" target="_blank">
|
||||
<b>{{ testCaseCountData.unexecuteCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.execution_failed') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('executionFailedCount')"
|
||||
target="_blank">
|
||||
<b>{{ testCaseCountData.executionFailedCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="default-property">
|
||||
{{ $t('error_report_library.option.name') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('fakeErrorCount')" target="_blank">
|
||||
<b>{{ testCaseCountData.fakeErrorCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.execution_pass') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('executionPassCount')"
|
||||
target="_blank">
|
||||
<b>{{ testCaseCountData.executionPassCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-else>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('unexecuteCount')" target="_blank">
|
||||
<b>{{ testCaseCountData.unexecuteCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.execution_failed') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('notSuccessCount')" target="_blank">
|
||||
<b>{{ testCaseCountData.executionFailedCount + testCaseCountData.fakeErrorCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.execution_pass') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('executionPassCount')"
|
||||
target="_blank">
|
||||
<b>{{ testCaseCountData.executionPassCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<!-- 接口覆盖率 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 5px;">
|
||||
<el-row>
|
||||
<span style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.rate.interface_coverage') + ":" }}
|
||||
</span>
|
||||
<span class="rows-count-number" style="font-size: 14px">
|
||||
<b>
|
||||
{{ testCaseCountData.coverageRage }}
|
||||
</b>
|
||||
<el-tooltip placement="top" class="info-tool-tip">
|
||||
<div slot="content">{{ $t('api_test.home_page.formula.coverage') }}</div>
|
||||
<el-button icon="el-icon-info" style="padding:0px;border: 0px"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.uncoverage') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link type="info" class="rows-count-number" @click="redirectPage('uncoverageCount')" target="_blank">
|
||||
<b>{{ testCaseCountData.uncoverageCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.coverage') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('coverageCount')" target="_blank">
|
||||
<b>
|
||||
{{ testCaseCountData.coverageCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import CountRectangleChart from "@/business/components/common/chart/CountRectangleChart";
|
||||
|
||||
export default {
|
||||
name: "ApiCaseCountCard",
|
||||
|
||||
components: {CountRectangleChart},
|
||||
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
testCaseCountData: {},
|
||||
apiCaseCoverage: Object,
|
||||
isXpack: Boolean,
|
||||
},
|
||||
methods: {
|
||||
redirectPage(clickType) {
|
||||
if (clickType === 'uncoverageCount') {
|
||||
//这里业务逻辑应当跳转接口列表
|
||||
this.$emit("redirectPage", "api", "api", "unCoverageTestCase");
|
||||
} else if (clickType === 'coverageCount') {
|
||||
//这里业务逻辑应当跳转接口列表
|
||||
this.$emit("redirectPage", "api", "api", "coverageTestCase");
|
||||
} else {
|
||||
this.$emit("redirectPage", "api", "apiTestCase", clickType);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
|
||||
},
|
||||
activated() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-aside {
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rows-count-number {
|
||||
font-family: 'ArialMT', 'Arial', sans-serif;
|
||||
font-size: 12px;
|
||||
color: var(--count_number);
|
||||
}
|
||||
|
||||
.detail-container {
|
||||
margin-top: 20px
|
||||
}
|
||||
|
||||
.default-property {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.main-property {
|
||||
color: #F39021;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.el-card /deep/ .el-card__header {
|
||||
border-bottom: 0px solid #EBEEF5;
|
||||
}
|
||||
|
||||
.count-info-div {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.count-info-div >>> p {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.info-tool-tip {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 5px;"
|
||||
style="height: 350px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.api_count_card.title') }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- 数值统计 -->
|
||||
<el-container>
|
||||
<el-aside width="34%">
|
||||
<count-rectangle-chart :content="apiCountData.allApiDataCountNumber"/>
|
||||
</el-aside>
|
||||
<el-main style="padding-left: 0px;padding-right: 0px;">
|
||||
<div style="width: 185px; float:right;margin:0 auto">
|
||||
|
||||
<el-row align="right">
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="apiCountData.httpCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="apiCountData.rpcCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6"
|
||||
style="padding: 5px;border-right-style: solid;border-right-width: 1px;border-right-color: #ECEEF4;">
|
||||
<div class="count-info-div" v-html="apiCountData.tcpCountStr"></div>
|
||||
</el-col>
|
||||
<el-col :span="6" style="padding: 5px;">
|
||||
<div class="count-info-div" v-html="apiCountData.sqlCountStr"></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<el-container class="detail-container">
|
||||
<!-- 本周新增 -->
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 0px;">
|
||||
<el-row>
|
||||
<el-col>
|
||||
{{ $t('api_test.home_page.api_details_card.this_week_add') }}
|
||||
<el-link type="info" @click="redirectPage('thisWeekCount')" target="_blank" style="color: #000000">
|
||||
{{ apiCountData.thisWeekAddedCount }}
|
||||
</el-link>
|
||||
{{ $t('api_test.home_page.unit_of_measurement') }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8"> </el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<!-- 接口完成率 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 5px;">
|
||||
<el-row>
|
||||
<span style="float: left;">
|
||||
{{ $t('api_test.home_page.detail_card.rate.api_completion') + ":" }}
|
||||
</span>
|
||||
<span class="rows-count-number" style="font-size:14px">
|
||||
<b>
|
||||
{{ apiCountData.completionRage }}
|
||||
</b>
|
||||
<el-tooltip placement="top" class="info-tool-tip">
|
||||
<div slot="content">{{ $t('api_test.home_page.formula.completion') }}</div>
|
||||
<el-button icon="el-icon-info" style="padding:0px;border: 0px"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.not_started') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('Prepare')" target="_blank">
|
||||
<b>{{ apiCountData.notStartedCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.running') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('Underway')" target="_blank">
|
||||
<b>{{ apiCountData.runningCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.finished') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('Completed')" target="_blank">
|
||||
<b>{{ apiCountData.finishedCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<!-- 接口覆蓋率 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 5px;">
|
||||
<el-row>
|
||||
<span style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.rate.interface_coverage') + ":" }}
|
||||
</span>
|
||||
<span v-if="apiCoverage.rateOfCoverage === 'waitting...'">
|
||||
<i class="el-icon-loading lading-icon"></i>
|
||||
</span>
|
||||
<span v-else class="rows-count-number" style="font-size: 14px">
|
||||
<b>{{ apiCoverage.rateOfCoverage }}</b>
|
||||
<el-tooltip placement="top" class="info-tool-tip">
|
||||
<div slot="content">{{ $t('api_test.home_page.formula.api_coverage') }}</div>
|
||||
<el-button icon="el-icon-info" style="padding:0px;border: 0px"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<span class="rows-count-number">
|
||||
{{ $t('api_test.home_page.detail_card.uncoverage') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" type="info" @click="redirectPage('notCoverate')" target="_blank">
|
||||
<b>
|
||||
{{ apiCoverage.notCoverate }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.coverage') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('coverate')" target="_blank">
|
||||
<b>
|
||||
{{ apiCoverage.coverate }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import CountRectangleChart from "@/business/components/common/chart/CountRectangleChart";
|
||||
|
||||
export default {
|
||||
name: "ApiCountCard",
|
||||
|
||||
components: {CountRectangleChart},
|
||||
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
apiCountData: {},
|
||||
apiCoverage: Object,
|
||||
},
|
||||
methods: {
|
||||
redirectPage(clickType) {
|
||||
this.$emit("redirectPage", "api", "api", clickType);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-aside {
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rows-count-number {
|
||||
font-family: 'ArialMT', 'Arial', sans-serif;
|
||||
font-size: 12px;
|
||||
color: var(--count_number);
|
||||
}
|
||||
|
||||
.detail-container {
|
||||
margin-top: 20px
|
||||
}
|
||||
|
||||
.default-property {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.main-property {
|
||||
color: #F39021;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.el-card /deep/ .el-card__header {
|
||||
border-bottom: 0px solid #EBEEF5;
|
||||
}
|
||||
|
||||
.count-info-div {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.count-info-div >>> p {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.info-tool-tip {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,281 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 5px;"
|
||||
style="height: 350px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.test_scene_count_card.title') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 数量统计 -->
|
||||
<el-container>
|
||||
<el-aside width="34%">
|
||||
<count-rectangle-chart :content="sceneCountData.allApiDataCountNumber"/>
|
||||
</el-aside>
|
||||
<el-main style="padding-left: 0px;padding-right: 0px; margin-right: 5px">
|
||||
<div style="width: 185px; float:right;margin:0 auto">
|
||||
<el-row align="right">
|
||||
<span style="text-align: right;display:block;">
|
||||
{{
|
||||
$t('api_test.home_page.test_scene_details_card.this_week_execute', [sceneCountData.thisWeekExecutedCount])
|
||||
}}
|
||||
</span>
|
||||
</el-row>
|
||||
<el-row align="right">
|
||||
|
||||
</el-row>
|
||||
<el-row align="right">
|
||||
<span style="text-align: right;display:block;">
|
||||
{{ $t('api_test.home_page.test_scene_details_card.executed', [sceneCountData.executedCount]) }}
|
||||
</span>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<el-container class="detail-container">
|
||||
<!-- 本周新增 -->
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 0px;">
|
||||
<el-row>
|
||||
<el-col>
|
||||
{{ $t('api_test.home_page.api_details_card.this_week_add') }}
|
||||
<el-link type="info" @click="redirectPage('thisWeekCount')" target="_blank" style="color: #000000">
|
||||
{{ sceneCountData.thisWeekAddedCount }}
|
||||
</el-link>
|
||||
{{ $t('api_test.home_page.unit_of_measurement') }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8"> </el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<!-- 场景通过率 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 5px;">
|
||||
<el-row>
|
||||
<span style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.rate.scenario_pase') + ":" }}
|
||||
</span>
|
||||
<span class="rows-count-number" style="font-size: 14px">
|
||||
<b>
|
||||
{{ sceneCountData.passRage }}
|
||||
</b>
|
||||
<el-tooltip placement="top" class="info-tool-tip">
|
||||
<div slot="content">{{ $t('api_test.home_page.formula.pass') }}</div>
|
||||
<el-button icon="el-icon-info" style="padding:0px;border: 0px"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row v-if="this.isXpack">
|
||||
<el-col :span="6">
|
||||
<span class="rows-count-number">
|
||||
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link type="info" @click="redirectPage('unexecuteCount')" target="_blank" style="color: #000000">
|
||||
<b>{{ sceneCountData.unexecuteCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="rows-count-number" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.execution_failed') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('executionFailedCount')" target="_blank">
|
||||
<b>
|
||||
{{ sceneCountData.executionFailedCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="rows-count-number" style="float: left">
|
||||
{{ $t('error_report_library.option.name') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('fakeErrorCount')" target="_blank">
|
||||
<b>
|
||||
{{ sceneCountData.fakeErrorCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.execution_pass') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('executionPassCount')" target="_blank">
|
||||
<b>
|
||||
{{ sceneCountData.executionPassCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-else>
|
||||
<el-col :span="8">
|
||||
<span class="rows-count-number">
|
||||
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link type="info" @click="redirectPage('unexecuteCount')" target="_blank" style="color: #000000">
|
||||
<b>{{ sceneCountData.unexecuteCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="rows-count-number" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.execution_failed') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('notSuccessCount')" target="_blank">
|
||||
<b>
|
||||
{{ sceneCountData.executionFailedCount + sceneCountData.fakeErrorCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.execution_pass') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('executionPassCount')" target="_blank">
|
||||
<b>
|
||||
{{ sceneCountData.executionPassCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<!-- 场景覆盖率 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 5px;">
|
||||
<el-row>
|
||||
<span style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.rate.interface_coverage') + ":" }}
|
||||
</span>
|
||||
<span v-if="scenarioCoverage.rateOfCoverage === 'waitting...'">
|
||||
<i class="el-icon-loading lading-icon"></i>
|
||||
</span>
|
||||
<span v-else class="rows-count-number" style="font-size: 14px">
|
||||
<b>
|
||||
{{ scenarioCoverage.rateOfCoverage }}
|
||||
</b>
|
||||
<el-tooltip placement="top" class="info-tool-tip">
|
||||
<div slot="content">{{ $t('api_test.home_page.formula.interface_coverage') }}</div>
|
||||
<el-button icon="el-icon-info" style="padding:0px;border: 0px"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.uncoverage') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link type="info" class="rows-count-number" @click="redirectPage('notCoverate')" target="_blank">
|
||||
<b>{{ scenarioCoverage.notCoverate }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.coverage') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('coverate')" target="_blank">
|
||||
<b>{{ scenarioCoverage.coverate }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import CountRectangleChart from "@/business/components/common/chart/CountRectangleChart";
|
||||
|
||||
export default {
|
||||
name: "ScenarioCountCard",
|
||||
|
||||
components: {CountRectangleChart},
|
||||
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
sceneCountData: {},
|
||||
scenarioCoverage: Object,
|
||||
isXpack: Boolean,
|
||||
},
|
||||
methods: {
|
||||
redirectPage(clickType) {
|
||||
if (clickType === "coverate") {
|
||||
this.$emit("redirectPage", "api", "api", "coverageScenario");
|
||||
} else if (clickType === "notCoverate") {
|
||||
this.$emit("redirectPage", "api", "api", "unCoverageScenario");
|
||||
} else {
|
||||
this.$emit("redirectPage", "scenario", "scenario", clickType);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-aside {
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rows-count-number {
|
||||
font-family: 'ArialMT', 'Arial', sans-serif;
|
||||
font-size: 12px;
|
||||
color: var(--count_number);
|
||||
}
|
||||
|
||||
.detail-container {
|
||||
margin-top: 20px
|
||||
}
|
||||
|
||||
.default-property {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.main-property {
|
||||
color: #F39021;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.el-card /deep/ .el-card__header {
|
||||
border-bottom: 0px solid #EBEEF5;
|
||||
}
|
||||
|
||||
.count-info-div {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.count-info-div >>> p {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.info-tool-tip {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,215 @@
|
|||
<template>
|
||||
<el-card class="table-card" v-loading="result.loading" body-style="padding:16px 5px 16px 5px;"
|
||||
style="height: 350px;margin-top: 5px">
|
||||
<div slot="header">
|
||||
<span class="title">
|
||||
{{ $t('api_test.home_page.schedule_task_count_card.title') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 数量统计 -->
|
||||
<el-container>
|
||||
<el-aside width="34%">
|
||||
<count-rectangle-chart :content="scheduleTaskCountData.allApiDataCountNumber"/>
|
||||
</el-aside>
|
||||
<el-main style="padding-left: 0px;padding-right: 0px; margin-right: 5px">
|
||||
<div style="width: 185px; float:right;margin:0 auto">
|
||||
<el-row align="right">
|
||||
<span style="text-align: right;display:block;">
|
||||
{{
|
||||
$t('api_test.home_page.test_scene_details_card.this_week_execute', [scheduleTaskCountData.thisWeekExecutedCount])
|
||||
}}
|
||||
</span>
|
||||
</el-row>
|
||||
<el-row align="right">
|
||||
|
||||
</el-row>
|
||||
<el-row align="right">
|
||||
<span style="text-align: right;display:block;">
|
||||
{{ $t('api_test.home_page.test_scene_details_card.executed', [scheduleTaskCountData.executedCount]) }}
|
||||
</span>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<el-container class="detail-container">
|
||||
<!-- 本周新增 -->
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 0px;">
|
||||
<el-row>
|
||||
<el-col>
|
||||
{{ $t('api_test.home_page.api_details_card.this_week_add') }}
|
||||
<el-link type="info" @click="redirectPage('thisWeekCount')" target="_blank" style="color: #000000">
|
||||
{{ scheduleTaskCountData.thisWeekAddedCount }}
|
||||
</el-link>
|
||||
{{ $t('api_test.home_page.unit_of_measurement') }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row>
|
||||
<el-col :span="8"> </el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<!-- 任务成功率 -->
|
||||
<el-container class="detail-container">
|
||||
<el-header style="height:20px;padding: 0px;margin-bottom: 5px;">
|
||||
<el-row>
|
||||
<span style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.rate.success') + ":" }}
|
||||
</span>
|
||||
<span class="rows-count-number" style="font-size: 14px">
|
||||
<b>
|
||||
{{ scheduleTaskCountData.successRage }}
|
||||
</b>
|
||||
<el-tooltip placement="top" class="info-tool-tip">
|
||||
<div slot="content">{{ $t('api_test.home_page.formula.success') }}</div>
|
||||
<el-button icon="el-icon-info" style="padding:0px;border: 0px"></el-button>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main style="padding:0px">
|
||||
<el-row v-if="this.isXpack">
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.failed') }}
|
||||
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link type="info" class="rows-count-number" @click="redirectPage('executionFailedCount')"
|
||||
target="_blank">
|
||||
<b>{{ scheduleTaskCountData.failedCount + scheduleTaskCountData.failedCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('error_report_library.option.name') }}
|
||||
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link type="info" class="rows-count-number" @click="redirectPage('fakeErrorCount')" target="_blank">
|
||||
<b>{{ scheduleTaskCountData.fakeErrorCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.success') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('executionPassCount')" target="_blank">
|
||||
<b>
|
||||
{{ scheduleTaskCountData.successCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-else>
|
||||
<el-col :span="8">
|
||||
<span class="default-property">
|
||||
{{ $t('api_test.home_page.detail_card.failed') }}
|
||||
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link type="info" class="rows-count-number" @click="redirectPage('notSuccessCount')" target="_blank">
|
||||
<b>{{ scheduleTaskCountData.failedCount + scheduleTaskCountData.fakeErrorCount }}</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<span class="main-property" style="float: left">
|
||||
{{ $t('api_test.home_page.detail_card.success') }}
|
||||
{{ "\xa0\xa0" }}
|
||||
<el-link class="rows-count-number" @click="redirectPage('executionPassCount')" target="_blank">
|
||||
<b>
|
||||
{{ scheduleTaskCountData.successCount }}
|
||||
</b>
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import 'element-ui/lib/theme-chalk/display.css';
|
||||
import CountRectangleChart from "@/business/components/common/chart/CountRectangleChart";
|
||||
|
||||
|
||||
export default {
|
||||
|
||||
name: "MsScheduleTaskInfoCard",
|
||||
|
||||
components: {CountRectangleChart},
|
||||
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
apiCountData: {},
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
scheduleTaskCountData: {},
|
||||
isXpack: Boolean,
|
||||
},
|
||||
methods: {
|
||||
redirectPage(clickType) {
|
||||
this.$emit("redirectPage", "scenario", "schedule", clickType);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
},
|
||||
activated() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-aside {
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rows-count-number {
|
||||
font-family: 'ArialMT', 'Arial', sans-serif;
|
||||
font-size: 12px;
|
||||
color: var(--count_number);
|
||||
}
|
||||
|
||||
.detail-container {
|
||||
margin-top: 20px
|
||||
}
|
||||
|
||||
.default-property {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.main-property {
|
||||
color: #F39021;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.el-card /deep/ .el-card__header {
|
||||
border-bottom: 0px solid #EBEEF5;
|
||||
}
|
||||
|
||||
.count-info-div {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.count-info-div >>> p {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.info-tool-tip {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
export default {
|
||||
path: "/api",
|
||||
name: "api",
|
||||
|
@ -30,12 +28,12 @@ export default {
|
|||
|
||||
},
|
||||
{
|
||||
path: "definition/:redirectID?/:dataType?/:dataSelectRange?/:projectId?/:type?/:workspaceId?",
|
||||
path: "definition",
|
||||
name: "ApiDefinition",
|
||||
component: () => import('@/business/components/api/definition/ApiDefinition'),
|
||||
},
|
||||
{
|
||||
path: "automation/:redirectID?/:dataType?/:dataSelectRange?/:projectId?/:workspaceId?",
|
||||
path: "automation",
|
||||
name: "ApiAutomation",
|
||||
component: () => import('@/business/components/api/automation/ApiAutomation'),
|
||||
},
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<div class="main-number-show">
|
||||
<span class="count-number" :class="{'big_count-number': content < 10000}">
|
||||
{{ content }}
|
||||
</span>
|
||||
<span style="color: #6C317C;">
|
||||
{{ $t('api_test.home_page.unit_of_measurement') }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "CountRectangleChart",
|
||||
props: {
|
||||
content: {
|
||||
type: [Number, String]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.main-number-show {
|
||||
height: 62px;
|
||||
line-height: 62px;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-color: var(--count_number);
|
||||
background-color: #F1EAF1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-radius: 5%;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.count-number {
|
||||
font-family: 'ArialMT', 'Arial', sans-serif;
|
||||
font-size: 23px;
|
||||
color: var(--count_number);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.big_count-number {
|
||||
font-size: 33px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -456,9 +456,9 @@ export default {
|
|||
delete_all_version: 'All versions',
|
||||
change_password_tips: 'Your password is the initial system password, please change it as soon as possible',
|
||||
ui: 'UI TEST',
|
||||
not_eligible_for_deletion:'Not Eligible For Deletion',
|
||||
batch:'Batch',
|
||||
change:'Change',
|
||||
not_eligible_for_deletion: 'Not Eligible For Deletion',
|
||||
batch: 'Batch',
|
||||
change: 'Change',
|
||||
follow_people: "Follow people",
|
||||
default_module: {
|
||||
test_case: 'default',
|
||||
|
@ -489,8 +489,8 @@ export default {
|
|||
expired: 'expired',
|
||||
},
|
||||
workstation: {
|
||||
sync:'Synchronize',
|
||||
ignore:'Ignore',
|
||||
sync: 'Synchronize',
|
||||
ignore: 'Ignore',
|
||||
dash_board: 'My DashBoard',
|
||||
upcoming: 'My Upcoming',
|
||||
focus: 'My Focus',
|
||||
|
@ -499,7 +499,7 @@ export default {
|
|||
creation_issue: 'My Creation Issue',
|
||||
creation_case_tip: 'No use case has been created yet, create it now',
|
||||
creation_issue_tip: 'No defects have been created yet, create them now',
|
||||
delNotSame:'Remove parameters in use cases that cannot correspond to API documentation',
|
||||
delNotSame: 'Remove parameters in use cases that cannot correspond to API documentation',
|
||||
table_name: {
|
||||
track_case: 'Track Case',
|
||||
track_plan: 'Track Plan',
|
||||
|
@ -1812,9 +1812,10 @@ export default {
|
|||
completion: "finished api / all api * 100%",
|
||||
coverage: "apis whitch have test case / all apis * 100%",
|
||||
pass: "scenarios whitch final execute is sucess / all scenarios * 100%",
|
||||
api_case_pass: "api case whitch final execute is sucess / all api case *100%",
|
||||
success: "execute success count number / all execute count number * 100%",
|
||||
interface_coverage: "api whitch in scenario's step / all api * 100%",
|
||||
api_coverage: "api whitch have case or in scenario's step / all api * 100%",
|
||||
interface_coverage: "api whitch url in scenario's step / all api * 100%",
|
||||
api_coverage: "api(URL) whitch have case or in scenario's step / all api * 100%",
|
||||
review: "reviewed cases / all cases * 100%",
|
||||
testplan_coverage: "relevance function cases / all function cases * 100%",
|
||||
},
|
||||
|
@ -1842,6 +1843,9 @@ export default {
|
|||
failed: "Failure",
|
||||
success: "Success",
|
||||
rate: {
|
||||
api_completion: "API Completion",
|
||||
case_pase: "Case pass rate",
|
||||
scenario_pase: "Scenario pass rate",
|
||||
completion: "Completion rate",
|
||||
coverage: "Coverage",
|
||||
pass: "Pass rate",
|
||||
|
|
|
@ -458,9 +458,9 @@ export default {
|
|||
delete_all_version: '全部版本',
|
||||
change_password_tips: '您的密码是系统初始密码,请尽快修改密码',
|
||||
ui: 'UI 测试',
|
||||
not_eligible_for_deletion:'不符合删除条件',
|
||||
batch:'批量',
|
||||
change:'改变',
|
||||
not_eligible_for_deletion: '不符合删除条件',
|
||||
batch: '批量',
|
||||
change: '改变',
|
||||
follow_people: "关注人",
|
||||
default_module: {
|
||||
test_case: '未规划用例',
|
||||
|
@ -491,8 +491,8 @@ export default {
|
|||
expired: '已过期',
|
||||
},
|
||||
workstation: {
|
||||
sync:'同步',
|
||||
ignore:'忽略',
|
||||
sync: '同步',
|
||||
ignore: '忽略',
|
||||
dash_board: '我的仪表盘',
|
||||
upcoming: '我的待办',
|
||||
focus: '我的关注',
|
||||
|
@ -501,7 +501,7 @@ export default {
|
|||
creation_issue: '我创建的缺陷',
|
||||
creation_case_tip: '暂时还没有创建用例,马上创建',
|
||||
creation_issue_tip: '暂时还没有创建缺陷,马上创建',
|
||||
delNotSame:'删除用例中无法与API文档对应的参数',
|
||||
delNotSame: '删除用例中无法与API文档对应的参数',
|
||||
table_name: {
|
||||
track_case: '功能用例',
|
||||
track_plan: '测试计划',
|
||||
|
@ -1819,9 +1819,10 @@ export default {
|
|||
completion: "已完成的接口/接口总数*100%",
|
||||
coverage: "有用例的接口/接口总数*100%",
|
||||
pass: "最后一次执行成功的场景/场景总数*100%",
|
||||
api_case_pass: "最后一次执行成功的用例/用例总数*100%",
|
||||
success: "执行成功的次数/执行总次数*100%",
|
||||
interface_coverage: "被场景步骤包含的接口/接口总数*100%",
|
||||
api_coverage: "存在用例或被场景步骤包含的接口/接口总数*100%",
|
||||
interface_coverage: "被场景步骤包含的接口(URL)数/接口总数*100%",
|
||||
api_coverage: "接口(URL)有(用例或场景步骤)数/接口总数*100%",
|
||||
review: "已评审的功能案例/所有功能案例 * 100%",
|
||||
testplan_coverage: "关联的功能案例/所有功能案例 * 100%",
|
||||
},
|
||||
|
@ -1849,6 +1850,9 @@ export default {
|
|||
failed: "失败",
|
||||
success: "成功",
|
||||
rate: {
|
||||
api_completion: "接口完成率",
|
||||
case_pase: "用例通过率",
|
||||
scenario_pase: "场景通过率",
|
||||
completion: "完成率",
|
||||
coverage: "覆盖率",
|
||||
pass: "通过率",
|
||||
|
|
|
@ -458,9 +458,9 @@ export default {
|
|||
delete_all_version: '全部版本',
|
||||
change_password_tips: '您的密碼是系統初始密碼,請盡快修改密碼',
|
||||
ui: 'UI 測試',
|
||||
not_eligible_for_deletion:'不符合删除條件',
|
||||
batch:'批量',
|
||||
change:'改变',
|
||||
not_eligible_for_deletion: '不符合删除條件',
|
||||
batch: '批量',
|
||||
change: '改变',
|
||||
follow_people: "關註人",
|
||||
default_module: {
|
||||
test_case: '未規劃用例',
|
||||
|
@ -491,8 +491,8 @@ export default {
|
|||
expired: '已過期',
|
||||
},
|
||||
workstation: {
|
||||
sync:'同步',
|
||||
ignore:'忽略',
|
||||
sync: '同步',
|
||||
ignore: '忽略',
|
||||
dash_board: '我的儀表盤',
|
||||
upcoming: '我的待辦',
|
||||
focus: '我的關註',
|
||||
|
@ -501,7 +501,7 @@ export default {
|
|||
creation_issue: '我創建的缺陷',
|
||||
creation_case_tip: '暫時還沒有創建用例,馬上創建',
|
||||
creation_issue_tip: '暫時還沒有創建缺陷,馬上創建',
|
||||
delNotSame:'刪除用例中無法與API文檔對應的參數',
|
||||
delNotSame: '刪除用例中無法與API文檔對應的參數',
|
||||
table_name: {
|
||||
track_case: '功能用例',
|
||||
track_plan: '測試計劃',
|
||||
|
@ -1816,9 +1816,10 @@ export default {
|
|||
completion: "已完成的接口/接口總數*100%",
|
||||
coverage: "有用例的接口/接口總數*100%",
|
||||
pass: "最後一次執行成功的場景/場景總數*100%",
|
||||
api_case_pass: "最後一次執行成功的案例/案例總數*100%",
|
||||
success: "執行成功的次數/執行總次數*100%",
|
||||
interface_coverage: "被場景步驟包含的接口/接口總數*100%",
|
||||
api_coverage: "存在用例或被場景步驟包含的接口/接口總數*100%",
|
||||
interface_coverage: "被場景步驟包含的接口(URL)數/接口總數*100%",
|
||||
api_coverage: "接口(URL)有(用例或場景步驟)數/接口總數*100%",
|
||||
review: "已評審的功能案例/所有功能案例 * 100%",
|
||||
testplan_coverage: "關聯的功能案例/所有功能案例 * 100%",
|
||||
},
|
||||
|
@ -1846,6 +1847,9 @@ export default {
|
|||
failed: "失敗",
|
||||
success: "成功",
|
||||
rate: {
|
||||
api_completion: "接口完成率",
|
||||
case_pase: "用例通過率",
|
||||
scenario_pase: "場景通過率",
|
||||
completion: "完成率",
|
||||
coverage: "覆蓋率",
|
||||
pass: "通過率",
|
||||
|
|
Loading…
Reference in New Issue