diff --git a/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTask.java b/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTask.java index d07c7a27f2..b15d28d6a9 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTask.java +++ b/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTask.java @@ -41,8 +41,8 @@ public class ExecTask implements Serializable { @Size(min = 1, max = 50, message = "{exec_task.task_type.length_range}", groups = {Created.class, Updated.class}) private String taskType; - @Schema(description = "测试计划id") - private String testPlanId; + @Schema(description = "测试计划id/测试计划组id") + private String resourceId; @Schema(description = "执行模式", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank(message = "{exec_task.trigger_mode.not_blank}", groups = {Created.class}) @@ -81,7 +81,7 @@ public class ExecTask implements Serializable { caseCount("case_count", "caseCount", "BIGINT", false), result("result", "result", "VARCHAR", true), taskType("task_type", "taskType", "VARCHAR", false), - testPlanId("test_plan_id", "testPlanId", "VARCHAR", false), + resourceId("resource_id", "resourceId", "VARCHAR", false), triggerMode("trigger_mode", "triggerMode", "VARCHAR", false), projectId("project_id", "projectId", "VARCHAR", false), organizationId("organization_id", "organizationId", "VARCHAR", false), diff --git a/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTaskExample.java b/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTaskExample.java index fc2a8574f2..0199169e0f 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTaskExample.java +++ b/backend/framework/domain/src/main/java/io/metersphere/system/domain/ExecTaskExample.java @@ -574,73 +574,73 @@ public class ExecTaskExample { return (Criteria) this; } - public Criteria andTestPlanIdIsNull() { - addCriterion("test_plan_id is null"); + public Criteria andResourceIdIsNull() { + addCriterion("resource_id is null"); return (Criteria) this; } - public Criteria andTestPlanIdIsNotNull() { - addCriterion("test_plan_id is not null"); + public Criteria andResourceIdIsNotNull() { + addCriterion("resource_id is not null"); return (Criteria) this; } - public Criteria andTestPlanIdEqualTo(String value) { - addCriterion("test_plan_id =", value, "testPlanId"); + public Criteria andResourceIdEqualTo(String value) { + addCriterion("resource_id =", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdNotEqualTo(String value) { - addCriterion("test_plan_id <>", value, "testPlanId"); + public Criteria andResourceIdNotEqualTo(String value) { + addCriterion("resource_id <>", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdGreaterThan(String value) { - addCriterion("test_plan_id >", value, "testPlanId"); + public Criteria andResourceIdGreaterThan(String value) { + addCriterion("resource_id >", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdGreaterThanOrEqualTo(String value) { - addCriterion("test_plan_id >=", value, "testPlanId"); + public Criteria andResourceIdGreaterThanOrEqualTo(String value) { + addCriterion("resource_id >=", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdLessThan(String value) { - addCriterion("test_plan_id <", value, "testPlanId"); + public Criteria andResourceIdLessThan(String value) { + addCriterion("resource_id <", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdLessThanOrEqualTo(String value) { - addCriterion("test_plan_id <=", value, "testPlanId"); + public Criteria andResourceIdLessThanOrEqualTo(String value) { + addCriterion("resource_id <=", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdLike(String value) { - addCriterion("test_plan_id like", value, "testPlanId"); + public Criteria andResourceIdLike(String value) { + addCriterion("resource_id like", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdNotLike(String value) { - addCriterion("test_plan_id not like", value, "testPlanId"); + public Criteria andResourceIdNotLike(String value) { + addCriterion("resource_id not like", value, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdIn(List values) { - addCriterion("test_plan_id in", values, "testPlanId"); + public Criteria andResourceIdIn(List values) { + addCriterion("resource_id in", values, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdNotIn(List values) { - addCriterion("test_plan_id not in", values, "testPlanId"); + public Criteria andResourceIdNotIn(List values) { + addCriterion("resource_id not in", values, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdBetween(String value1, String value2) { - addCriterion("test_plan_id between", value1, value2, "testPlanId"); + public Criteria andResourceIdBetween(String value1, String value2) { + addCriterion("resource_id between", value1, value2, "resourceId"); return (Criteria) this; } - public Criteria andTestPlanIdNotBetween(String value1, String value2) { - addCriterion("test_plan_id not between", value1, value2, "testPlanId"); + public Criteria andResourceIdNotBetween(String value1, String value2) { + addCriterion("resource_id not between", value1, value2, "resourceId"); return (Criteria) this; } diff --git a/backend/framework/domain/src/main/java/io/metersphere/system/mapper/ExecTaskMapper.xml b/backend/framework/domain/src/main/java/io/metersphere/system/mapper/ExecTaskMapper.xml index 3cdb02987a..48f2c3df97 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/system/mapper/ExecTaskMapper.xml +++ b/backend/framework/domain/src/main/java/io/metersphere/system/mapper/ExecTaskMapper.xml @@ -9,7 +9,7 @@ - + @@ -77,7 +77,7 @@ - id, num, task_name, `status`, case_count, `result`, task_type, test_plan_id, trigger_mode, + id, num, task_name, `status`, case_count, `result`, task_type, resource_id, trigger_mode, project_id, organization_id, create_time, create_user, start_time, end_time + + \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/serializer/CustomRateSerializer.java b/backend/services/system-setting/src/main/java/io/metersphere/system/serializer/CustomRateSerializer.java similarity index 93% rename from backend/services/test-plan/src/main/java/io/metersphere/plan/serializer/CustomRateSerializer.java rename to backend/services/system-setting/src/main/java/io/metersphere/system/serializer/CustomRateSerializer.java index 0d22ebee39..2413bcde86 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/serializer/CustomRateSerializer.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/serializer/CustomRateSerializer.java @@ -1,4 +1,4 @@ -package io.metersphere.plan.serializer; +package io.metersphere.system.serializer; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java index 2a630b4ffc..7466e6ad00 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseTaskHubService.java @@ -2,6 +2,9 @@ package io.metersphere.system.service; import com.github.pagehelper.Page; import com.github.pagehelper.page.PageMethod; +import io.metersphere.plan.mapper.TestPlanMapper; +import io.metersphere.sdk.constants.ExecStatus; +import io.metersphere.sdk.constants.ResultStatus; import io.metersphere.sdk.util.SubListUtils; import io.metersphere.system.domain.ExecTask; import io.metersphere.system.domain.ExecTaskItem; @@ -11,6 +14,7 @@ import io.metersphere.system.dto.taskhub.TaskHubDTO; import io.metersphere.system.dto.taskhub.TaskHubItemDTO; import io.metersphere.system.dto.taskhub.TaskHubScheduleDTO; import io.metersphere.system.dto.taskhub.request.TaskHubItemRequest; +import io.metersphere.system.dto.taskhub.response.TaskStatisticsResponse; import io.metersphere.system.mapper.*; import io.metersphere.system.utils.PageUtils; import io.metersphere.system.utils.Pager; @@ -50,6 +54,8 @@ public class BaseTaskHubService { private SqlSessionFactory sqlSessionFactory; @Resource private ExtExecTaskItemMapper extExecTaskItemMapper; + @Resource + private TestPlanMapper testPlanMapper; /** * 系统-获取执行任务列表 @@ -174,4 +180,38 @@ public class BaseTaskHubService { private List getCaseTaskItemPage(TaskHubItemRequest request, String orgId, String projectId) { return extExecTaskItemMapper.selectList(request, orgId, projectId); } + + /** + * 计算任务通过率和执行进度 + * + * @param taskIds + * @return + */ + public List calculateRate(List taskIds) { + List responseList = new ArrayList<>(); + List taskItemList = extExecTaskItemMapper.selectItemByTaskIds(taskIds); + Map> taskItems = taskItemList.stream().collect(Collectors.groupingBy(ExecTaskItem::getTaskId)); + taskItems.forEach((taskId, items) -> { + //成功数量 + long successCount = items.stream().filter(item -> StringUtils.endsWithIgnoreCase(ResultStatus.SUCCESS.name(), item.getStatus())).count(); + //失败数量 + long errorCount = items.stream().filter(item -> StringUtils.endsWithIgnoreCase(ResultStatus.ERROR.name(), item.getStatus())).count(); + //误报数量 + long fakeErrorCount = items.stream().filter(item -> StringUtils.endsWithIgnoreCase(ResultStatus.FAKE_ERROR.name(), item.getStatus())).count(); + //未执行数量 + long pendingCount = items.stream().filter(item -> StringUtils.endsWithIgnoreCase(ExecStatus.PENDING.name(), item.getStatus())).count(); + + TaskStatisticsResponse response = new TaskStatisticsResponse(); + response.setId(taskId); + response.setCaseTotal(items.size()); + response.setSuccessCount(successCount); + response.setErrorCount(errorCount); + response.setFakeErrorCount(fakeErrorCount); + response.setPendingCount(pendingCount); + response.calculateExecuteRate(); + responseList.add(response); + }); + return responseList; + } + } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/utils/RateCalculateUtils.java b/backend/services/system-setting/src/main/java/io/metersphere/system/utils/RateCalculateUtils.java similarity index 97% rename from backend/services/test-plan/src/main/java/io/metersphere/plan/utils/RateCalculateUtils.java rename to backend/services/system-setting/src/main/java/io/metersphere/system/utils/RateCalculateUtils.java index bcf33d85fd..e099b507d6 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/utils/RateCalculateUtils.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/utils/RateCalculateUtils.java @@ -1,4 +1,4 @@ -package io.metersphere.plan.utils; +package io.metersphere.system.utils; import lombok.experimental.UtilityClass; diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java index 932ce6a721..bb43bfe1f5 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/BaseTaskHubControllerTests.java @@ -34,6 +34,7 @@ public class BaseTaskHubControllerTests extends BaseTest { public static final String SYSTEM_TASK_PAGE = "/system/task-center/exec-task/page"; public static final String SYSTEM_SCHEDULE_TASK_PAGE = "/system/task-center/schedule/page"; public static final String SYSTEM_TASK_ITEM_PAGE = "/system/task-center/exec-task/item/page"; + public static final String SYSTEM_STATISTICS = "/system/task-center/exec-task/statistics"; @Test @Order(1) @@ -90,6 +91,21 @@ public class BaseTaskHubControllerTests extends BaseTest { Assertions.assertNotNull(resultHolder); } + /** + * 系统用例任务完成率统计 + */ + @Test + @Order(3) + public void getStatistics() throws Exception { + List ids = List.of("1","2"); + MvcResult mvcResult = this.requestPostWithOkAndReturn(SYSTEM_STATISTICS, ids); + // 获取返回值 + String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); + ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); + // 返回请求正常 + Assertions.assertNotNull(resultHolder); + } + /** * 组织任务中心测试用例 diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportDetailResponse.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportDetailResponse.java index 61d01b582d..d9433395c4 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportDetailResponse.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportDetailResponse.java @@ -2,7 +2,7 @@ package io.metersphere.plan.dto.response; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.metersphere.plan.dto.CaseCount; -import io.metersphere.plan.serializer.CustomRateSerializer; +import io.metersphere.system.serializer.CustomRateSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportPageResponse.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportPageResponse.java index 3340077292..4b49d1976a 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportPageResponse.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanReportPageResponse.java @@ -1,7 +1,7 @@ package io.metersphere.plan.dto.response; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.metersphere.plan.serializer.CustomRateSerializer; +import io.metersphere.system.serializer.CustomRateSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanStatisticsResponse.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanStatisticsResponse.java index 56a97139d6..0e0f17de01 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanStatisticsResponse.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/response/TestPlanStatisticsResponse.java @@ -1,10 +1,10 @@ package io.metersphere.plan.dto.response; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.metersphere.plan.serializer.CustomRateSerializer; -import io.metersphere.plan.utils.RateCalculateUtils; import io.metersphere.sdk.constants.TestPlanConstants; import io.metersphere.system.dto.request.schedule.BaseScheduleConfigRequest; +import io.metersphere.system.serializer.CustomRateSerializer; +import io.metersphere.system.utils.RateCalculateUtils; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java index 4f6c64aca7..9675d31bcd 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java @@ -15,7 +15,6 @@ import io.metersphere.plan.dto.response.TestPlanReportPageResponse; import io.metersphere.plan.enums.TestPlanReportAttachmentSourceType; import io.metersphere.plan.mapper.*; import io.metersphere.plan.utils.CountUtils; -import io.metersphere.plan.utils.RateCalculateUtils; import io.metersphere.plugin.platform.dto.SelectOption; import io.metersphere.sdk.constants.*; import io.metersphere.sdk.exception.MSException; @@ -33,6 +32,7 @@ import io.metersphere.system.service.CommonFileService; import io.metersphere.system.service.FileService; import io.metersphere.system.service.SimpleUserService; import io.metersphere.system.uid.IDGenerator; +import io.metersphere.system.utils.RateCalculateUtils; import io.metersphere.system.utils.ServiceUtils; import jakarta.annotation.Resource; import org.apache.commons.collections4.CollectionUtils;