refactor(测试计划): 测试计划状态重构
This commit is contained in:
parent
54c102aad3
commit
01c7a365e0
|
@ -47,5 +47,10 @@ CALL UpdatePosForNoneGroup();
|
||||||
DROP PROCEDURE IF EXISTS UpdatePosForNoneGroup;
|
DROP PROCEDURE IF EXISTS UpdatePosForNoneGroup;
|
||||||
-- 清洗测试计划表的pos数据结束
|
-- 清洗测试计划表的pos数据结束
|
||||||
|
|
||||||
|
-- 修改未归档测试计划的存储状态
|
||||||
|
UPDATE test_plan
|
||||||
|
SET status = 'NOT_ARCHIVED'
|
||||||
|
WHERE status != 'ARCHIVED';
|
||||||
|
|
||||||
-- set innodb lock wait timeout to default
|
-- set innodb lock wait timeout to default
|
||||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
|
@ -5,19 +5,21 @@ public class TestPlanConstants {
|
||||||
public static final String TEST_PLAN_TYPE_PLAN = "TEST_PLAN";
|
public static final String TEST_PLAN_TYPE_PLAN = "TEST_PLAN";
|
||||||
//测试计划类型-测试计划组
|
//测试计划类型-测试计划组
|
||||||
public static final String TEST_PLAN_TYPE_GROUP = "GROUP";
|
public static final String TEST_PLAN_TYPE_GROUP = "GROUP";
|
||||||
|
|
||||||
//测试计划组默认ID
|
//测试计划组默认ID
|
||||||
public static final String TEST_PLAN_DEFAULT_GROUP_ID = "NONE";
|
public static final String TEST_PLAN_DEFAULT_GROUP_ID = "NONE";
|
||||||
|
|
||||||
//测试计划中相关的默认父ID
|
//测试计划中相关的默认父ID
|
||||||
public static final String DEFAULT_PARENT_ID = "NONE";
|
public static final String DEFAULT_PARENT_ID = "NONE";
|
||||||
|
|
||||||
//测试计划状态-未开始
|
//测试计划状态-未开始
|
||||||
public static final String TEST_PLAN_STATUS_PREPARED = "PREPARED";
|
public static final String TEST_PLAN_STATUS_NOT_ARCHIVED = "NOT_ARCHIVED";
|
||||||
//测试计划状态-进行中
|
|
||||||
public static final String TEST_PLAN_STATUS_UNDERWAY = "UNDERWAY";
|
|
||||||
//测试计划状态-已完成
|
|
||||||
public static final String TEST_PLAN_STATUS_COMPLETED = "COMPLETED";
|
|
||||||
//测试计划状态-已归档
|
//测试计划状态-已归档
|
||||||
public static final String TEST_PLAN_STATUS_ARCHIVED = "ARCHIVED";
|
public static final String TEST_PLAN_STATUS_ARCHIVED = "ARCHIVED";
|
||||||
|
|
||||||
|
//测试计划对外展示状态-未开始
|
||||||
|
public static final String TEST_PLAN_SHOW_STATUS_PREPARED = "PREPARED";
|
||||||
|
//测试计划对外展示状态-进行中
|
||||||
|
public static final String TEST_PLAN_SHOW_STATUS_UNDERWAY = "UNDERWAY";
|
||||||
|
//测试计划对外展示状态-已完成
|
||||||
|
public static final String TEST_PLAN_SHOW_STATUS_COMPLETED = "COMPLETED";
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ import io.metersphere.system.utils.SessionUtils;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@ -36,10 +36,10 @@ import java.util.List;
|
||||||
@RequestMapping("/project/log")
|
@RequestMapping("/project/log")
|
||||||
public class ProjectLogController {
|
public class ProjectLogController {
|
||||||
|
|
||||||
@Autowired
|
@Resource
|
||||||
private SimpleUserService simpleUserService;
|
private SimpleUserService simpleUserService;
|
||||||
|
|
||||||
@Autowired
|
@Resource
|
||||||
private OperationLogService operationLogService;
|
private OperationLogService operationLogService;
|
||||||
|
|
||||||
@GetMapping("/user/list/{projectId}")
|
@GetMapping("/user/list/{projectId}")
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package io.metersphere.plan.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TestPlanGroupCountDTO {
|
||||||
|
private String groupId;
|
||||||
|
private long count;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.metersphere.plan.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TestPlanResourceExecResultDTO {
|
||||||
|
private String testPlanId;
|
||||||
|
private String execResult;
|
||||||
|
private String testPlanGroupId;
|
||||||
|
}
|
|
@ -26,6 +26,9 @@ public class TestPlanTableRequest extends BasePageRequest {
|
||||||
@Schema(description = "通过Keyword过滤出的测试子计划的测试计划组id")
|
@Schema(description = "通过Keyword过滤出的测试子计划的测试计划组id")
|
||||||
private List<String> keywordFilterIds;
|
private List<String> keywordFilterIds;
|
||||||
|
|
||||||
|
@Schema(description = "通过其他条件查询出来的,必须要包含的测试计划ID")
|
||||||
|
private List<String> innerIds;
|
||||||
|
|
||||||
public String getSortString() {
|
public String getSortString() {
|
||||||
if (StringUtils.isEmpty(super.getSortString())) {
|
if (StringUtils.isEmpty(super.getSortString())) {
|
||||||
return "t.update_time desc";
|
return "t.update_time desc";
|
||||||
|
|
|
@ -16,8 +16,6 @@ public class TestPlanResponse extends TestPlanStatisticsResponse {
|
||||||
private long num;
|
private long num;
|
||||||
@Schema(description = "名称")
|
@Schema(description = "名称")
|
||||||
private String name;
|
private String name;
|
||||||
@Schema(description = "状态")
|
|
||||||
private String status;
|
|
||||||
@Schema(description = "测试计划类型 测试计划/测试计划组")
|
@Schema(description = "测试计划类型 测试计划/测试计划组")
|
||||||
private String type;
|
private String type;
|
||||||
@Schema(description = "标签")
|
@Schema(description = "标签")
|
||||||
|
|
|
@ -2,6 +2,8 @@ package io.metersphere.plan.dto.response;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import io.metersphere.plan.serializer.CustomRateSerializer;
|
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.dto.request.schedule.BaseScheduleConfigRequest;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
@ -16,7 +18,8 @@ public class TestPlanStatisticsResponse {
|
||||||
|
|
||||||
@Schema(description = "测试计划ID")
|
@Schema(description = "测试计划ID")
|
||||||
private String id;
|
private String id;
|
||||||
|
@Schema(description = "测试计划状态")
|
||||||
|
private String status;
|
||||||
@Schema(description = "测试计划通过阈值{0-100}")
|
@Schema(description = "测试计划通过阈值{0-100}")
|
||||||
@JsonSerialize(using = CustomRateSerializer.class)
|
@JsonSerialize(using = CustomRateSerializer.class)
|
||||||
private Double passThreshold;
|
private Double passThreshold;
|
||||||
|
@ -33,31 +36,70 @@ public class TestPlanStatisticsResponse {
|
||||||
* 执行进度中的用例数量统计
|
* 执行进度中的用例数量统计
|
||||||
*/
|
*/
|
||||||
@Schema(description = "成功用例数量")
|
@Schema(description = "成功用例数量")
|
||||||
private Integer successCount = 0;
|
private long successCount = 0;
|
||||||
@Schema(description = "失败用例数量")
|
@Schema(description = "失败用例数量")
|
||||||
private Integer errorCount = 0;
|
private long errorCount = 0;
|
||||||
@Schema(description = "误报用例数量")
|
@Schema(description = "误报用例数量")
|
||||||
private Integer fakeErrorCount = 0;
|
private long fakeErrorCount = 0;
|
||||||
@Schema(description = "阻塞用例数量")
|
@Schema(description = "阻塞用例数量")
|
||||||
private Integer blockCount = 0;
|
private long blockCount = 0;
|
||||||
@Schema(description = "未执行用例数量")
|
@Schema(description = "未执行用例数量")
|
||||||
private Integer pendingCount = 0;
|
private long pendingCount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用例数中用例数量统计
|
* 用例数中用例数量统计
|
||||||
*/
|
*/
|
||||||
@Schema(description = "用例总数")
|
@Schema(description = "用例总数")
|
||||||
private Integer caseTotal = 0;
|
private long caseTotal = 0;
|
||||||
@Schema(description = "功能用例数量")
|
@Schema(description = "功能用例数量")
|
||||||
private Integer functionalCaseCount = 0;
|
private long functionalCaseCount = 0;
|
||||||
@Schema(description = "接口用例数量")
|
@Schema(description = "接口用例数量")
|
||||||
private Integer apiCaseCount = 0;
|
private long apiCaseCount = 0;
|
||||||
@Schema(description = "接口场景数量")
|
@Schema(description = "接口场景数量")
|
||||||
private Integer apiScenarioCount = 0;
|
private long apiScenarioCount = 0;
|
||||||
@Schema(description = "缺陷数量")
|
@Schema(description = "缺陷数量")
|
||||||
private Integer bugCount = 0;
|
private long bugCount = 0;
|
||||||
@Schema(description = "定时任务配置")
|
@Schema(description = "定时任务配置")
|
||||||
private BaseScheduleConfigRequest scheduleConfig;
|
private BaseScheduleConfigRequest scheduleConfig;
|
||||||
@Schema(description = "定时任务下一次执行时间")
|
@Schema(description = "定时任务下一次执行时间")
|
||||||
private Long nextTriggerTime;
|
private Long nextTriggerTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算测试计划状态
|
||||||
|
* 未开始:执行进度0%
|
||||||
|
* 进行中:执行进度不到100%
|
||||||
|
* 已完成:执行进度100%
|
||||||
|
*/
|
||||||
|
public void calculateStatus() {
|
||||||
|
if (this.successCount == 0 && errorCount == 0 && fakeErrorCount == 0 && blockCount == 0) {
|
||||||
|
this.status = TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED;
|
||||||
|
} else if (this.pendingCount == 0) {
|
||||||
|
this.status = TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED;
|
||||||
|
} else {
|
||||||
|
this.status = TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculateCaseTotal() {
|
||||||
|
this.caseTotal = this.functionalCaseCount + this.apiCaseCount + this.apiScenarioCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculatePassRate() {
|
||||||
|
this.passRate = RateCalculateUtils.divWithPrecision(this.successCount, this.caseTotal, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculateExecuteRate() {
|
||||||
|
this.executeRate = RateCalculateUtils.divWithPrecision(this.successCount - this.pendingCount, this.caseTotal, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculateAllNumber(TestPlanStatisticsResponse childResponse) {
|
||||||
|
this.functionalCaseCount += childResponse.getFunctionalCaseCount();
|
||||||
|
this.apiCaseCount += childResponse.getApiCaseCount();
|
||||||
|
this.apiScenarioCount += childResponse.getApiScenarioCount();
|
||||||
|
this.successCount += childResponse.getSuccessCount();
|
||||||
|
this.errorCount += childResponse.getErrorCount();
|
||||||
|
this.fakeErrorCount += childResponse.getFakeErrorCount();
|
||||||
|
this.blockCount += childResponse.getBlockCount();
|
||||||
|
this.pendingCount += childResponse.getPendingCount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package io.metersphere.plan.mapper;
|
package io.metersphere.plan.mapper;
|
||||||
|
|
||||||
import io.metersphere.api.domain.ApiTestCase;
|
|
||||||
import io.metersphere.api.dto.definition.ApiDefinitionDTO;
|
import io.metersphere.api.dto.definition.ApiDefinitionDTO;
|
||||||
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
|
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
|
||||||
import io.metersphere.functional.dto.ProjectOptionDTO;
|
import io.metersphere.functional.dto.ProjectOptionDTO;
|
||||||
|
@ -8,6 +7,7 @@ import io.metersphere.plan.domain.TestPlanApiCase;
|
||||||
import io.metersphere.plan.dto.ApiCaseModuleDTO;
|
import io.metersphere.plan.dto.ApiCaseModuleDTO;
|
||||||
import io.metersphere.plan.dto.ResourceSelectParam;
|
import io.metersphere.plan.dto.ResourceSelectParam;
|
||||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||||
|
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||||
import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRequest;
|
import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanApiCaseModuleRequest;
|
import io.metersphere.plan.dto.request.TestPlanApiCaseModuleRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
|
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
|
||||||
|
@ -75,4 +75,5 @@ public interface ExtTestPlanApiCaseMapper {
|
||||||
|
|
||||||
List<TestPlanApiCase> getPlanApiCaseNotDeletedByCollectionIds(@Param("collectionIds") List<String> collectionIds);
|
List<TestPlanApiCase> getPlanApiCaseNotDeletedByCollectionIds(@Param("collectionIds") List<String> collectionIds);
|
||||||
|
|
||||||
|
List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -717,4 +717,23 @@
|
||||||
WHERE t.test_plan_id = #{request.testPlanId} AND atc.deleted = false
|
WHERE t.test_plan_id = #{request.testPlanId} AND atc.deleted = false
|
||||||
<include refid="queryWhereConditionByBatchQueryRequest"/>
|
<include refid="queryWhereConditionByBatchQueryRequest"/>
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectDistinctExecResult" resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
|
||||||
|
select distinct resource.test_plan_id AS testPlanId,
|
||||||
|
CASE
|
||||||
|
WHEN resource.last_exec_result = 'BLOCKED'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'FAKE_ERROR'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'ERROR'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'SUCCESS'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
ELSE 'PENDING'
|
||||||
|
END AS execResult,
|
||||||
|
test_plan.group_id AS testPlanGroupId
|
||||||
|
from test_plan_api_case resource
|
||||||
|
INNER JOIN test_plan ON test_plan.id = resource.test_plan_id
|
||||||
|
where test_plan.project_id = #{projectId}
|
||||||
|
AND test_plan.status != 'ARCHIVED'
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -6,6 +6,7 @@ import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||||
import io.metersphere.plan.dto.ApiScenarioModuleDTO;
|
import io.metersphere.plan.dto.ApiScenarioModuleDTO;
|
||||||
import io.metersphere.plan.dto.ResourceSelectParam;
|
import io.metersphere.plan.dto.ResourceSelectParam;
|
||||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||||
|
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||||
import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
|
import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest;
|
import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
||||||
|
@ -69,4 +70,6 @@ public interface ExtTestPlanApiScenarioMapper {
|
||||||
List<String> getIdsByReportIdAndCollectionId(@Param("testPlanReportId") String testPlanReportId, @Param("collectionId") String collectionId);
|
List<String> getIdsByReportIdAndCollectionId(@Param("testPlanReportId") String testPlanReportId, @Param("collectionId") String collectionId);
|
||||||
|
|
||||||
List<TestPlanApiScenario> getPlanScenarioCaseNotDeletedByCollectionIds(@Param("collectionIds") List<String> collectionIds);
|
List<TestPlanApiScenario> getPlanScenarioCaseNotDeletedByCollectionIds(@Param("collectionIds") List<String> collectionIds);
|
||||||
|
|
||||||
|
List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,6 +485,25 @@
|
||||||
</foreach>
|
</foreach>
|
||||||
AND a.deleted = false
|
AND a.deleted = false
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectDistinctExecResult" resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
|
||||||
|
select distinct resource.test_plan_id AS testPlanId,
|
||||||
|
CASE
|
||||||
|
WHEN resource.last_exec_result = 'BLOCKED'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'FAKE_ERROR'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'ERROR'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'SUCCESS'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
ELSE 'PENDING'
|
||||||
|
END AS execResult,
|
||||||
|
test_plan.group_id AS testPlanGroupId
|
||||||
|
from test_plan_api_scenario resource
|
||||||
|
INNER JOIN test_plan ON test_plan.id = resource.test_plan_id
|
||||||
|
where test_plan.project_id = #{projectId}
|
||||||
|
AND test_plan.status != 'ARCHIVED'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<update id="batchUpdateExecutor">
|
<update id="batchUpdateExecutor">
|
||||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.functional.dto.ProjectOptionDTO;
|
||||||
import io.metersphere.plan.domain.TestPlanFunctionalCase;
|
import io.metersphere.plan.domain.TestPlanFunctionalCase;
|
||||||
import io.metersphere.plan.dto.ResourceSelectParam;
|
import io.metersphere.plan.dto.ResourceSelectParam;
|
||||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||||
|
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||||
import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
|
import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanCaseModuleRequest;
|
import io.metersphere.plan.dto.request.TestPlanCaseModuleRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanCaseRequest;
|
import io.metersphere.plan.dto.request.TestPlanCaseRequest;
|
||||||
|
@ -67,4 +68,5 @@ public interface ExtTestPlanFunctionalCaseMapper {
|
||||||
|
|
||||||
List<TestPlanFunctionalCase> getPlanCaseNotDeletedByCollectionIds(@Param("collectionIds") List<String> collectionIds);
|
List<TestPlanFunctionalCase> getPlanCaseNotDeletedByCollectionIds(@Param("collectionIds") List<String> collectionIds);
|
||||||
|
|
||||||
|
List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,4 +578,23 @@
|
||||||
GROUP BY
|
GROUP BY
|
||||||
test_plan_functional_case.test_plan_collection_id
|
test_plan_functional_case.test_plan_collection_id
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectDistinctExecResult" resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
|
||||||
|
select distinct resource.test_plan_id AS testPlanId,
|
||||||
|
CASE
|
||||||
|
WHEN resource.last_exec_result = 'BLOCKED'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'FAKE_ERROR'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'ERROR'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
WHEN resource.last_exec_result = 'SUCCESS'
|
||||||
|
THEN 'COMPLETED'
|
||||||
|
ELSE 'PENDING'
|
||||||
|
END AS execResult,
|
||||||
|
test_plan.group_id AS testPlanGroupId
|
||||||
|
from test_plan_functional_case resource
|
||||||
|
INNER JOIN test_plan ON test_plan.id = resource.test_plan_id
|
||||||
|
where test_plan.project_id = #{projectId}
|
||||||
|
AND test_plan.status != 'ARCHIVED'
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -2,6 +2,7 @@ package io.metersphere.plan.mapper;
|
||||||
|
|
||||||
import io.metersphere.plan.domain.TestPlan;
|
import io.metersphere.plan.domain.TestPlan;
|
||||||
import io.metersphere.plan.dto.TestPlanExecuteHisDTO;
|
import io.metersphere.plan.dto.TestPlanExecuteHisDTO;
|
||||||
|
import io.metersphere.plan.dto.TestPlanGroupCountDTO;
|
||||||
import io.metersphere.plan.dto.TestPlanQueryConditions;
|
import io.metersphere.plan.dto.TestPlanQueryConditions;
|
||||||
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
|
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanExecuteHisPageRequest;
|
import io.metersphere.plan.dto.request.TestPlanExecuteHisPageRequest;
|
||||||
|
@ -66,4 +67,8 @@ public interface ExtTestPlanMapper {
|
||||||
List<TestPlanExecuteHisDTO> listHis(@Param("request")TestPlanExecuteHisPageRequest request);
|
List<TestPlanExecuteHisDTO> listHis(@Param("request")TestPlanExecuteHisPageRequest request);
|
||||||
|
|
||||||
List<String> selectGroupIdByKeyword(@Param("projectId") String projectId, @Param("keyword") String keyword);
|
List<String> selectGroupIdByKeyword(@Param("projectId") String projectId, @Param("keyword") String keyword);
|
||||||
|
|
||||||
|
List<TestPlanGroupCountDTO> countByGroupPlan(String projectId);
|
||||||
|
|
||||||
|
List<String> selectIdByProjectIdAndWithoutList(@Param("projectId") String projectId, @Param("withoutList") List<String> withoutList);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,13 @@
|
||||||
</if>
|
</if>
|
||||||
)
|
)
|
||||||
</if>
|
</if>
|
||||||
|
<if test="request.innerIds != null and request.innerIds.size() > 0">
|
||||||
|
and t.id in
|
||||||
|
<foreach collection="request.innerIds" item="id" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
|
||||||
<choose>
|
<choose>
|
||||||
<when test='request.searchMode == "AND"'>
|
<when test='request.searchMode == "AND"'>
|
||||||
AND <include refid="queryCombine"/>
|
AND <include refid="queryCombine"/>
|
||||||
|
@ -483,6 +490,27 @@
|
||||||
or t.tags like concat('%', #{keyword}, '%')
|
or t.tags like concat('%', #{keyword}, '%')
|
||||||
)
|
)
|
||||||
</select>
|
</select>
|
||||||
|
<select id="countByGroupPlan" resultType="io.metersphere.plan.dto.TestPlanGroupCountDTO">
|
||||||
|
SELECT group_id AS groupId, count(id) AS count
|
||||||
|
FROM test_plan
|
||||||
|
WHERE project_id = #{0}
|
||||||
|
AND status != 'ARCHIVED'
|
||||||
|
AND group_id != 'NONE'
|
||||||
|
GROUP BY group_id;
|
||||||
|
</select>
|
||||||
|
<select id="selectIdByProjectIdAndWithoutList" resultType="java.lang.String">
|
||||||
|
SELECT id
|
||||||
|
FROM test_plan
|
||||||
|
WHERE project_id = #{projectId}
|
||||||
|
AND status != 'ARCHIVED'
|
||||||
|
AND group_id = 'NONE'
|
||||||
|
<if test="withoutList != null and withoutList.size() != ''">
|
||||||
|
AND id not in
|
||||||
|
<foreach collection="withoutList" item="id" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
<update id="batchUpdate">
|
<update id="batchUpdate">
|
||||||
update test_plan
|
update test_plan
|
||||||
|
|
|
@ -118,6 +118,10 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
||||||
@Resource
|
@Resource
|
||||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||||
|
|
||||||
|
public List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId) {
|
||||||
|
return extTestPlanApiCaseMapper.selectDistinctExecResult(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
||||||
TestPlanApiCaseExample example = new TestPlanApiCaseExample();
|
TestPlanApiCaseExample example = new TestPlanApiCaseExample();
|
||||||
|
|
|
@ -112,6 +112,10 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanConfigService testPlanConfigService;
|
private TestPlanConfigService testPlanConfigService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId) {
|
||||||
|
return extTestPlanApiScenarioMapper.selectDistinctExecResult(projectId);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
||||||
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
|
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package io.metersphere.plan.service;
|
package io.metersphere.plan.service;
|
||||||
|
|
||||||
|
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||||
import io.metersphere.plan.mapper.ExtTestPlanMapper;
|
import io.metersphere.plan.mapper.ExtTestPlanMapper;
|
||||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||||
import io.metersphere.sdk.constants.ModuleConstants;
|
import io.metersphere.sdk.constants.ModuleConstants;
|
||||||
|
import io.metersphere.sdk.constants.TestPlanConstants;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.Translator;
|
import io.metersphere.sdk.util.Translator;
|
||||||
import io.metersphere.system.domain.TestPlanModuleExample;
|
import io.metersphere.system.domain.TestPlanModuleExample;
|
||||||
|
@ -12,6 +14,11 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class TestPlanBaseUtilsService {
|
public class TestPlanBaseUtilsService {
|
||||||
|
@ -40,4 +47,64 @@ public class TestPlanBaseUtilsService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Map<String, List<String>>> parseExecResult(List<TestPlanResourceExecResultDTO> execResults) {
|
||||||
|
Map<String, Map<String, List<String>>> returnMap = new HashMap<>();
|
||||||
|
for (TestPlanResourceExecResultDTO execResult : execResults) {
|
||||||
|
String groupId = execResult.getTestPlanGroupId();
|
||||||
|
String planId = execResult.getTestPlanId();
|
||||||
|
|
||||||
|
Map<String, List<String>> planMap;
|
||||||
|
if (returnMap.containsKey(groupId)) {
|
||||||
|
planMap = returnMap.get(groupId);
|
||||||
|
List<String> resultList;
|
||||||
|
if (planMap.containsKey(planId)) {
|
||||||
|
resultList = planMap.get(planId);
|
||||||
|
} else {
|
||||||
|
resultList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
resultList.add(execResult.getExecResult());
|
||||||
|
planMap.put(planId, resultList);
|
||||||
|
} else {
|
||||||
|
planMap = new HashMap<>();
|
||||||
|
List<String> resultList = new ArrayList<>();
|
||||||
|
resultList.add(execResult.getExecResult());
|
||||||
|
planMap.put(planId, resultList);
|
||||||
|
}
|
||||||
|
returnMap.put(groupId, planMap);
|
||||||
|
}
|
||||||
|
return returnMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String calculateTestPlanStatus(List<String> resultList) {
|
||||||
|
//同时包含两种状态:进行中
|
||||||
|
if (resultList.size() == 1) {
|
||||||
|
if (resultList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
|
||||||
|
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED;
|
||||||
|
} else
|
||||||
|
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED;
|
||||||
|
} else {
|
||||||
|
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String calculateStatusByChildren(List<String> childStatus) {
|
||||||
|
// 首先去重
|
||||||
|
childStatus = childStatus.stream().distinct().toList();
|
||||||
|
|
||||||
|
/*
|
||||||
|
1:全部都未开始 则为未开始
|
||||||
|
2:全部都已完成 则为已完成
|
||||||
|
3:包含进行中 则为进行中
|
||||||
|
4:未开始+已完成:进行中
|
||||||
|
*/
|
||||||
|
if (childStatus.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
|
||||||
|
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY;
|
||||||
|
} else if (childStatus.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED) && childStatus.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
|
||||||
|
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY;
|
||||||
|
} else if (childStatus.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
|
||||||
|
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED;
|
||||||
|
} else {
|
||||||
|
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
||||||
testPlan.setPos(testPlanGroupService.getNextOrder(targetId));
|
testPlan.setPos(testPlanGroupService.getNextOrder(targetId));
|
||||||
testPlan.setActualEndTime(null);
|
testPlan.setActualEndTime(null);
|
||||||
testPlan.setActualStartTime(null);
|
testPlan.setActualStartTime(null);
|
||||||
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_NOT_ARCHIVED);
|
||||||
testPlanMapper.insert(testPlan);
|
testPlanMapper.insert(testPlan);
|
||||||
|
|
||||||
//测试配置信息
|
//测试配置信息
|
||||||
|
@ -286,7 +286,7 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
||||||
testPlanGroup.setPos(testPlanGroupService.getNextOrder(originalGroup.getGroupId()));
|
testPlanGroup.setPos(testPlanGroupService.getNextOrder(originalGroup.getGroupId()));
|
||||||
testPlanGroup.setActualEndTime(null);
|
testPlanGroup.setActualEndTime(null);
|
||||||
testPlanGroup.setActualStartTime(null);
|
testPlanGroup.setActualStartTime(null);
|
||||||
testPlanGroup.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
testPlanGroup.setStatus(TestPlanConstants.TEST_PLAN_STATUS_NOT_ARCHIVED);
|
||||||
testPlanMapper.insert(testPlanGroup);
|
testPlanMapper.insert(testPlanGroup);
|
||||||
|
|
||||||
//测试配置信息
|
//测试配置信息
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.metersphere.bug.mapper.BugRelationCaseMapper;
|
||||||
import io.metersphere.bug.service.BugCommonService;
|
import io.metersphere.bug.service.BugCommonService;
|
||||||
import io.metersphere.plan.dto.TestPlanBugCaseDTO;
|
import io.metersphere.plan.dto.TestPlanBugCaseDTO;
|
||||||
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
||||||
|
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||||
import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
|
import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanBugPageRequest;
|
import io.metersphere.plan.dto.request.TestPlanBugPageRequest;
|
||||||
import io.metersphere.plan.dto.response.TestPlanBugPageResponse;
|
import io.metersphere.plan.dto.response.TestPlanBugPageResponse;
|
||||||
|
@ -62,6 +63,11 @@ public class TestPlanBugService extends TestPlanResourceService {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNextOrder(String testPlanId) {
|
public long getNextOrder(String testPlanId) {
|
||||||
|
|
|
@ -137,6 +137,10 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId) {
|
||||||
|
return extTestPlanFunctionalCaseMapper.selectDistinctExecResult(projectId);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public long copyResource(String originalTestPlanId, String newTestPlanId, Map<String, String> oldCollectionIdToNewCollectionId, String operator, long operatorTime) {
|
public long copyResource(String originalTestPlanId, String newTestPlanId, Map<String, String> oldCollectionIdToNewCollectionId, String operator, long operatorTime) {
|
||||||
List<TestPlanFunctionalCase> copyList = new ArrayList<>();
|
List<TestPlanFunctionalCase> copyList = new ArrayList<>();
|
||||||
|
|
|
@ -5,6 +5,8 @@ import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||||
import io.metersphere.plan.domain.TestPlan;
|
import io.metersphere.plan.domain.TestPlan;
|
||||||
import io.metersphere.plan.domain.TestPlanExample;
|
import io.metersphere.plan.domain.TestPlanExample;
|
||||||
|
import io.metersphere.plan.dto.TestPlanGroupCountDTO;
|
||||||
|
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||||
import io.metersphere.plan.dto.request.TestPlanTableRequest;
|
import io.metersphere.plan.dto.request.TestPlanTableRequest;
|
||||||
import io.metersphere.plan.dto.response.TestPlanResponse;
|
import io.metersphere.plan.dto.response.TestPlanResponse;
|
||||||
import io.metersphere.plan.mapper.ExtTestPlanMapper;
|
import io.metersphere.plan.mapper.ExtTestPlanMapper;
|
||||||
|
@ -23,6 +25,8 @@ import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -43,6 +47,8 @@ public class TestPlanManagementService {
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanStatisticsService testPlanStatisticsService;
|
private TestPlanStatisticsService testPlanStatisticsService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private TestPlanBaseUtilsService testPlanBaseUtilsService;
|
||||||
|
@Resource
|
||||||
private TestPlanMapper testPlanMapper;
|
private TestPlanMapper testPlanMapper;
|
||||||
|
|
||||||
public Map<String, Long> moduleCount(TestPlanTableRequest request) {
|
public Map<String, Long> moduleCount(TestPlanTableRequest request) {
|
||||||
|
@ -69,12 +75,13 @@ public class TestPlanManagementService {
|
||||||
return PageUtils.setPageInfo(page, this.list(request));
|
return PageUtils.setPageInfo(page, this.list(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
private void initDefaultFilter(TestPlanTableRequest request) {
|
private void initDefaultFilter(TestPlanTableRequest request) {
|
||||||
|
|
||||||
|
List<String> defaultStatusList = new ArrayList<>();
|
||||||
|
defaultStatusList.add(TestPlanConstants.TEST_PLAN_STATUS_NOT_ARCHIVED);
|
||||||
if (request.getFilter() == null || !request.getFilter().containsKey("status")) {
|
if (request.getFilter() == null || !request.getFilter().containsKey("status")) {
|
||||||
List<String> defaultStatusList = new ArrayList<>();
|
|
||||||
defaultStatusList.add(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
|
||||||
defaultStatusList.add(TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY);
|
|
||||||
defaultStatusList.add(TestPlanConstants.TEST_PLAN_STATUS_COMPLETED);
|
|
||||||
if (request.getFilter() == null) {
|
if (request.getFilter() == null) {
|
||||||
request.setFilter(new HashMap<>() {{
|
request.setFilter(new HashMap<>() {{
|
||||||
this.put("status", defaultStatusList);
|
this.put("status", defaultStatusList);
|
||||||
|
@ -82,6 +89,76 @@ public class TestPlanManagementService {
|
||||||
} else {
|
} else {
|
||||||
request.getFilter().put("status", defaultStatusList);
|
request.getFilter().put("status", defaultStatusList);
|
||||||
}
|
}
|
||||||
|
} else if (!request.getFilter().get("status").contains(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) {
|
||||||
|
List<String> statusList = request.getFilter().get("status");
|
||||||
|
request.getFilter().put("status", defaultStatusList);
|
||||||
|
if (statusList.size() < 3) {
|
||||||
|
List<String> innerIdList = new ArrayList<>();
|
||||||
|
// 条件过滤
|
||||||
|
Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class);
|
||||||
|
// 将当前项目下未归档的测试计划结果查询出来,进行下列符合条件的筛选
|
||||||
|
List<TestPlanResourceExecResultDTO> execResults = new ArrayList<>();
|
||||||
|
beansOfType.forEach((k, v) -> execResults.addAll(v.selectDistinctExecResult(request.getProjectId())));
|
||||||
|
Map<String, Map<String, List<String>>> testPlanExecMap = testPlanBaseUtilsService.parseExecResult(execResults);
|
||||||
|
Map<String, Long> groupCountMap = extTestPlanMapper.countByGroupPlan(request.getProjectId())
|
||||||
|
.stream().collect(Collectors.toMap(TestPlanGroupCountDTO::getGroupId, TestPlanGroupCountDTO::getCount));
|
||||||
|
|
||||||
|
List<String> completedTestPlanIds = new ArrayList<>();
|
||||||
|
List<String> preparedTestPlanIds = new ArrayList<>();
|
||||||
|
List<String> underwayTestPlanIds = new ArrayList<>();
|
||||||
|
testPlanExecMap.forEach((groupId, planMap) -> {
|
||||||
|
if (StringUtils.equalsIgnoreCase(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||||
|
planMap.forEach((planId, resultList) -> {
|
||||||
|
String result = testPlanBaseUtilsService.calculateTestPlanStatus(resultList);
|
||||||
|
if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
|
||||||
|
completedTestPlanIds.add(planId);
|
||||||
|
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
|
||||||
|
underwayTestPlanIds.add(planId);
|
||||||
|
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
|
||||||
|
preparedTestPlanIds.add(planId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
long itemPlanCount = groupCountMap.getOrDefault(groupId, 0L);
|
||||||
|
List<String> itemStatusList = new ArrayList<>();
|
||||||
|
if (itemPlanCount > planMap.size()) {
|
||||||
|
// 存在未执行或者没有用例的测试计划。 此时这种测试计划的状态为未开始
|
||||||
|
itemStatusList.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED);
|
||||||
|
}
|
||||||
|
planMap.forEach((planId, resultList) -> {
|
||||||
|
itemStatusList.add(testPlanBaseUtilsService.calculateTestPlanStatus(resultList));
|
||||||
|
});
|
||||||
|
String groupStatus = testPlanBaseUtilsService.calculateStatusByChildren(itemStatusList);
|
||||||
|
if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
|
||||||
|
completedTestPlanIds.add(groupId);
|
||||||
|
} else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
|
||||||
|
underwayTestPlanIds.add(groupId);
|
||||||
|
} else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
|
||||||
|
preparedTestPlanIds.add(groupId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
testPlanExecMap = null;
|
||||||
|
if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
|
||||||
|
// 已完成
|
||||||
|
innerIdList.addAll(completedTestPlanIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
|
||||||
|
// 进行中
|
||||||
|
innerIdList.addAll(underwayTestPlanIds);
|
||||||
|
}
|
||||||
|
if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
|
||||||
|
// 未开始 有一些测试计划/计划组没有用例 / 测试计划, 在上面的计算中无法过滤。所以用排除法机型处理
|
||||||
|
List<String> withoutList = new ArrayList<>();
|
||||||
|
withoutList.addAll(completedTestPlanIds);
|
||||||
|
withoutList.addAll(underwayTestPlanIds);
|
||||||
|
innerIdList.addAll(extTestPlanMapper.selectIdByProjectIdAndWithoutList(request.getProjectId(), withoutList));
|
||||||
|
withoutList = null;
|
||||||
|
}
|
||||||
|
request.setInnerIds(innerIdList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(request.getKeyword())) {
|
if (StringUtils.isNotBlank(request.getKeyword())) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.metersphere.plan.domain.TestPlanCollectionExample;
|
||||||
import io.metersphere.plan.dto.ModuleSelectDTO;
|
import io.metersphere.plan.dto.ModuleSelectDTO;
|
||||||
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
||||||
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
||||||
|
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO;
|
||||||
import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
|
import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
|
||||||
import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
|
import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
|
||||||
import io.metersphere.plan.dto.response.TestPlanAssociationResponse;
|
import io.metersphere.plan.dto.response.TestPlanAssociationResponse;
|
||||||
|
@ -65,6 +66,7 @@ public abstract class TestPlanResourceService extends TestPlanSortService {
|
||||||
|
|
||||||
public abstract long copyResource(String originalTestPlanId, String newTestPlanId, Map<String, String> oldCollectionIdToNewCollectionId, String operator, long operatorTime);
|
public abstract long copyResource(String originalTestPlanId, String newTestPlanId, Map<String, String> oldCollectionIdToNewCollectionId, String operator, long operatorTime);
|
||||||
|
|
||||||
|
public abstract List<TestPlanResourceExecResultDTO> selectDistinctExecResult(String projectId);
|
||||||
/**
|
/**
|
||||||
* 关联用例
|
* 关联用例
|
||||||
*
|
*
|
||||||
|
@ -124,6 +126,4 @@ public abstract class TestPlanResourceService extends TestPlanSortService {
|
||||||
AssociateCaseDTO associateCaseDTO = new AssociateCaseDTO(excludeIds, selectIds, moduleIds);
|
AssociateCaseDTO associateCaseDTO = new AssociateCaseDTO(excludeIds, selectIds, moduleIds);
|
||||||
return associateCaseDTO;
|
return associateCaseDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class TestPlanSendNoticeService {
|
||||||
public TestPlanDTO sendAddNotice(TestPlanCreateRequest request) {
|
public TestPlanDTO sendAddNotice(TestPlanCreateRequest request) {
|
||||||
TestPlanDTO dto = new TestPlanDTO();
|
TestPlanDTO dto = new TestPlanDTO();
|
||||||
BeanUtils.copyBean(dto, request);
|
BeanUtils.copyBean(dto, request);
|
||||||
dto.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
dto.setStatus(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED);
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.plan.dto.TestPlanExecuteHisDTO;
|
||||||
import io.metersphere.plan.dto.request.*;
|
import io.metersphere.plan.dto.request.*;
|
||||||
import io.metersphere.plan.dto.response.TestPlanDetailResponse;
|
import io.metersphere.plan.dto.response.TestPlanDetailResponse;
|
||||||
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||||
|
import io.metersphere.plan.dto.response.TestPlanStatisticsResponse;
|
||||||
import io.metersphere.plan.enums.ExecuteMethod;
|
import io.metersphere.plan.enums.ExecuteMethod;
|
||||||
import io.metersphere.plan.job.TestPlanScheduleJob;
|
import io.metersphere.plan.job.TestPlanScheduleJob;
|
||||||
import io.metersphere.plan.mapper.*;
|
import io.metersphere.plan.mapper.*;
|
||||||
|
@ -102,7 +103,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
|
|
||||||
private static final int MAX_TAG_SIZE = 10;
|
private static final int MAX_TAG_SIZE = 10;
|
||||||
|
|
||||||
@Autowired
|
@Resource
|
||||||
private TestPlanReportService testPlanReportService;
|
private TestPlanReportService testPlanReportService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,7 +152,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
createTestPlan.setUpdateUser(operator);
|
createTestPlan.setUpdateUser(operator);
|
||||||
createTestPlan.setCreateTime(operateTime);
|
createTestPlan.setCreateTime(operateTime);
|
||||||
createTestPlan.setUpdateTime(operateTime);
|
createTestPlan.setUpdateTime(operateTime);
|
||||||
createTestPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
createTestPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_NOT_ARCHIVED);
|
||||||
|
|
||||||
TestPlanConfig testPlanConfig = new TestPlanConfig();
|
TestPlanConfig testPlanConfig = new TestPlanConfig();
|
||||||
testPlanConfig.setTestPlanId(createTestPlan.getId());
|
testPlanConfig.setTestPlanId(createTestPlan.getId());
|
||||||
|
@ -395,18 +396,20 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试计划归档
|
* 测试计划归档
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @param userId
|
|
||||||
*/
|
*/
|
||||||
public void archived(String id, String userId) {
|
public void archived(String id, String userId) {
|
||||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id);
|
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(id);
|
||||||
|
|
||||||
if (StringUtils.equalsAnyIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
if (StringUtils.equalsAnyIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||||
|
//判断当前计划组下是否都已完成 (由于算法原因,只需要校验当前测试计划组即可)
|
||||||
|
if (!this.isTestPlanCompleted(id)) {
|
||||||
|
throw new MSException(Translator.get("test_plan.group.not_plan"));
|
||||||
|
}
|
||||||
//测试计划组归档
|
//测试计划组归档
|
||||||
updateGroupStatus(testPlan.getId(), userId);
|
updateCompletedGroupStatus(testPlan.getId(), userId);
|
||||||
//关闭定时任务
|
//关闭定时任务
|
||||||
this.deleteScheduleConfig(testPlan.getId());
|
this.deleteScheduleConfig(testPlan.getId());
|
||||||
} else if (StringUtils.equals(testPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_COMPLETED) && StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
} else if (this.isTestPlanCompleted(id) && StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||||
//测试计划
|
//测试计划
|
||||||
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||||
testPlan.setUpdateUser(userId);
|
testPlan.setUpdateUser(userId);
|
||||||
|
@ -417,7 +420,37 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
} else {
|
} else {
|
||||||
throw new MSException(Translator.get("test_plan.cannot.archived"));
|
throw new MSException(Translator.get("test_plan.cannot.archived"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试计划归档
|
||||||
|
*/
|
||||||
|
public boolean archived(TestPlan testPlan, String userId) {
|
||||||
|
if (!this.isTestPlanCompleted(testPlan.getId())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (StringUtils.equalsAnyIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||||
|
//测试计划组归档
|
||||||
|
updateCompletedGroupStatus(testPlan.getId(), userId);
|
||||||
|
//关闭定时任务
|
||||||
|
this.deleteScheduleConfig(testPlan.getId());
|
||||||
|
return true;
|
||||||
|
} else if (StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||||
|
//测试计划
|
||||||
|
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||||
|
testPlan.setUpdateUser(userId);
|
||||||
|
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||||
|
testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||||
|
//关闭定时任务
|
||||||
|
this.deleteScheduleConfig(testPlan.getId());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTestPlanCompleted(String testPlanId) {
|
||||||
|
TestPlanStatisticsResponse statisticsResponse = testPlanStatisticsService.calculateRate(Collections.singletonList(testPlanId)).getFirst();
|
||||||
|
return StringUtils.equalsIgnoreCase(statisticsResponse.getStatus(), TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -430,14 +463,20 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
List<String> batchArchivedIds = request.getSelectIds();
|
List<String> batchArchivedIds = request.getSelectIds();
|
||||||
if (CollectionUtils.isNotEmpty(batchArchivedIds)) {
|
if (CollectionUtils.isNotEmpty(batchArchivedIds)) {
|
||||||
TestPlanExample example = new TestPlanExample();
|
TestPlanExample example = new TestPlanExample();
|
||||||
example.createCriteria().andIdIn(batchArchivedIds);
|
example.createCriteria().andIdIn(batchArchivedIds).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||||
List<TestPlan> archivedPlanList = testPlanMapper.selectByExample(example).stream().filter(
|
List<TestPlan> testPlanList = testPlanMapper.selectByExample(example).stream().filter(
|
||||||
testPlan -> StringUtils.equalsAnyIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)
|
testPlan -> StringUtils.equalsAnyIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)
|
||||||
|| (StringUtils.equals(testPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_COMPLETED) && StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID))
|
|| (StringUtils.equalsIgnoreCase(testPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID))
|
||||||
).collect(Collectors.toList());
|
).toList();
|
||||||
archivedPlanList.forEach(item -> this.archived(item.getId(), currentUser));
|
List<TestPlan> archivedPlanGroupList = new ArrayList<>();
|
||||||
|
testPlanList.forEach(item -> {
|
||||||
|
boolean result = this.archived(item, currentUser);
|
||||||
|
if (result) {
|
||||||
|
archivedPlanGroupList.add(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
//日志
|
//日志
|
||||||
testPlanLogService.saveBatchLog(archivedPlanList, currentUser, "/test-plan/batch-archived", HttpMethodConstants.POST.name(), OperationLogType.ARCHIVED.name(), "archive");
|
testPlanLogService.saveBatchLog(archivedPlanGroupList, currentUser, "/test-plan/batch-archived", HttpMethodConstants.POST.name(), OperationLogType.ARCHIVED.name(), "archive");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,17 +486,14 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
* @param id
|
* @param id
|
||||||
* @param userId
|
* @param userId
|
||||||
*/
|
*/
|
||||||
private void updateGroupStatus(String id, String userId) {
|
private void updateCompletedGroupStatus(String id, String userId) {
|
||||||
TestPlanExample example = new TestPlanExample();
|
TestPlanExample example = new TestPlanExample();
|
||||||
example.createCriteria().andGroupIdEqualTo(id);
|
example.createCriteria().andGroupIdEqualTo(id);
|
||||||
List<TestPlan> testPlanList = testPlanMapper.selectByExample(example);
|
List<TestPlan> testPlanList = testPlanMapper.selectByExample(example);
|
||||||
if (CollectionUtils.isEmpty(testPlanList)) {
|
if (CollectionUtils.isEmpty(testPlanList)) {
|
||||||
throw new MSException(Translator.get("test_plan.group.not_plan"));
|
throw new MSException(Translator.get("test_plan.group.not_plan"));
|
||||||
}
|
}
|
||||||
List<String> ids = testPlanList.stream().filter(item -> StringUtils.equalsIgnoreCase(item.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_COMPLETED)).map(TestPlan::getId).collect(Collectors.toList());
|
List<String> ids = testPlanList.stream().map(TestPlan::getId).collect(Collectors.toList());
|
||||||
if (CollectionUtils.isEmpty(ids)) {
|
|
||||||
throw new MSException(Translator.get("test_plan.group.not_plan"));
|
|
||||||
}
|
|
||||||
ids.add(id);
|
ids.add(id);
|
||||||
extTestPlanMapper.batchUpdateStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED, userId, System.currentTimeMillis(), ids);
|
extTestPlanMapper.batchUpdateStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED, userId, System.currentTimeMillis(), ids);
|
||||||
}
|
}
|
||||||
|
@ -772,37 +808,6 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// private void updateTestPlanStatus(String testPlanId) {
|
|
||||||
// Map<String, Long> caseExecResultCount = new HashMap<>();
|
|
||||||
// Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class);
|
|
||||||
// beansOfType.forEach((k, v) -> {
|
|
||||||
// Map<String, Long> map = v.caseExecResultCount(testPlanId);
|
|
||||||
// map.forEach((key, value) -> {
|
|
||||||
// if (value != 0) {
|
|
||||||
// caseExecResultCount.merge(key, value, Long::sum);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// String testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY;
|
|
||||||
// if (MapUtils.isEmpty(caseExecResultCount)) {
|
|
||||||
// // 没有任何执行结果: 状态是未开始
|
|
||||||
// testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
|
||||||
// extTestPlanMapper.clearActualEndTime(testPlanId);
|
|
||||||
// } else if (caseExecResultCount.size() == 1 && caseExecResultCount.containsKey(ExecStatus.PENDING.name()) && caseExecResultCount.get(ExecStatus.PENDING.name()) > 0) {
|
|
||||||
// // 执行结果只有未开始: 状态是未开始
|
|
||||||
// testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_PREPARED;
|
|
||||||
// extTestPlanMapper.clearActualEndTime(testPlanId);
|
|
||||||
// } else if (!caseExecResultCount.containsKey(ExecStatus.PENDING.name())) {
|
|
||||||
// // 执行结果没有未开始: 已完成
|
|
||||||
// testPlanFinalStatus = TestPlanConstants.TEST_PLAN_STATUS_COMPLETED;
|
|
||||||
// extTestPlanMapper.setActualEndTime(testPlanId, System.currentTimeMillis());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// this.updateTestPlanStatusAndGroupStatus(testPlanId, testPlanFinalStatus);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public TestPlanOperationResponse sort(PosRequest request, LogInsertModule logInsertModule) {
|
public TestPlanOperationResponse sort(PosRequest request, LogInsertModule logInsertModule) {
|
||||||
testPlanGroupService.sort(request);
|
testPlanGroupService.sort(request);
|
||||||
testPlanLogService.saveMoveLog(testPlanMapper.selectByPrimaryKey(request.getMoveId()), request.getMoveId(), logInsertModule);
|
testPlanLogService.saveMoveLog(testPlanMapper.selectByPrimaryKey(request.getMoveId()), request.getMoveId(), logInsertModule);
|
||||||
|
|
|
@ -4,7 +4,6 @@ import io.metersphere.plan.domain.*;
|
||||||
import io.metersphere.plan.dto.response.TestPlanBugPageResponse;
|
import io.metersphere.plan.dto.response.TestPlanBugPageResponse;
|
||||||
import io.metersphere.plan.dto.response.TestPlanStatisticsResponse;
|
import io.metersphere.plan.dto.response.TestPlanStatisticsResponse;
|
||||||
import io.metersphere.plan.mapper.*;
|
import io.metersphere.plan.mapper.*;
|
||||||
import io.metersphere.plan.utils.RateCalculateUtils;
|
|
||||||
import io.metersphere.sdk.constants.ExecStatus;
|
import io.metersphere.sdk.constants.ExecStatus;
|
||||||
import io.metersphere.sdk.constants.ResultStatus;
|
import io.metersphere.sdk.constants.ResultStatus;
|
||||||
import io.metersphere.sdk.constants.ScheduleResourceType;
|
import io.metersphere.sdk.constants.ScheduleResourceType;
|
||||||
|
@ -16,6 +15,7 @@ import io.metersphere.system.mapper.ScheduleMapper;
|
||||||
import io.metersphere.system.utils.ScheduleUtils;
|
import io.metersphere.system.utils.ScheduleUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -41,6 +41,8 @@ public class TestPlanStatisticsService {
|
||||||
private ExtTestPlanBugMapper extTestPlanBugMapper;
|
private ExtTestPlanBugMapper extTestPlanBugMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ScheduleMapper scheduleMapper;
|
private ScheduleMapper scheduleMapper;
|
||||||
|
@Resource
|
||||||
|
private TestPlanBaseUtilsService testPlanBaseUtilsService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计划/计划组的用例统计数据
|
* 计划/计划组的用例统计数据
|
||||||
|
@ -71,92 +73,160 @@ public class TestPlanStatisticsService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Map<String, TestPlanConfig> selectConfig(List<String> testPlanIds) {
|
||||||
* 计划/计划组的{通过率, 执行进度}统计数据
|
|
||||||
*
|
|
||||||
* @param planIds 计划ID集合
|
|
||||||
*/
|
|
||||||
public List<TestPlanStatisticsResponse> calculateRate(List<String> planIds) {
|
|
||||||
// 查出子计划
|
|
||||||
TestPlanExample testPlanExample = new TestPlanExample();
|
|
||||||
testPlanExample.createCriteria().andGroupIdIn(planIds);
|
|
||||||
List<TestPlan> childrenPlan = testPlanMapper.selectByExample(testPlanExample);
|
|
||||||
childrenPlan.forEach(item -> planIds.add(item.getId()));
|
|
||||||
|
|
||||||
List<TestPlanStatisticsResponse> planStatisticsResponses = new ArrayList<>();
|
|
||||||
/*
|
|
||||||
* 1. 查询计划下的用例数据集合
|
|
||||||
* 2. 根据执行结果统计(结果小数保留两位)
|
|
||||||
*/
|
|
||||||
// 计划的更多配置
|
|
||||||
TestPlanConfigExample example = new TestPlanConfigExample();
|
TestPlanConfigExample example = new TestPlanConfigExample();
|
||||||
example.createCriteria().andTestPlanIdIn(planIds);
|
example.createCriteria().andTestPlanIdIn(testPlanIds);
|
||||||
List<TestPlanConfig> testPlanConfigList = testPlanConfigMapper.selectByExample(example);
|
List<TestPlanConfig> testPlanConfigList = testPlanConfigMapper.selectByExample(example);
|
||||||
Map<String, TestPlanConfig> planConfigMap = testPlanConfigList.stream().collect(Collectors.toMap(TestPlanConfig::getTestPlanId, p -> p));
|
return testPlanConfigList.stream().collect(Collectors.toMap(TestPlanConfig::getTestPlanId, p -> p));
|
||||||
// 关联的用例数据
|
}
|
||||||
Map<String, List<TestPlanFunctionalCase>> planFunctionalCaseMap = getFunctionalCaseMapByPlanIds(planIds);
|
|
||||||
Map<String, List<TestPlanApiCase>> planApiCaseMap = getApiCaseMapByPlanIds(planIds);
|
|
||||||
Map<String, List<TestPlanApiScenario>> planApiScenarioMap = getApiScenarioByPlanIds(planIds);
|
|
||||||
|
|
||||||
//查询定时任务
|
private Map<String, Schedule> selectSchedule(List<String> testPlanIds) {
|
||||||
ScheduleExample scheduleExample = new ScheduleExample();
|
ScheduleExample scheduleExample = new ScheduleExample();
|
||||||
scheduleExample.createCriteria().andResourceIdIn(planIds).andResourceTypeEqualTo(ScheduleResourceType.TEST_PLAN.name());
|
scheduleExample.createCriteria().andResourceIdIn(testPlanIds).andResourceTypeEqualTo(ScheduleResourceType.TEST_PLAN.name());
|
||||||
List<Schedule> schedules = scheduleMapper.selectByExample(scheduleExample);
|
List<Schedule> schedules = scheduleMapper.selectByExample(scheduleExample);
|
||||||
Map<String, Schedule> scheduleMap = schedules.stream().collect(Collectors.toMap(Schedule::getResourceId, t -> t));
|
return schedules.stream().collect(Collectors.toMap(Schedule::getResourceId, t -> t));
|
||||||
|
}
|
||||||
|
|
||||||
planIds.forEach(planId -> {
|
/**
|
||||||
TestPlanStatisticsResponse statisticsResponse = new TestPlanStatisticsResponse();
|
* 计划/计划组的{通过率, 执行进度, 状态}统计数据
|
||||||
statisticsResponse.setId(planId);
|
*
|
||||||
|
*/
|
||||||
|
public List<TestPlanStatisticsResponse> calculateRate(List<String> paramIds) {
|
||||||
|
// 查出所有计划
|
||||||
|
TestPlanExample testPlanExample = new TestPlanExample();
|
||||||
|
testPlanExample.createCriteria().andIdIn(paramIds);
|
||||||
|
List<TestPlan> paramTestPlanList = testPlanMapper.selectByExample(testPlanExample);
|
||||||
|
testPlanExample.clear();
|
||||||
|
testPlanExample.createCriteria().andGroupIdIn(paramIds);
|
||||||
|
List<TestPlan> childrenTestPlan = testPlanMapper.selectByExample(testPlanExample);
|
||||||
|
paramTestPlanList.removeAll(childrenTestPlan);
|
||||||
|
List<String> allTestPlanIdList = new ArrayList<>();
|
||||||
|
allTestPlanIdList.addAll(paramTestPlanList.stream().map(TestPlan::getId).toList());
|
||||||
|
allTestPlanIdList.addAll(childrenTestPlan.stream().map(TestPlan::getId).toList());
|
||||||
|
|
||||||
// 测试计划组没有测试计划配置。同理,也不用参与用例等数据的计算
|
Map<TestPlan, List<TestPlan>> groupTestPlanMap = new HashMap<>();
|
||||||
if (planConfigMap.containsKey(planId)) {
|
for (TestPlan testPlan : paramTestPlanList) {
|
||||||
statisticsResponse.setPassThreshold(planConfigMap.get(planId).getPassThreshold());
|
List<TestPlan> children = new ArrayList<>();
|
||||||
// 功能用例分组统计开始 (为空时, 默认为未执行)
|
for (TestPlan child : childrenTestPlan) {
|
||||||
List<TestPlanFunctionalCase> functionalCases = planFunctionalCaseMap.get(planId);
|
if (StringUtils.equalsIgnoreCase(child.getGroupId(), testPlan.getId())) {
|
||||||
statisticsResponse.setFunctionalCaseCount(CollectionUtils.isNotEmpty(functionalCases) ? functionalCases.size() : 0);
|
children.add(child);
|
||||||
Map<String, Long> functionalCaseResultCountMap = CollectionUtils.isEmpty(functionalCases) ? new HashMap<>(16) : functionalCases.stream().collect(
|
|
||||||
Collectors.groupingBy(functionalCase -> Optional.ofNullable(functionalCase.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting()));
|
|
||||||
// 接口用例分组统计开始 (为空时, 默认为未执行)
|
|
||||||
List<TestPlanApiCase> apiCases = planApiCaseMap.get(planId);
|
|
||||||
statisticsResponse.setApiCaseCount(CollectionUtils.isNotEmpty(apiCases) ? apiCases.size() : 0);
|
|
||||||
Map<String, Long> apiCaseResultCountMap = CollectionUtils.isEmpty(apiCases) ? new HashMap<>(16) : apiCases.stream().collect(
|
|
||||||
Collectors.groupingBy(apiCase -> Optional.ofNullable(apiCase.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting()));
|
|
||||||
// 接口场景用例分组统计开始 (为空时, 默认为未执行)
|
|
||||||
List<TestPlanApiScenario> apiScenarios = planApiScenarioMap.get(planId);
|
|
||||||
statisticsResponse.setApiScenarioCount(CollectionUtils.isNotEmpty(apiScenarios) ? apiScenarios.size() : 0);
|
|
||||||
Map<String, Long> apiScenarioResultCountMap = CollectionUtils.isEmpty(apiScenarios) ? new HashMap<>(16) : apiScenarios.stream().collect(
|
|
||||||
Collectors.groupingBy(apiScenario -> Optional.ofNullable(apiScenario.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting()));
|
|
||||||
// 用例数据汇总
|
|
||||||
statisticsResponse.setSuccessCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.SUCCESS.name()));
|
|
||||||
statisticsResponse.setErrorCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.ERROR.name()));
|
|
||||||
statisticsResponse.setFakeErrorCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.FAKE_ERROR.name()));
|
|
||||||
statisticsResponse.setBlockCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.BLOCKED.name()));
|
|
||||||
statisticsResponse.setPendingCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ExecStatus.PENDING.name()));
|
|
||||||
statisticsResponse.setCaseTotal(statisticsResponse.getFunctionalCaseCount() + statisticsResponse.getApiCaseCount() + statisticsResponse.getApiScenarioCount());
|
|
||||||
// 通过率 {通过用例数/总用例数} && 执行进度 {非未执行的用例数/总用例数}
|
|
||||||
statisticsResponse.setPassRate(RateCalculateUtils.divWithPrecision(statisticsResponse.getSuccessCount(), statisticsResponse.getCaseTotal(), 2));
|
|
||||||
statisticsResponse.setExecuteRate(RateCalculateUtils.divWithPrecision(statisticsResponse.getCaseTotal() - statisticsResponse.getPendingCount(), statisticsResponse.getCaseTotal(), 2));
|
|
||||||
}
|
|
||||||
planStatisticsResponses.add(statisticsResponse);
|
|
||||||
|
|
||||||
//定时任务
|
|
||||||
if (scheduleMap.containsKey(planId)) {
|
|
||||||
Schedule schedule = scheduleMap.get(planId);
|
|
||||||
BaseScheduleConfigRequest request = new BaseScheduleConfigRequest();
|
|
||||||
request.setEnable(schedule.getEnable());
|
|
||||||
request.setCron(schedule.getValue());
|
|
||||||
request.setResourceId(planId);
|
|
||||||
if (schedule.getConfig() != null) {
|
|
||||||
request.setRunConfig(JSON.parseObject(schedule.getConfig(), Map.class));
|
|
||||||
}
|
|
||||||
statisticsResponse.setScheduleConfig(request);
|
|
||||||
if (schedule.getEnable()) {
|
|
||||||
statisticsResponse.setNextTriggerTime(ScheduleUtils.getNextTriggerTime(schedule.getValue()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
groupTestPlanMap.put(testPlan, children);
|
||||||
|
childrenTestPlan.removeAll(children);
|
||||||
|
}
|
||||||
|
childrenTestPlan = null;
|
||||||
|
paramTestPlanList = null;
|
||||||
|
|
||||||
|
List<TestPlanStatisticsResponse> returnResponse = new ArrayList<>();
|
||||||
|
|
||||||
|
// 计划的更多配置
|
||||||
|
Map<String, TestPlanConfig> planConfigMap = this.selectConfig(allTestPlanIdList);
|
||||||
|
// 关联的用例数据
|
||||||
|
Map<String, List<TestPlanFunctionalCase>> planFunctionalCaseMap = getFunctionalCaseMapByPlanIds(allTestPlanIdList);
|
||||||
|
Map<String, List<TestPlanApiCase>> planApiCaseMap = getApiCaseMapByPlanIds(allTestPlanIdList);
|
||||||
|
Map<String, List<TestPlanApiScenario>> planApiScenarioMap = getApiScenarioByPlanIds(allTestPlanIdList);
|
||||||
|
//查询定时任务
|
||||||
|
Map<String, Schedule> scheduleMap = this.selectSchedule(allTestPlanIdList);
|
||||||
|
|
||||||
|
groupTestPlanMap.forEach((rootPlan, children) -> {
|
||||||
|
TestPlanStatisticsResponse rootResponse = this.genTestPlanStatisticsResponse(rootPlan, planConfigMap, planFunctionalCaseMap, planApiCaseMap, planApiScenarioMap, scheduleMap);
|
||||||
|
List<TestPlanStatisticsResponse> childrenResponse = new ArrayList<>();
|
||||||
|
if (!CollectionUtils.isEmpty(children)) {
|
||||||
|
List<String> childStatus = new ArrayList<>();
|
||||||
|
children.forEach(child -> {
|
||||||
|
TestPlanStatisticsResponse childResponse = this.genTestPlanStatisticsResponse(child, planConfigMap, planFunctionalCaseMap, planApiCaseMap, planApiScenarioMap, scheduleMap);
|
||||||
|
childResponse.calculateStatus();
|
||||||
|
childStatus.add(childResponse.getStatus());
|
||||||
|
//添加到rootResponse中
|
||||||
|
rootResponse.calculateAllNumber(childResponse);
|
||||||
|
childrenResponse.add(childResponse);
|
||||||
|
});
|
||||||
|
rootResponse.calculateCaseTotal();
|
||||||
|
rootResponse.calculatePassRate();
|
||||||
|
rootResponse.calculateExecuteRate();
|
||||||
|
rootResponse.setStatus(testPlanBaseUtilsService.calculateStatusByChildren(childStatus));
|
||||||
|
} else {
|
||||||
|
rootResponse.calculateCaseTotal();
|
||||||
|
rootResponse.calculatePassRate();
|
||||||
|
rootResponse.calculateExecuteRate();
|
||||||
|
rootResponse.calculateStatus();
|
||||||
|
}
|
||||||
|
returnResponse.add(rootResponse);
|
||||||
|
returnResponse.addAll(childrenResponse);
|
||||||
});
|
});
|
||||||
return planStatisticsResponses;
|
return returnResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Long> countApiScenarioExecResultMap(List<TestPlanApiScenario> apiScenarios) {
|
||||||
|
return CollectionUtils.isEmpty(apiScenarios) ? new HashMap<>(16) : apiScenarios.stream().collect(
|
||||||
|
Collectors.groupingBy(apiScenario -> Optional.ofNullable(apiScenario.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Long> countApiTestCaseExecResultMap(List<TestPlanApiCase> apiCases) {
|
||||||
|
return CollectionUtils.isEmpty(apiCases) ? new HashMap<>(16) : apiCases.stream().collect(
|
||||||
|
Collectors.groupingBy(apiCase -> Optional.ofNullable(apiCase.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Long> countFunctionalCaseExecResultMap(List<TestPlanFunctionalCase> functionalCases) {
|
||||||
|
return CollectionUtils.isEmpty(functionalCases) ? new HashMap<>(16) : functionalCases.stream().collect(
|
||||||
|
Collectors.groupingBy(functionalCase -> Optional.ofNullable(functionalCase.getLastExecResult()).orElse(ExecStatus.PENDING.name()), Collectors.counting()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TestPlanStatisticsResponse genTestPlanStatisticsResponse(TestPlan child,
|
||||||
|
Map<String, TestPlanConfig> planConfigMap,
|
||||||
|
Map<String, List<TestPlanFunctionalCase>> planFunctionalCaseMap,
|
||||||
|
Map<String, List<TestPlanApiCase>> planApiCaseMap,
|
||||||
|
Map<String, List<TestPlanApiScenario>> planApiScenarioMap,
|
||||||
|
Map<String, Schedule> scheduleMap) {
|
||||||
|
String planId = child.getId();
|
||||||
|
TestPlanStatisticsResponse statisticsResponse = new TestPlanStatisticsResponse();
|
||||||
|
statisticsResponse.setId(planId);
|
||||||
|
// 测试计划组没有测试计划配置。同理,也不用参与用例等数据的计算
|
||||||
|
if (planConfigMap.containsKey(planId)) {
|
||||||
|
statisticsResponse.setPassThreshold(planConfigMap.get(planId).getPassThreshold());
|
||||||
|
|
||||||
|
List<TestPlanFunctionalCase> functionalCases = planFunctionalCaseMap.get(planId);
|
||||||
|
List<TestPlanApiCase> apiCases = planApiCaseMap.get(planId);
|
||||||
|
List<TestPlanApiScenario> apiScenarios = planApiScenarioMap.get(planId);
|
||||||
|
|
||||||
|
|
||||||
|
// 功能用例分组统计开始 (为空时, 默认为未执行)
|
||||||
|
Map<String, Long> functionalCaseResultCountMap = this.countFunctionalCaseExecResultMap(functionalCases);
|
||||||
|
// 接口用例分组统计开始 (为空时, 默认为未执行)
|
||||||
|
Map<String, Long> apiCaseResultCountMap = this.countApiTestCaseExecResultMap(apiCases);
|
||||||
|
// 接口场景用例分组统计开始 (为空时, 默认为未执行)
|
||||||
|
Map<String, Long> apiScenarioResultCountMap = this.countApiScenarioExecResultMap(apiScenarios);
|
||||||
|
|
||||||
|
// 用例数据汇总
|
||||||
|
statisticsResponse.setFunctionalCaseCount(CollectionUtils.isNotEmpty(functionalCases) ? functionalCases.size() : 0);
|
||||||
|
statisticsResponse.setApiCaseCount(CollectionUtils.isNotEmpty(apiCases) ? apiCases.size() : 0);
|
||||||
|
statisticsResponse.setApiScenarioCount(CollectionUtils.isNotEmpty(apiScenarios) ? apiScenarios.size() : 0);
|
||||||
|
statisticsResponse.setSuccessCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.SUCCESS.name()));
|
||||||
|
statisticsResponse.setErrorCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.ERROR.name()));
|
||||||
|
statisticsResponse.setFakeErrorCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.FAKE_ERROR.name()));
|
||||||
|
statisticsResponse.setBlockCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ResultStatus.BLOCKED.name()));
|
||||||
|
statisticsResponse.setPendingCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ExecStatus.PENDING.name()));
|
||||||
|
statisticsResponse.calculateCaseTotal();
|
||||||
|
statisticsResponse.calculatePassRate();
|
||||||
|
statisticsResponse.calculateExecuteRate();
|
||||||
|
}
|
||||||
|
//定时任务
|
||||||
|
if (scheduleMap.containsKey(planId)) {
|
||||||
|
Schedule schedule = scheduleMap.get(planId);
|
||||||
|
BaseScheduleConfigRequest request = new BaseScheduleConfigRequest();
|
||||||
|
request.setEnable(schedule.getEnable());
|
||||||
|
request.setCron(schedule.getValue());
|
||||||
|
request.setResourceId(planId);
|
||||||
|
if (schedule.getConfig() != null) {
|
||||||
|
request.setRunConfig(JSON.parseObject(schedule.getConfig(), Map.class));
|
||||||
|
}
|
||||||
|
statisticsResponse.setScheduleConfig(request);
|
||||||
|
if (schedule.getEnable()) {
|
||||||
|
statisticsResponse.setNextTriggerTime(ScheduleUtils.getNextTriggerTime(schedule.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return statisticsResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class RateCalculateUtils {
|
||||||
* @param precision 精度
|
* @param precision 精度
|
||||||
* @return rate
|
* @return rate
|
||||||
*/
|
*/
|
||||||
public static Double divWithPrecision(Integer molecular, Integer denominator, Integer precision) {
|
public static Double divWithPrecision(Long molecular, Long denominator, Integer precision) {
|
||||||
DecimalFormat rateFormat = new DecimalFormat("#.##");
|
DecimalFormat rateFormat = new DecimalFormat("#.##");
|
||||||
rateFormat.setMinimumFractionDigits(precision);
|
rateFormat.setMinimumFractionDigits(precision);
|
||||||
rateFormat.setMaximumFractionDigits(precision);
|
rateFormat.setMaximumFractionDigits(precision);
|
||||||
|
@ -38,4 +38,8 @@ public class RateCalculateUtils {
|
||||||
}
|
}
|
||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Double divWithPrecision(Integer molecular, Integer denominator, Integer precision) {
|
||||||
|
return divWithPrecision((long) molecular, (long) denominator, precision);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,9 @@ package io.metersphere.plan.controller;
|
||||||
import io.metersphere.api.domain.ApiScenario;
|
import io.metersphere.api.domain.ApiScenario;
|
||||||
import io.metersphere.api.domain.ApiTestCase;
|
import io.metersphere.api.domain.ApiTestCase;
|
||||||
import io.metersphere.functional.domain.FunctionalCase;
|
import io.metersphere.functional.domain.FunctionalCase;
|
||||||
|
import io.metersphere.functional.mapper.FunctionalCaseMapper;
|
||||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||||
import io.metersphere.plan.domain.TestPlan;
|
import io.metersphere.plan.domain.*;
|
||||||
import io.metersphere.plan.domain.TestPlanConfig;
|
|
||||||
import io.metersphere.plan.domain.TestPlanExample;
|
|
||||||
import io.metersphere.plan.domain.TestPlanReport;
|
|
||||||
import io.metersphere.plan.dto.request.*;
|
import io.metersphere.plan.dto.request.*;
|
||||||
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||||
import io.metersphere.plan.dto.response.TestPlanResponse;
|
import io.metersphere.plan.dto.response.TestPlanResponse;
|
||||||
|
@ -21,10 +19,7 @@ import io.metersphere.plan.utils.TestPlanTestUtils;
|
||||||
import io.metersphere.project.domain.Project;
|
import io.metersphere.project.domain.Project;
|
||||||
import io.metersphere.project.dto.filemanagement.request.FileModuleCreateRequest;
|
import io.metersphere.project.dto.filemanagement.request.FileModuleCreateRequest;
|
||||||
import io.metersphere.project.dto.filemanagement.request.FileModuleUpdateRequest;
|
import io.metersphere.project.dto.filemanagement.request.FileModuleUpdateRequest;
|
||||||
import io.metersphere.sdk.constants.ModuleConstants;
|
import io.metersphere.sdk.constants.*;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
|
||||||
import io.metersphere.sdk.constants.SessionConstants;
|
|
||||||
import io.metersphere.sdk.constants.TestPlanConstants;
|
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
@ -43,6 +38,7 @@ import io.metersphere.system.log.constants.OperationLogType;
|
||||||
import io.metersphere.system.mapper.TestPlanModuleMapper;
|
import io.metersphere.system.mapper.TestPlanModuleMapper;
|
||||||
import io.metersphere.system.service.CommonProjectService;
|
import io.metersphere.system.service.CommonProjectService;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
|
import io.metersphere.system.uid.NumGenerator;
|
||||||
import io.metersphere.system.utils.CheckLogModel;
|
import io.metersphere.system.utils.CheckLogModel;
|
||||||
import io.metersphere.system.utils.Pager;
|
import io.metersphere.system.utils.Pager;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
@ -138,9 +134,13 @@ public class TestPlanTests extends BaseTest {
|
||||||
private static final String URL_TEST_PLAN_BATCH_ARCHIVED = "/test-plan/batch-archived";
|
private static final String URL_TEST_PLAN_BATCH_ARCHIVED = "/test-plan/batch-archived";
|
||||||
private static final String URL_TEST_PLAN_BATCH_EDIT = "/test-plan/batch-edit";
|
private static final String URL_TEST_PLAN_BATCH_EDIT = "/test-plan/batch-edit";
|
||||||
|
|
||||||
|
private static String testPlanId6 = null;
|
||||||
|
private static String testPlanId16 = null;
|
||||||
private static String groupTestPlanId7 = null;
|
private static String groupTestPlanId7 = null;
|
||||||
private static String groupTestPlanId15 = null;
|
private static String groupTestPlanId15 = null;
|
||||||
private static String groupTestPlanId35 = null;
|
private static String groupTestPlanId35 = null;
|
||||||
|
private static String groupTestPlanId45 = null;
|
||||||
|
private static String groupTestPlanId46 = null;
|
||||||
|
|
||||||
private static List<String> rootPlanIds = new ArrayList<>();
|
private static List<String> rootPlanIds = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -154,6 +154,10 @@ public class TestPlanTests extends BaseTest {
|
||||||
private ExtTestPlanMapper extTestPlanMapper;
|
private ExtTestPlanMapper extTestPlanMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
|
private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private FunctionalCaseMapper functionalCaseMapper;
|
||||||
|
|
||||||
|
private static List<String> functionalCaseId = new ArrayList<>();
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void initTestData() {
|
public void initTestData() {
|
||||||
|
@ -542,7 +546,7 @@ public class TestPlanTests extends BaseTest {
|
||||||
String moduleId;
|
String moduleId;
|
||||||
if (i < 50) {
|
if (i < 50) {
|
||||||
moduleId = a1Node.getId();
|
moduleId = a1Node.getId();
|
||||||
if (i == 7 || i == 15 || i == 35) {
|
if (i == 7 || i == 15 || i == 35 || i == 45 || i == 46) {
|
||||||
request.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
|
request.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
|
||||||
}
|
}
|
||||||
a1NodeCount++;
|
a1NodeCount++;
|
||||||
|
@ -574,13 +578,20 @@ public class TestPlanTests extends BaseTest {
|
||||||
ResultHolder holder = JSON.parseObject(returnStr, ResultHolder.class);
|
ResultHolder holder = JSON.parseObject(returnStr, ResultHolder.class);
|
||||||
String returnId = JSON.parseObject(JSON.toJSONString(holder.getData()), TestPlan.class).getId();
|
String returnId = JSON.parseObject(JSON.toJSONString(holder.getData()), TestPlan.class).getId();
|
||||||
Assertions.assertNotNull(returnId);
|
Assertions.assertNotNull(returnId);
|
||||||
|
if (i == 6) {
|
||||||
if (i == 7) {
|
testPlanId6 = returnId;
|
||||||
|
} else if (i == 7) {
|
||||||
groupTestPlanId7 = returnId;
|
groupTestPlanId7 = returnId;
|
||||||
} else if (i == 15) {
|
} else if (i == 15) {
|
||||||
groupTestPlanId15 = returnId;
|
groupTestPlanId15 = returnId;
|
||||||
|
} else if (i == 16) {
|
||||||
|
testPlanId16 = returnId;
|
||||||
} else if (i == 35) {
|
} else if (i == 35) {
|
||||||
groupTestPlanId35 = returnId;
|
groupTestPlanId35 = returnId;
|
||||||
|
} else if (i == 45) {
|
||||||
|
groupTestPlanId45 = returnId;
|
||||||
|
} else if (i == 46) {
|
||||||
|
groupTestPlanId46 = returnId;
|
||||||
} else if (i > 700 && i < 725) {
|
} else if (i > 700 && i < 725) {
|
||||||
// 701-749 要创建测试计划报告 每个测试计划创建250个报告
|
// 701-749 要创建测试计划报告 每个测试计划创建250个报告
|
||||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
@ -676,6 +687,32 @@ public class TestPlanTests extends BaseTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testPlanId6关联两条已完成用例
|
||||||
|
this.associationFuncCase(testPlanId6, true);
|
||||||
|
// testPlanId16 关联未开始用例
|
||||||
|
this.associationFuncCase(testPlanId16, false);
|
||||||
|
//在groupTestPlanId35 和 groupTestPlanId46下面各创建2条测试计划并关联已完成用例
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
TestPlanCreateRequest itemRequest = new TestPlanCreateRequest();
|
||||||
|
itemRequest.setProjectId(project.getId());
|
||||||
|
itemRequest.setModuleId(a1Node.getId());
|
||||||
|
if (i > 2) {
|
||||||
|
itemRequest.setGroupId(groupTestPlanId46);
|
||||||
|
itemRequest.setName("testPlan_group46_" + i);
|
||||||
|
} else {
|
||||||
|
itemRequest.setGroupId(groupTestPlanId35);
|
||||||
|
itemRequest.setName("testPlan_group35_" + i);
|
||||||
|
}
|
||||||
|
itemRequest.setBaseAssociateCaseRequest(associateCaseRequest);
|
||||||
|
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_ADD, itemRequest);
|
||||||
|
String returnStr = mvcResult.getResponse().getContentAsString();
|
||||||
|
ResultHolder holder = JSON.parseObject(returnStr, ResultHolder.class);
|
||||||
|
Assertions.assertNotNull(JSON.parseObject(JSON.toJSONString(holder.getData()), TestPlan.class).getId());
|
||||||
|
String returnId = JSON.parseObject(JSON.toJSONString(holder.getData()), TestPlan.class).getId();
|
||||||
|
this.associationFuncCase(returnId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//校验Group数量
|
//校验Group数量
|
||||||
List<TestPlan> groupList = JSON.parseArray(
|
List<TestPlan> groupList = JSON.parseArray(
|
||||||
JSON.toJSONString(
|
JSON.toJSONString(
|
||||||
|
@ -683,7 +720,7 @@ public class TestPlanTests extends BaseTest {
|
||||||
this.requestGetWithOkAndReturn(String.format(URL_POST_TEST_PLAN_GROUP_LIST, project.getId()))
|
this.requestGetWithOkAndReturn(String.format(URL_POST_TEST_PLAN_GROUP_LIST, project.getId()))
|
||||||
.getResponse().getContentAsString(), ResultHolder.class).getData()),
|
.getResponse().getContentAsString(), ResultHolder.class).getData()),
|
||||||
TestPlan.class);
|
TestPlan.class);
|
||||||
Assertions.assertEquals(groupList.size(), 3);
|
Assertions.assertEquals(groupList.size(), 5);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
反例
|
反例
|
||||||
|
@ -717,7 +754,49 @@ public class TestPlanTests extends BaseTest {
|
||||||
this.checkTestPlanSortWithOutGroup();
|
this.checkTestPlanSortWithOutGroup();
|
||||||
this.checkTestPlanSortInGroup(groupTestPlanId7);
|
this.checkTestPlanSortInGroup(groupTestPlanId7);
|
||||||
this.checkTestPlanMoveToGroup();
|
this.checkTestPlanMoveToGroup();
|
||||||
this.checkTestPlanGroupArchived(groupTestPlanId7);
|
this.checkTestPlanGroupArchived(groupTestPlanId35);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void associationFuncCase(String testPlanId, boolean isFinish) {
|
||||||
|
FunctionalCase functionalCase = new FunctionalCase();
|
||||||
|
functionalCase.setProjectId(project.getId());
|
||||||
|
functionalCase.setName(String.valueOf(System.currentTimeMillis()));
|
||||||
|
functionalCase.setId(IDGenerator.nextStr());
|
||||||
|
functionalCase.setModuleId("root");
|
||||||
|
functionalCase.setTemplateId("root");
|
||||||
|
functionalCase.setReviewStatus("PREPARED");
|
||||||
|
functionalCase.setCaseEditType("STEP");
|
||||||
|
functionalCase.setPos(4096L);
|
||||||
|
functionalCase.setVersionId("root");
|
||||||
|
functionalCase.setRefId(functionalCase.getId());
|
||||||
|
functionalCase.setLastExecuteResult("PREPARED");
|
||||||
|
functionalCase.setDeleted(false);
|
||||||
|
functionalCase.setPublicCase(false);
|
||||||
|
functionalCase.setLatest(true);
|
||||||
|
functionalCase.setCreateUser("admin");
|
||||||
|
functionalCase.setCreateTime(System.currentTimeMillis());
|
||||||
|
functionalCase.setUpdateTime(System.currentTimeMillis());
|
||||||
|
functionalCase.setNum(NumGenerator.nextNum(project.getId(), ApplicationNumScope.CASE_MANAGEMENT));
|
||||||
|
functionalCaseMapper.insert(functionalCase);
|
||||||
|
functionalCaseId.add(functionalCase.getId());
|
||||||
|
|
||||||
|
TestPlanFunctionalCase testPlanFunctionalCase = new TestPlanFunctionalCase();
|
||||||
|
testPlanFunctionalCase.setId(IDGenerator.nextStr());
|
||||||
|
testPlanFunctionalCase.setTestPlanId(testPlanId);
|
||||||
|
testPlanFunctionalCase.setFunctionalCaseId(functionalCase.getId());
|
||||||
|
testPlanFunctionalCase.setCreateTime(System.currentTimeMillis());
|
||||||
|
testPlanFunctionalCase.setCreateUser("admin");
|
||||||
|
testPlanFunctionalCase.setPos(4096L);
|
||||||
|
testPlanFunctionalCase.setLastExecResult("SUCCESS");
|
||||||
|
testPlanFunctionalCase.setTestPlanCollectionId("root");
|
||||||
|
testPlanFunctionalCaseMapper.insert(testPlanFunctionalCase);
|
||||||
|
|
||||||
|
if (!isFinish) {
|
||||||
|
testPlanFunctionalCase.setId(IDGenerator.nextStr());
|
||||||
|
testPlanFunctionalCase.setPos(8192L);
|
||||||
|
testPlanFunctionalCase.setLastExecResult("PENDING");
|
||||||
|
testPlanFunctionalCaseMapper.insert(testPlanFunctionalCase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TestPlanResponse> selectByGroupId(String groupId) throws Exception {
|
private List<TestPlanResponse> selectByGroupId(String groupId) throws Exception {
|
||||||
|
@ -912,16 +991,16 @@ public class TestPlanTests extends BaseTest {
|
||||||
|
|
||||||
//判断组归档
|
//判断组归档
|
||||||
TestPlan updatePlan = new TestPlan();
|
TestPlan updatePlan = new TestPlan();
|
||||||
updatePlan.setId(groupTestPlanId35);
|
updatePlan.setId(groupTestPlanId45);
|
||||||
updatePlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
updatePlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||||
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
||||||
this.requestPost(URL_TEST_PLAN_BATCH_MOVE, request).andExpect(status().is5xxServerError());
|
this.requestPost(URL_TEST_PLAN_BATCH_MOVE, request).andExpect(status().is5xxServerError());
|
||||||
//改回来
|
//改回来
|
||||||
updatePlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
updatePlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_NOT_ARCHIVED);
|
||||||
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
||||||
|
|
||||||
//正式测试
|
//正式测试
|
||||||
groupId = groupTestPlanId35;
|
groupId = groupTestPlanId45;
|
||||||
request.setTargetId(groupId);
|
request.setTargetId(groupId);
|
||||||
this.requestPostWithOkAndReturn(URL_TEST_PLAN_BATCH_MOVE, request);
|
this.requestPostWithOkAndReturn(URL_TEST_PLAN_BATCH_MOVE, request);
|
||||||
List<TestPlanResponse> groups = this.selectByGroupId(groupId);
|
List<TestPlanResponse> groups = this.selectByGroupId(groupId);
|
||||||
|
@ -950,20 +1029,21 @@ public class TestPlanTests extends BaseTest {
|
||||||
// 测试计划组内的测试计划不能归档
|
// 测试计划组内的测试计划不能归档
|
||||||
List<TestPlanResponse> testPlanResponseList = this.selectByGroupId(groupId);
|
List<TestPlanResponse> testPlanResponseList = this.selectByGroupId(groupId);
|
||||||
TestPlanResponse cannotArchivedPlan = testPlanResponseList.getFirst();
|
TestPlanResponse cannotArchivedPlan = testPlanResponseList.getFirst();
|
||||||
testPlanMapper.updateByPrimaryKeySelective(new TestPlan() {{
|
|
||||||
this.setId(cannotArchivedPlan.getId());
|
|
||||||
this.setStatus(TestPlanConstants.TEST_PLAN_STATUS_COMPLETED);
|
|
||||||
}});
|
|
||||||
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, cannotArchivedPlan.getId())).andExpect(status().is5xxServerError());
|
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, cannotArchivedPlan.getId())).andExpect(status().is5xxServerError());
|
||||||
|
|
||||||
//归档测试组内的测试计划
|
//归档测试组内的测试计划
|
||||||
for (TestPlanResponse testPlanResponse : testPlanResponseList) {
|
|
||||||
testPlanMapper.updateByPrimaryKeySelective(new TestPlan() {{
|
|
||||||
this.setId(testPlanResponse.getId());
|
|
||||||
this.setStatus(TestPlanConstants.TEST_PLAN_STATUS_COMPLETED);
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
this.requestGetWithOk(String.format(URL_TEST_PLAN_ARCHIVED, groupId));
|
this.requestGetWithOk(String.format(URL_TEST_PLAN_ARCHIVED, groupId));
|
||||||
|
|
||||||
|
//归档不能归档的测试计划
|
||||||
|
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, rootPlanIds.getFirst())).andExpect(status().is5xxServerError());
|
||||||
|
|
||||||
|
//归档普通测试计划
|
||||||
|
this.requestGetWithOk(String.format(URL_TEST_PLAN_ARCHIVED, testPlanId6));
|
||||||
|
// testPlan6更改回去
|
||||||
|
TestPlan testPlan = new TestPlan();
|
||||||
|
testPlan.setId(testPlanId6);
|
||||||
|
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_NOT_ARCHIVED);
|
||||||
|
testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1003,11 +1083,104 @@ public class TestPlanTests extends BaseTest {
|
||||||
TestPlanTableRequest groupRequest = new TestPlanTableRequest();
|
TestPlanTableRequest groupRequest = new TestPlanTableRequest();
|
||||||
//查询游离态测试计划
|
//查询游离态测试计划
|
||||||
TestPlanTableRequest onlyPlanRequest = new TestPlanTableRequest();
|
TestPlanTableRequest onlyPlanRequest = new TestPlanTableRequest();
|
||||||
|
// 状态过滤的测试计划
|
||||||
|
TestPlanTableRequest statusRequest = new TestPlanTableRequest();
|
||||||
BeanUtils.copyBean(groupRequest, dataRequest);
|
BeanUtils.copyBean(groupRequest, dataRequest);
|
||||||
BeanUtils.copyBean(onlyPlanRequest, dataRequest);
|
BeanUtils.copyBean(onlyPlanRequest, dataRequest);
|
||||||
|
BeanUtils.copyBean(statusRequest, dataRequest);
|
||||||
groupRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
|
groupRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
|
||||||
onlyPlanRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
|
onlyPlanRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
|
||||||
|
|
||||||
|
|
||||||
|
//进行状态筛选 -- 空状态
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
999 - 1);
|
||||||
|
/*
|
||||||
|
现有数据状态:
|
||||||
|
已完成的 6 47(组)
|
||||||
|
进行中的 16
|
||||||
|
已归档的 35(组)
|
||||||
|
*/
|
||||||
|
//进行状态筛选 -- 未开始
|
||||||
|
statusRequest.setFilter(new HashMap<>() {{
|
||||||
|
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED));
|
||||||
|
}});
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
999 - 1 - 1 - 2);
|
||||||
|
//进行状态筛选 -- 已完成
|
||||||
|
statusRequest.setFilter(new HashMap<>() {{
|
||||||
|
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED));
|
||||||
|
}});
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
2);
|
||||||
|
//进行状态筛选 -- 进行中
|
||||||
|
statusRequest.setFilter(new HashMap<>() {{
|
||||||
|
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY));
|
||||||
|
}});
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
1);
|
||||||
|
//进行状态筛选 -- 已完成和未开始
|
||||||
|
statusRequest.setFilter(new HashMap<>() {{
|
||||||
|
this.put("status", new ArrayList<String>() {{
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED);
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED);
|
||||||
|
}});
|
||||||
|
}});
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
999 - 1 - 1);
|
||||||
|
//进行状态筛选 -- 已完成和进行中
|
||||||
|
statusRequest.setFilter(new HashMap<>() {{
|
||||||
|
this.put("status", new ArrayList<String>() {{
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED);
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY);
|
||||||
|
}});
|
||||||
|
}});
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
3);
|
||||||
|
//进行状态筛选 -- 进行中和未开始
|
||||||
|
statusRequest.setFilter(new HashMap<>() {{
|
||||||
|
this.put("status", new ArrayList<String>() {{
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY);
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED);
|
||||||
|
}});
|
||||||
|
}});
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
999 - 1 - 2);
|
||||||
|
//进行状态筛选 -- 已完成、未开始、进行中
|
||||||
|
statusRequest.setFilter(new HashMap<>() {{
|
||||||
|
this.put("status", new ArrayList<String>() {{
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY);
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED);
|
||||||
|
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED);
|
||||||
|
}});
|
||||||
|
}});
|
||||||
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
|
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
|
dataRequest.getCurrent(),
|
||||||
|
dataRequest.getPageSize(),
|
||||||
|
999 - 1);
|
||||||
|
|
||||||
BaseTreeNode a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1");
|
BaseTreeNode a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1");
|
||||||
BaseTreeNode a2Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a2");
|
BaseTreeNode a2Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a2");
|
||||||
BaseTreeNode a3Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a3");
|
BaseTreeNode a3Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a3");
|
||||||
|
@ -1024,6 +1197,7 @@ public class TestPlanTests extends BaseTest {
|
||||||
dataRequest.getCurrent(),
|
dataRequest.getCurrent(),
|
||||||
dataRequest.getPageSize(),
|
dataRequest.getPageSize(),
|
||||||
999 - 1);
|
999 - 1);
|
||||||
|
|
||||||
//查询归档的
|
//查询归档的
|
||||||
dataRequest.setFilter(new HashMap<>() {{
|
dataRequest.setFilter(new HashMap<>() {{
|
||||||
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED));
|
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED));
|
||||||
|
@ -1038,13 +1212,13 @@ public class TestPlanTests extends BaseTest {
|
||||||
URL_POST_TEST_PLAN_PAGE, groupRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
URL_POST_TEST_PLAN_PAGE, groupRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
dataRequest.getCurrent(),
|
dataRequest.getCurrent(),
|
||||||
dataRequest.getPageSize(),
|
dataRequest.getPageSize(),
|
||||||
3 - 1);
|
5 - 1);
|
||||||
//只查询计划
|
//只查询计划
|
||||||
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
|
||||||
URL_POST_TEST_PLAN_PAGE, onlyPlanRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
URL_POST_TEST_PLAN_PAGE, onlyPlanRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
|
||||||
dataRequest.getCurrent(),
|
dataRequest.getCurrent(),
|
||||||
dataRequest.getPageSize(),
|
dataRequest.getPageSize(),
|
||||||
996);
|
999 - 5);
|
||||||
|
|
||||||
//按照名称倒叙
|
//按照名称倒叙
|
||||||
dataRequest.setSort(new HashMap<>() {{
|
dataRequest.setSort(new HashMap<>() {{
|
||||||
|
@ -1243,17 +1417,17 @@ public class TestPlanTests extends BaseTest {
|
||||||
|
|
||||||
//修改a2节点下的数据(91,92)的所属测试计划组
|
//修改a2节点下的数据(91,92)的所属测试计划组
|
||||||
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_91").getId());
|
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_91").getId());
|
||||||
updateRequest.setGroupId(groupTestPlanId35);
|
updateRequest.setGroupId(groupTestPlanId45);
|
||||||
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
|
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
|
||||||
a2NodeCount--;
|
a2NodeCount--;
|
||||||
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_92").getId());
|
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_92").getId());
|
||||||
updateRequest.setGroupId(groupTestPlanId35);
|
updateRequest.setGroupId(groupTestPlanId45);
|
||||||
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
|
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
|
||||||
a2NodeCount--;
|
a2NodeCount--;
|
||||||
|
|
||||||
TestPlan updatePlan = new TestPlan();
|
TestPlan updatePlan = new TestPlan();
|
||||||
updatePlan.setId(groupTestPlanId7);
|
updatePlan.setId(groupTestPlanId7);
|
||||||
updatePlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_UNDERWAY);
|
updatePlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_NOT_ARCHIVED);
|
||||||
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
testPlanMapper.updateByPrimaryKeySelective(updatePlan);
|
||||||
//修改测试计划组信息
|
//修改测试计划组信息
|
||||||
updateRequest = testPlanTestService.generateUpdateRequest(groupTestPlanId7);
|
updateRequest = testPlanTestService.generateUpdateRequest(groupTestPlanId7);
|
||||||
|
@ -2113,25 +2287,15 @@ public class TestPlanTests extends BaseTest {
|
||||||
public void testArchived() throws Exception {
|
public void testArchived() throws Exception {
|
||||||
//计划 -- 首先状态不是已完成
|
//计划 -- 首先状态不是已完成
|
||||||
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_1")).andExpect(status().is5xxServerError());
|
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_1")).andExpect(status().is5xxServerError());
|
||||||
//更改状态再归档
|
|
||||||
TestPlan testPlan = new TestPlan();
|
|
||||||
testPlan.setId("wx_test_plan_id_1");
|
|
||||||
testPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_COMPLETED);
|
|
||||||
testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
|
||||||
this.requestGetWithOk(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_1"));
|
|
||||||
|
|
||||||
//计划组没有可归档的测试计划:
|
//计划组没有可归档的测试计划:
|
||||||
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_2")).andExpect(status().is5xxServerError());
|
this.requestGet(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_2")).andExpect(status().is5xxServerError());
|
||||||
this.requestGetWithOk(String.format(URL_TEST_PLAN_ARCHIVED, "wx_test_plan_id_5"));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(303)
|
@Order(303)
|
||||||
public void testCopy() throws Exception {
|
public void testCopy() throws Exception {
|
||||||
// 1. 已归档的不能再归档计划 无用例
|
// 1. 已归档的不能再归档计划 无用例
|
||||||
requestGet(String.format(URL_TEST_PLAN_COPY, "wx_test_plan_id_1")).andExpect(status().is5xxServerError());
|
requestGet(String.format(URL_TEST_PLAN_COPY, groupTestPlanId35)).andExpect(status().is5xxServerError());
|
||||||
|
|
||||||
|
|
||||||
// 2.计划 有用例
|
// 2.计划 有用例
|
||||||
MvcResult mvcResult1 = this.requestGetWithOkAndReturn(String.format(URL_TEST_PLAN_COPY, "wx_test_plan_id_4"));
|
MvcResult mvcResult1 = this.requestGetWithOkAndReturn(String.format(URL_TEST_PLAN_COPY, "wx_test_plan_id_4"));
|
||||||
|
|
Loading…
Reference in New Issue