feat(测试计划): 测试计划增加通过和未通过的查询条件筛选

This commit is contained in:
Jianguo-Genius 2024-12-02 16:59:25 +08:00 committed by 建国
parent c510277add
commit c61d571296
22 changed files with 884 additions and 181 deletions

View File

@ -22,4 +22,9 @@ public class TestPlanConstants {
public static final String TEST_PLAN_SHOW_STATUS_UNDERWAY = "UNDERWAY"; public static final String TEST_PLAN_SHOW_STATUS_UNDERWAY = "UNDERWAY";
//测试计划对外展示状态-已完成 //测试计划对外展示状态-已完成
public static final String TEST_PLAN_SHOW_STATUS_COMPLETED = "COMPLETED"; public static final String TEST_PLAN_SHOW_STATUS_COMPLETED = "COMPLETED";
//测试计划对外展示状态-通过
public static final String TEST_PLAN_SHOW_STATUS_PASSED = "PASSED";
//测试计划对外展示状态-未通过
public static final String TEST_PLAN_SHOW_STATUS_NOT_PASSED = "NOT_PASSED";
} }

View File

@ -1,9 +1,12 @@
package io.metersphere.sdk.util; package io.metersphere.sdk.util;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
public class SubListUtils { public class SubListUtils {
@ -28,4 +31,26 @@ public class SubListUtils {
} }
} }
public static <K, V> void dealForSubMap(Map<K, V> totalMap, int batchSize, Consumer<Map<K, V>> subFunc) {
if (MapUtils.isEmpty(totalMap)) {
return;
}
Map<K, V> dealMap = new LinkedHashMap<>(totalMap);
while (dealMap.size() > batchSize) {
Map<K, V> subMap = new LinkedHashMap<>();
dealMap.forEach((k, v) -> {
if (subMap.size() < batchSize) {
subMap.put(k, v);
}
});
subFunc.accept(subMap);
subMap.forEach(dealMap::remove);
}
if (MapUtils.isNotEmpty(dealMap)) {
subFunc.accept(dealMap);
}
}
} }

View File

@ -0,0 +1,167 @@
package io.metersphere.plan.dto;
import io.metersphere.sdk.constants.TestPlanConstants;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
@Data
public class TestPlanCalculationDTO {
private List<String> statusConditionList;
private List<String> passedConditionList;
private List<String> passedTestPlanIds = new ArrayList<>();
private List<String> passedItemTestPlanIds = new ArrayList<>();
private List<String> notPassedTestPlanIds = new ArrayList<>();
private List<String> notPassedItemTestPlanIds = new ArrayList<>();
private List<String> completedTestPlanIds = new ArrayList<>();
private List<String> completedItemTestPlanIds = new ArrayList<>();
private List<String> preparedTestPlanIds = new ArrayList<>();
private List<String> preparedItemTestPlanIds = new ArrayList<>();
private List<String> underwayTestPlanIds = new ArrayList<>();
private List<String> underwayItemTestPlanIds = new ArrayList<>();
public void addPassedTestPlanId(String testPlanId) {
if (!passedTestPlanIds.contains(testPlanId)) {
passedTestPlanIds.add(testPlanId);
}
}
public void addPassedItemTestPlanId(String testPlanId) {
if (!passedItemTestPlanIds.contains(testPlanId)) {
passedItemTestPlanIds.add(testPlanId);
}
}
public void addNotPassedTestPlanId(String testPlanId) {
if (!notPassedTestPlanIds.contains(testPlanId)) {
notPassedTestPlanIds.add(testPlanId);
}
}
public void addNotPassedItemTestPlanId(String testPlanId) {
if (!notPassedItemTestPlanIds.contains(testPlanId)) {
notPassedItemTestPlanIds.add(testPlanId);
}
}
public void addCompletedTestPlanId(String testPlanId) {
if (!completedTestPlanIds.contains(testPlanId)) {
completedTestPlanIds.add(testPlanId);
}
}
public void addCompletedItemTestPlanId(String testPlanId) {
if (!completedItemTestPlanIds.contains(testPlanId)) {
completedItemTestPlanIds.add(testPlanId);
}
}
public void addPreparedTestPlanId(String testPlanId) {
if (!preparedTestPlanIds.contains(testPlanId)) {
preparedTestPlanIds.add(testPlanId);
}
}
public void addPreparedItemTestPlanId(String testPlanId) {
if (!preparedItemTestPlanIds.contains(testPlanId)) {
preparedItemTestPlanIds.add(testPlanId);
}
}
public void addUnderwayTestPlanId(String testPlanId) {
if (!underwayTestPlanIds.contains(testPlanId)) {
underwayTestPlanIds.add(testPlanId);
}
}
public void addUnderwayItemTestPlanId(String testPlanId) {
if (!underwayItemTestPlanIds.contains(testPlanId)) {
underwayItemTestPlanIds.add(testPlanId);
}
}
public void merge(TestPlanCalculationDTO dto) {
passedTestPlanIds.addAll(dto.getPassedTestPlanIds());
notPassedTestPlanIds.addAll(dto.getNotPassedTestPlanIds());
completedTestPlanIds.addAll(dto.getCompletedTestPlanIds());
preparedTestPlanIds.addAll(dto.getPreparedTestPlanIds());
underwayTestPlanIds.addAll(dto.getUnderwayTestPlanIds());
passedItemTestPlanIds.addAll(dto.getPassedItemTestPlanIds());
notPassedItemTestPlanIds.addAll(dto.getNotPassedItemTestPlanIds());
completedItemTestPlanIds.addAll(dto.getCompletedItemTestPlanIds());
preparedItemTestPlanIds.addAll(dto.getPreparedItemTestPlanIds());
underwayItemTestPlanIds.addAll(dto.getUnderwayItemTestPlanIds());
}
public List<String> getConditionInnerId() {
List<String> passedConditionInnerId = new ArrayList<>();
List<String> statusConditionInnerId = new ArrayList<>();
if (CollectionUtils.isNotEmpty(passedConditionList)) {
passedConditionList.forEach(condition -> {
if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED)) {
passedConditionInnerId.addAll(this.passedTestPlanIds);
} else if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_NOT_PASSED)) {
passedConditionInnerId.addAll(this.notPassedTestPlanIds);
}
});
}
if (CollectionUtils.isNotEmpty(statusConditionList)) {
statusConditionList.forEach(status -> {
if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
statusConditionInnerId.addAll(this.completedTestPlanIds);
} else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
statusConditionInnerId.addAll(this.preparedTestPlanIds);
} else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
statusConditionInnerId.addAll(this.underwayTestPlanIds);
}
});
}
if (CollectionUtils.isNotEmpty(statusConditionInnerId) && CollectionUtils.isNotEmpty(passedConditionInnerId)) {
return statusConditionInnerId.stream().filter(passedConditionInnerId::contains).toList();
} else {
return ListUtils.union(statusConditionInnerId, passedConditionInnerId);
}
}
public List<String> getConditionItemPlanId() {
List<String> passedConditionInnerId = new ArrayList<>();
List<String> statusConditionInnerId = new ArrayList<>();
if (CollectionUtils.isNotEmpty(passedConditionList)) {
passedConditionList.forEach(condition -> {
if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED)) {
passedConditionInnerId.addAll(this.passedItemTestPlanIds);
} else if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_NOT_PASSED)) {
passedConditionInnerId.addAll(this.notPassedItemTestPlanIds);
}
});
}
if (CollectionUtils.isNotEmpty(statusConditionList)) {
statusConditionList.forEach(status -> {
if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
statusConditionInnerId.addAll(this.completedItemTestPlanIds);
} else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
statusConditionInnerId.addAll(this.preparedItemTestPlanIds);
} else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
statusConditionInnerId.addAll(this.underwayItemTestPlanIds);
}
});
}
if (CollectionUtils.isNotEmpty(statusConditionInnerId) && CollectionUtils.isNotEmpty(passedConditionInnerId)) {
return statusConditionInnerId.stream().filter(passedConditionInnerId::contains).toList();
} else {
return ListUtils.union(statusConditionInnerId, passedConditionInnerId);
}
}
}

View File

@ -43,6 +43,10 @@ public class TestPlanTableRequest extends BasePageRequest {
@Schema(description = "额外的子计划ID集合") @Schema(description = "额外的子计划ID集合")
private List<String> extraIncludeChildIds; private List<String> extraIncludeChildIds;
@Schema(description = "应当包含的子测试计划ID (用于程序内部筛选过滤)")
private List<String> includeItemTestPlanIds;
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";

View File

@ -84,4 +84,6 @@ public interface ExtTestPlanApiCaseMapper {
Integer countByPlanIds(@Param("planIds") List<String> planIds); Integer countByPlanIds(@Param("planIds") List<String> planIds);
List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds); List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId);
} }

View File

@ -910,6 +910,7 @@
<select id="selectLastExecResultByTestPlanIds" <select id="selectLastExecResultByTestPlanIds"
resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO"> resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
select resource.test_plan_id AS testPlanId, select resource.test_plan_id AS testPlanId,
test_plan.group_id AS testPlanGroupId,
CASE CASE
WHEN resource.last_exec_result is null WHEN resource.last_exec_result is null
THEN 'PENDING' THEN 'PENDING'
@ -921,6 +922,7 @@
END AS execResult END AS execResult
from test_plan_api_case resource from test_plan_api_case resource
INNER JOIN api_test_case apiCase ON resource.api_case_id = apiCase.id INNER JOIN api_test_case apiCase ON resource.api_case_id = apiCase.id
INNER JOIN test_plan ON test_plan.id = resource.test_plan_id
where resource.test_plan_id IN where resource.test_plan_id IN
<foreach collection="testPlanIds" item="testPlanId" separator="," open="(" close=")"> <foreach collection="testPlanIds" item="testPlanId" separator="," open="(" close=")">
#{testPlanId} #{testPlanId}
@ -947,4 +949,16 @@
</foreach> </foreach>
</where> </where>
</select> </select>
<select id="selectLastExecResultByProjectId"
resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
select resource.test_plan_id AS testPlanId,
resource.last_exec_result 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
INNER JOIN api_test_case ON resource.api_case_id = api_test_case.id
where test_plan.project_id = #{projectId}
AND api_test_case.deleted is false
AND test_plan.status != 'ARCHIVED'
</select>
</mapper> </mapper>

View File

@ -81,4 +81,6 @@ public interface ExtTestPlanApiScenarioMapper {
Integer countByPlanIds(@Param("planIds") List<String> planIds); Integer countByPlanIds(@Param("planIds") List<String> planIds);
List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds); List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId);
} }

View File

@ -680,6 +680,7 @@
<select id="selectLastExecResultByTestPlanIds" <select id="selectLastExecResultByTestPlanIds"
resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO"> resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
select resource.test_plan_id AS testPlanId, select resource.test_plan_id AS testPlanId,
test_plan.group_id AS testPlanGroupId,
CASE CASE
WHEN resource.last_exec_result is null WHEN resource.last_exec_result is null
THEN 'PENDING' THEN 'PENDING'
@ -690,6 +691,7 @@
ELSE resource.last_exec_result ELSE resource.last_exec_result
END AS execResult END AS execResult
from test_plan_api_scenario resource from test_plan_api_scenario resource
INNER JOIN test_plan ON test_plan.id = resource.test_plan_id
INNER JOIN api_scenario scenario ON resource.api_scenario_id = scenario.id INNER JOIN api_scenario scenario ON resource.api_scenario_id = scenario.id
where resource.test_plan_id IN where resource.test_plan_id IN
<foreach collection="testPlanIds" item="testPlanId" separator="," open="(" close=")"> <foreach collection="testPlanIds" item="testPlanId" separator="," open="(" close=")">
@ -697,4 +699,16 @@
</foreach> </foreach>
AND scenario.deleted IS FALSE AND scenario.deleted IS FALSE
</select> </select>
<select id="selectLastExecResultByProjectId"
resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
select resource.test_plan_id AS testPlanId,
resource.last_exec_result 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
INNER JOIN api_scenario ON resource.api_scenario_id = api_scenario.id
where test_plan.project_id = #{projectId}
AND api_scenario.deleted is false
AND test_plan.status != 'ARCHIVED'
</select>
</mapper> </mapper>

View File

@ -89,4 +89,6 @@ public interface ExtTestPlanFunctionalCaseMapper {
Collection<String> selectIdsByRootIds(@Param("rootIds") List<String> rootIds, @Param("testPlanId") String testPlanId); Collection<String> selectIdsByRootIds(@Param("rootIds") List<String> rootIds, @Param("testPlanId") String testPlanId);
List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds); List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId);
} }

View File

@ -807,6 +807,7 @@
<select id="selectLastExecResultByTestPlanIds" <select id="selectLastExecResultByTestPlanIds"
resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO"> resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
select resource.test_plan_id AS testPlanId, select resource.test_plan_id AS testPlanId,
test_plan.group_id AS testPlanGroupId,
CASE CASE
WHEN resource.last_exec_result is null WHEN resource.last_exec_result is null
THEN 'PENDING' THEN 'PENDING'
@ -817,6 +818,7 @@
ELSE resource.last_exec_result ELSE resource.last_exec_result
END AS execResult END AS execResult
FROM test_plan_functional_case resource FROM test_plan_functional_case resource
INNER JOIN test_plan ON test_plan.id = resource.test_plan_id
INNER JOIN functional_case funcCase ON resource.functional_case_id = funcCase.id INNER JOIN functional_case funcCase ON resource.functional_case_id = funcCase.id
WHERE resource.test_plan_id IN WHERE resource.test_plan_id IN
<foreach collection="testPlanIds" item="testPlanId" separator="," open="(" close=")"> <foreach collection="testPlanIds" item="testPlanId" separator="," open="(" close=")">
@ -824,5 +826,17 @@
</foreach> </foreach>
AND funcCase.deleted IS FALSE AND funcCase.deleted IS FALSE
</select> </select>
<select id="selectLastExecResultByProjectId"
resultType="io.metersphere.plan.dto.TestPlanResourceExecResultDTO">
select resource.test_plan_id AS testPlanId,
resource.last_exec_result 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
INNER JOIN functional_case ON resource.functional_case_id = functional_case.id
where test_plan.project_id = #{projectId}
AND functional_case.deleted is false
AND test_plan.status != 'ARCHIVED'
</select>
</mapper> </mapper>

View File

@ -1,6 +1,7 @@
package io.metersphere.plan.mapper; package io.metersphere.plan.mapper;
import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.domain.TestPlanConfig;
import io.metersphere.plan.dto.TestPlanAndGroupInfoDTO; import io.metersphere.plan.dto.TestPlanAndGroupInfoDTO;
import io.metersphere.plan.dto.TestPlanExecuteHisDTO; import io.metersphere.plan.dto.TestPlanExecuteHisDTO;
import io.metersphere.plan.dto.TestPlanGroupCountDTO; import io.metersphere.plan.dto.TestPlanGroupCountDTO;
@ -107,4 +108,8 @@ public interface ExtTestPlanMapper {
TestPlan getLatestPlan(@Param("projectId") String projectId); TestPlan getLatestPlan(@Param("projectId") String projectId);
List<TestPlanConfig> selectTestPlanConfigByTestPlanIds(@Param("testPlanIds") List<String> testPlanIds);
List<TestPlan> selectIdAndGroupIdByProjectId(String projectId);
} }

View File

@ -952,6 +952,20 @@
where type = 'TEST_PLAN' and status='NOT_ARCHIVED' and project_id = #{projectId} order by create_time desc limit 1; where type = 'TEST_PLAN' and status='NOT_ARCHIVED' and project_id = #{projectId} order by create_time desc limit 1;
</select> </select>
<select id="selectTestPlanConfigByTestPlanIds" resultType="io.metersphere.plan.domain.TestPlanConfig">
SELECT *
from test_plan_config test_plan_id
WHERE test_plan_id IN
<foreach collection="testPlanIds" item="testPlanId" open="(" separator="," close=")">
#{testPlanId}
</foreach>
</select>
<select id="selectIdAndGroupIdByProjectId" resultType="io.metersphere.plan.domain.TestPlan">
SELECT id, group_id, type
FROM test_plan
WHERE project_id = #{0}
AND status != 'ARCHIVED'
</select>
<sql id="queryMyFollowGroupByTableRequest"> <sql id="queryMyFollowGroupByTableRequest">
<include refid="baseConditionQuery"/> <include refid="baseConditionQuery"/>

View File

@ -151,6 +151,11 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
return extTestPlanApiCaseMapper.selectLastExecResultByTestPlanIds(testPlanIds); return extTestPlanApiCaseMapper.selectLastExecResultByTestPlanIds(testPlanIds);
} }
@Override
public List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId) {
return extTestPlanApiCaseMapper.selectLastExecResultByProjectId(projectId);
}
@Override @Override
public void deleteBatchByTestPlanId(List<String> testPlanIdList) { public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
TestPlanApiCaseExample example = new TestPlanApiCaseExample(); TestPlanApiCaseExample example = new TestPlanApiCaseExample();

View File

@ -139,6 +139,11 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
return extTestPlanApiScenarioMapper.selectLastExecResultByTestPlanIds(testPlanIds); return extTestPlanApiScenarioMapper.selectLastExecResultByTestPlanIds(testPlanIds);
} }
@Override
public List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId) {
return extTestPlanApiScenarioMapper.selectLastExecResultByProjectId(projectId);
}
@Override @Override
public void deleteBatchByTestPlanId(List<String> testPlanIdList) { public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();

View File

@ -4,12 +4,14 @@ 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.ResultStatus;
import io.metersphere.sdk.constants.TestPlanConstants; 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;
import io.metersphere.system.mapper.TestPlanModuleMapper; import io.metersphere.system.mapper.TestPlanModuleMapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; 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;
@ -76,13 +78,23 @@ public class TestPlanBaseUtilsService {
} }
public String calculateTestPlanStatus(List<String> resultList) { public String calculateTestPlanStatus(List<String> resultList) {
List<String> calculateList = resultList.stream().distinct().toList();
//目前只有三个状态如果同时包含多种状态(进行中/未开始进行中/已完成已完成/未开始进行中/未开始/已完成),根据算法可得测试计划都会是进行中 //目前只有三个状态如果同时包含多种状态(进行中/未开始进行中/已完成已完成/未开始进行中/未开始/已完成),根据算法可得测试计划都会是进行中
List<String> allStatus = new ArrayList<>();
resultList.stream().distinct().forEach(item -> {
if (StringUtils.equalsAnyIgnoreCase(item, ResultStatus.BLOCKED.name(), ResultStatus.FAKE_ERROR.name(), ResultStatus.ERROR.name(), ResultStatus.SUCCESS.name(), TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
allStatus.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED);
} else {
allStatus.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED);
}
});
List<String> calculateList = allStatus.stream().distinct().toList();
if (calculateList.size() == 1) { if (calculateList.size() == 1) {
if (calculateList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { if (calculateList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED; return TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED;
} else } else
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED; return TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED;
} else if (CollectionUtils.isEmpty(calculateList)) {
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED;
} else { } else {
return TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY; return TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY;
} }

View File

@ -68,6 +68,11 @@ public class TestPlanBugService extends TestPlanResourceService {
return List.of(); return List.of();
} }
@Override
public List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId) {
return List.of();
}
@Override @Override
public List<TestPlanResourceExecResultDTO> selectDistinctExecResultByTestPlanIds(List<String> testPlanIds) { public List<TestPlanResourceExecResultDTO> selectDistinctExecResultByTestPlanIds(List<String> testPlanIds) {
return List.of(); return List.of();

View File

@ -138,6 +138,11 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
return extTestPlanFunctionalCaseMapper.selectDistinctExecResult(projectId); return extTestPlanFunctionalCaseMapper.selectDistinctExecResult(projectId);
} }
@Override
public List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId) {
return extTestPlanFunctionalCaseMapper.selectLastExecResultByProjectId(projectId);
}
@Override @Override
public List<TestPlanResourceExecResultDTO> selectDistinctExecResultByTestPlanIds(List<String> testPlanIds) { public List<TestPlanResourceExecResultDTO> selectDistinctExecResultByTestPlanIds(List<String> testPlanIds) {
return extTestPlanFunctionalCaseMapper.selectDistinctExecResultByTestPlanIds(testPlanIds); return extTestPlanFunctionalCaseMapper.selectDistinctExecResultByTestPlanIds(testPlanIds);

View File

@ -4,8 +4,9 @@ import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; 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.TestPlanConfig;
import io.metersphere.plan.domain.TestPlanExample; import io.metersphere.plan.domain.TestPlanExample;
import io.metersphere.plan.dto.TestPlanGroupCountDTO; import io.metersphere.plan.dto.TestPlanCalculationDTO;
import io.metersphere.plan.dto.TestPlanResourceExecResultDTO; 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;
@ -14,12 +15,16 @@ import io.metersphere.plan.mapper.ExtTestPlanFunctionalCaseMapper;
import io.metersphere.plan.mapper.ExtTestPlanMapper; import io.metersphere.plan.mapper.ExtTestPlanMapper;
import io.metersphere.plan.mapper.ExtTestPlanModuleMapper; import io.metersphere.plan.mapper.ExtTestPlanModuleMapper;
import io.metersphere.plan.mapper.TestPlanMapper; import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.plan.utils.TestPlanUtils;
import io.metersphere.project.domain.Project; import io.metersphere.project.domain.Project;
import io.metersphere.project.dto.ModuleCountDTO; import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.ResultStatus;
import io.metersphere.sdk.constants.TestPlanConstants; import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.CalculateUtils;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.SubListUtils;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.utils.PageUtils; import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager; import io.metersphere.system.utils.Pager;
@ -81,7 +86,7 @@ public class TestPlanManagementService {
this.initDefaultFilter(request); this.initDefaultFilter(request);
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
MapUtils.isEmpty(request.getSort()) ? "t.pos desc, t.id desc" : request.getSortString("id", "t")); MapUtils.isEmpty(request.getSort()) ? "t.pos desc, t.id desc" : request.getSortString("id", "t"));
return PageUtils.setPageInfo(page, this.list(request)); return PageUtils.setPageInfo(page, this.list(request, request.getIncludeItemTestPlanIds()));
} }
public void filterTestPlanIdWithStatus(Map<String, List<String>> testPlanExecMap, List<String> completedTestPlanIds, List<String> preparedTestPlanIds, List<String> underwayTestPlanIds) { public void filterTestPlanIdWithStatus(Map<String, List<String>> testPlanExecMap, List<String> completedTestPlanIds, List<String> preparedTestPlanIds, List<String> underwayTestPlanIds) {
@ -131,61 +136,194 @@ public class TestPlanManagementService {
return returnIdList; return returnIdList;
} }
private List<String> selectTestPlanIdByProjectIdAndStatus(String projectId, @NotEmpty List<String> statusList) { /**
List<String> innerIdList = new ArrayList<>(); * 根据项目ID和状态查询包含的测试计划ID
Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class); *
// 将当前项目下未归档的测试计划结果查询出来进行下列符合条件的筛选 * @param projectId 项目ID
List<TestPlanResourceExecResultDTO> execResults = new ArrayList<>(); * @param dataType 页面视图 ( 全部查找符合条件的测试计划或测试子计划 计划查找符合条件的测试子计划 计划组查找符合条件的测试计划组
beansOfType.forEach((k, v) -> execResults.addAll(v.selectDistinctExecResultByProjectId(projectId))); * @param statusConditionList 状态列表
Map<String, Map<String, List<String>>> testPlanExecMap = testPlanBaseUtilsService.parseExecResult(execResults); * @return 测试计划ID列表
Map<String, Long> groupCountMap = extTestPlanMapper.countByGroupPlan(projectId) */
.stream().collect(Collectors.toMap(TestPlanGroupCountDTO::getGroupId, TestPlanGroupCountDTO::getCount)); public TestPlanCalculationDTO selectTestPlanIdByProjectIdUnionConditions(String projectId, String dataType, List<String> statusConditionList, List<String> passedConditionList) {
if (CollectionUtils.isEmpty(statusConditionList) && CollectionUtils.isEmpty(passedConditionList)) {
List<String> completedTestPlanIds = new ArrayList<>(); return new TestPlanCalculationDTO();
List<String> preparedTestPlanIds = new ArrayList<>(); }
List<String> underwayTestPlanIds = new ArrayList<>(); boolean selectPassed = CollectionUtils.isNotEmpty(passedConditionList) && CollectionUtils.size(passedConditionList) == 1;
testPlanExecMap.forEach((groupId, planMap) -> { List<TestPlan> testPlanList = extTestPlanMapper.selectIdAndGroupIdByProjectId(projectId);
if (StringUtils.equalsIgnoreCase(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) { Map<String, List<String>> testPlanGroupIdMap = new HashMap<>();
this.filterTestPlanIdWithStatus(planMap, completedTestPlanIds, preparedTestPlanIds, underwayTestPlanIds); List<String> noGroupPlanIdList = new ArrayList<>();
} else { Map<String, List<String>> noGroupPlanIdMap = new HashMap<>();
long itemPlanCount = groupCountMap.getOrDefault(groupId, 0L); if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN)) {
List<String> itemStatusList = new ArrayList<>(); //只查游离态的测试计划
if (itemPlanCount > planMap.size()) { for (TestPlan item : testPlanList) {
// 存在未执行或者没有用例的测试计划 此时这种测试计划的状态为未开始 if (StringUtils.equalsIgnoreCase(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) && StringUtils.equals(item.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
itemStatusList.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); noGroupPlanIdList.add(item.getId());
}
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);
} }
} }
} else if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
//不查游离态的测试计划
testPlanList = testPlanList.stream().filter(item ->
StringUtils.equalsIgnoreCase(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP) || !StringUtils.equals(item.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)
).toList();
testPlanGroupIdMap = TestPlanUtils.parseGroupIdMap(testPlanList);
} else {
// 全部查询
testPlanGroupIdMap = TestPlanUtils.parseGroupIdMap(testPlanList);
noGroupPlanIdList = testPlanGroupIdMap.get(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
testPlanGroupIdMap.remove(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
}
noGroupPlanIdMap.put(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID, noGroupPlanIdList);
testPlanList = null;
Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class);
TestPlanCalculationDTO calculationDTO = this.calculationTestPlanByConditions(noGroupPlanIdMap, beansOfType, selectPassed, dataType);
SubListUtils.dealForSubMap(testPlanGroupIdMap, 50, groupIdMap -> {
TestPlanCalculationDTO dto = this.calculationTestPlanByConditions(groupIdMap, beansOfType, selectPassed, dataType);
calculationDTO.merge(dto);
}); });
testPlanExecMap = null; calculationDTO.setStatusConditionList(statusConditionList);
if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { calculationDTO.setPassedConditionList(passedConditionList);
// 已完成
innerIdList.addAll(completedTestPlanIds); return calculationDTO;
}
private TestPlanCalculationDTO calculationTestPlanByConditions(Map<String, List<String>> groupIdMap, Map<String, TestPlanResourceService> beansOfType, boolean selectPassed, String dataType) {
TestPlanCalculationDTO returnDTO = new TestPlanCalculationDTO();
List<String> selectTestPlanIds = new ArrayList<>();
groupIdMap.forEach((k, v) -> selectTestPlanIds.addAll(v));
if (CollectionUtils.isEmpty(selectTestPlanIds)) {
return returnDTO;
}
// 将当前项目下未归档的测试计划结果查询出来进行下列符合条件的筛选
List<TestPlanResourceExecResultDTO> execResults = new ArrayList<>();
Map<String, Map<String, List<String>>> testPlanExecMap = null;
if (selectPassed) {
beansOfType.forEach((k, v) -> execResults.addAll(v.selectLastExecResultByTestPlanIds(selectTestPlanIds)));
testPlanExecMap = testPlanBaseUtilsService.parseExecResult(execResults);
Map<String, TestPlanConfig> testPlanConfigMap = extTestPlanMapper.selectTestPlanConfigByTestPlanIds(selectTestPlanIds)
.stream().collect(Collectors.toMap(TestPlanConfig::getTestPlanId, item -> item));
for (Map.Entry<String, List<String>> entry : groupIdMap.entrySet()) {
String groupId = entry.getKey();
List<String> testPlanIdList = entry.getValue();
Map<String, List<String>> testPlanExecResult = testPlanExecMap.containsKey(groupId) ? testPlanExecMap.get(groupId) : new HashMap<>();
boolean isRootTestPlan = StringUtils.equalsIgnoreCase(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
boolean groupHasUnPassItem = false;
for (String testPlanId : testPlanIdList) {
TestPlanConfig config = testPlanConfigMap.get(testPlanId);
double passThreshold = (config == null || config.getPassThreshold() == null) ? 100 : config.getPassThreshold();
List<String> executeResultList = testPlanExecResult.containsKey(testPlanId) ? testPlanExecResult.get(testPlanId) : new ArrayList<>();
double executeRage = CalculateUtils.percentage(
executeResultList.stream().filter(result -> StringUtils.equalsIgnoreCase(result, ResultStatus.SUCCESS.name())).toList().size(),
executeResultList.size());
if (executeRage < passThreshold) {
groupHasUnPassItem = true;
}
if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && isRootTestPlan) {
if (executeRage >= passThreshold) {
returnDTO.addPassedTestPlanId(testPlanId);
} else {
returnDTO.addNotPassedTestPlanId(testPlanId);
}
} else if (StringUtils.equalsAnyIgnoreCase(dataType, "ALL")) {
if (executeRage >= passThreshold) {
if (isRootTestPlan) {
returnDTO.addPassedTestPlanId(testPlanId);
} else {
returnDTO.addPassedTestPlanId(groupId);
returnDTO.addPassedItemTestPlanId(testPlanId);
}
} else {
if (isRootTestPlan) {
returnDTO.addNotPassedTestPlanId(testPlanId);
} else {
returnDTO.addNotPassedTestPlanId(groupId);
returnDTO.addNotPassedItemTestPlanId(testPlanId);
}
}
}
}
if (!StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !isRootTestPlan) {
if (groupHasUnPassItem || CollectionUtils.isEmpty(testPlanIdList)) {
returnDTO.addNotPassedTestPlanId(groupId);
} else {
returnDTO.addPassedTestPlanId(groupId);
}
}
}
} else {
beansOfType.forEach((k, v) -> execResults.addAll(v.selectDistinctExecResultByTestPlanIds(selectTestPlanIds)));
testPlanExecMap = testPlanBaseUtilsService.parseExecResult(execResults);
} }
if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { for (Map.Entry<String, List<String>> entry : groupIdMap.entrySet()) {
// 进行中 String groupId = entry.getKey();
innerIdList.addAll(underwayTestPlanIds); List<String> testPlanIdList = entry.getValue();
Map<String, List<String>> testPlanExecResult = testPlanExecMap.containsKey(groupId) ? testPlanExecMap.get(groupId) : new HashMap<>();
boolean isRootTestPlan = StringUtils.equalsIgnoreCase(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
List<String> testPlanStatus = new ArrayList<>();
for (String testPlanId : testPlanIdList) {
List<String> executeResultList = testPlanExecResult.containsKey(testPlanId) ? testPlanExecResult.get(testPlanId) : new ArrayList<>();
String result = testPlanBaseUtilsService.calculateTestPlanStatus(executeResultList);
testPlanStatus.add(result);
if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && isRootTestPlan) {
if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
returnDTO.addCompletedTestPlanId(testPlanId);
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
returnDTO.addUnderwayTestPlanId(testPlanId);
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
returnDTO.addPreparedTestPlanId(testPlanId);
}
} else if (StringUtils.equalsAnyIgnoreCase(dataType, "ALL")) {
if (isRootTestPlan) {
if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
returnDTO.addCompletedTestPlanId(testPlanId);
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
returnDTO.addUnderwayTestPlanId(testPlanId);
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
returnDTO.addPreparedTestPlanId(testPlanId);
}
} else {
if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
returnDTO.addCompletedTestPlanId(groupId);
returnDTO.addCompletedItemTestPlanId(testPlanId);
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
returnDTO.addUnderwayTestPlanId(groupId);
returnDTO.addUnderwayItemTestPlanId(testPlanId);
} else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
returnDTO.addPreparedTestPlanId(groupId);
returnDTO.addPreparedItemTestPlanId(testPlanId);
}
}
}
}
if (!StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !isRootTestPlan) {
String groupStatus = testPlanBaseUtilsService.calculateStatusByChildren(testPlanStatus);
if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) {
returnDTO.addCompletedTestPlanId(groupId);
} else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) {
returnDTO.addUnderwayTestPlanId(groupId);
} else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) {
returnDTO.addPreparedTestPlanId(groupId);
}
}
} }
if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { return returnDTO;
// 未开始 有一些测试计划/计划组没有用例 / 测试计划 在上面的计算中无法过滤所以用排除法机型处理
List<String> withoutList = new ArrayList<>();
withoutList.addAll(completedTestPlanIds);
withoutList.addAll(underwayTestPlanIds);
innerIdList.addAll(extTestPlanMapper.selectIdByProjectIdAndWithoutList(projectId, withoutList));
}
return innerIdList;
} }
@Autowired @Autowired
@ -202,13 +340,23 @@ public class TestPlanManagementService {
item.setValue(defaultStatusList); item.setValue(defaultStatusList);
//目前未归档的测试计划只有3中类型所以这里判断如果是3个的话等于直接查询未归档 //目前未归档的测试计划只有3中类型所以这里判断如果是3个的话等于直接查询未归档
if (statusList.size() < 3) { if (statusList.size() < 3) {
request.setCombineInnerIds(this.selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), statusList)); TestPlanCalculationDTO calculationDTO = this.selectTestPlanIdByProjectIdUnionConditions(request.getProjectId(), request.getType(), statusList, null);
request.setCombineInnerIds(calculationDTO.getConditionInnerId());
request.setIncludeItemTestPlanIds(calculationDTO.getConditionItemPlanId());
request.setCombineOperator(item.getOperator()); request.setCombineOperator(item.getOperator());
if (CollectionUtils.isEmpty(request.getCombineInnerIds())) {
// 如果查询条件内未查出包含ID意味着查不出任何一条数据
request.setCombineInnerIds(Collections.singletonList("COMBINE_SEARCH_NONE"));
}
} }
} }
}); });
}); });
if (!StringUtils.equalsIgnoreCase(request.getViewId(), TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) { if (!StringUtils.equalsIgnoreCase(request.getViewId(), TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) {
List<String> statusSelectParam = null;
List<String> passedSelectParam = null;
if (request.getFilter() == null || !request.getFilter().containsKey("status")) { if (request.getFilter() == null || !request.getFilter().containsKey("status")) {
if (request.getFilter() == null) { if (request.getFilter() == null) {
request.setFilter(new HashMap<>() {{ request.setFilter(new HashMap<>() {{
@ -218,13 +366,31 @@ public class TestPlanManagementService {
request.getFilter().put("status", defaultStatusList); request.getFilter().put("status", defaultStatusList);
} }
} else if (!request.getFilter().get("status").contains(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) { } else if (!request.getFilter().get("status").contains(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) {
List<String> statusList = request.getFilter().get("status"); statusSelectParam = request.getFilter().get("status");
request.getFilter().put("status", defaultStatusList); request.getFilter().put("status", defaultStatusList);
//目前未归档的测试计划只有3中类型所以这里判断如果是3个的话等于直接查询未归档 }
if (statusList.size() < 3) {
request.setInnerIds(this.selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), statusList)); if (request.getFilter() != null && request.getFilter().containsKey("passed")) {
passedSelectParam = request.getFilter().get("passed");
}
boolean selectArchived = CollectionUtils.isNotEmpty(statusSelectParam) && statusSelectParam.contains(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
boolean selectStatus = !selectArchived && CollectionUtils.isNotEmpty(statusSelectParam) && CollectionUtils.size(statusSelectParam) < 3;
boolean selectPassed = CollectionUtils.isNotEmpty(passedSelectParam) && CollectionUtils.size(passedSelectParam) == 1;
if (selectStatus || selectPassed) {
TestPlanCalculationDTO calculationDTO = this.selectTestPlanIdByProjectIdUnionConditions(request.getProjectId(), request.getType(),
selectStatus ? statusSelectParam : null,
selectPassed ? passedSelectParam : null);
request.setInnerIds(calculationDTO.getConditionInnerId());
request.setIncludeItemTestPlanIds(calculationDTO.getConditionItemPlanId());
if (CollectionUtils.isEmpty(request.getInnerIds()) && !selectArchived) {
// 如果查询条件内未查出包含ID意味着查不出任何一条数据
request.setCombineInnerIds(Collections.singletonList("FILTER_SEARCH_NONE"));
} }
} }
} }
if (StringUtils.isNotBlank(request.getKeyword())) { if (StringUtils.isNotBlank(request.getKeyword())) {
@ -236,14 +402,15 @@ public class TestPlanManagementService {
} }
} }
public List<TestPlanResponse> list(TestPlanTableRequest request) { public List<TestPlanResponse> list(TestPlanTableRequest request, List<String> includeChildTestPlanId) {
List<TestPlanResponse> testPlanResponses = new ArrayList<>(); List<TestPlanResponse> testPlanResponses = new ArrayList<>();
if (StringUtils.equalsIgnoreCase(request.getViewId(), "my_follow")) { if (StringUtils.equalsIgnoreCase(request.getViewId(), "my_follow")) {
testPlanResponses = extTestPlanMapper.selectMyFollowByConditions(request); testPlanResponses = extTestPlanMapper.selectMyFollowByConditions(request);
} else { } else {
testPlanResponses = extTestPlanMapper.selectByConditions(request); testPlanResponses = extTestPlanMapper.selectByConditions(request);
} }
handChildren(testPlanResponses, request.getProjectId());
handChildren(testPlanResponses, includeChildTestPlanId);
return testPlanResponses; return testPlanResponses;
} }
@ -257,7 +424,7 @@ public class TestPlanManagementService {
/** /**
* 计划组子节点 * 计划组子节点
*/ */
private void handChildren(List<TestPlanResponse> testPlanResponses, String projectId) { private void handChildren(List<TestPlanResponse> testPlanResponses, List<String> includeItemTestPlanId) {
List<String> groupIds = testPlanResponses.stream().filter(item -> StringUtils.equals(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)).map(TestPlanResponse::getId).toList(); List<String> groupIds = testPlanResponses.stream().filter(item -> StringUtils.equals(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)).map(TestPlanResponse::getId).toList();
if (CollectionUtils.isNotEmpty(groupIds)) { if (CollectionUtils.isNotEmpty(groupIds)) {
List<TestPlanResponse> childrenList = extTestPlanMapper.selectByGroupIds(groupIds); List<TestPlanResponse> childrenList = extTestPlanMapper.selectByGroupIds(groupIds);
@ -266,6 +433,9 @@ public class TestPlanManagementService {
if (collect.containsKey(item.getId())) { if (collect.containsKey(item.getId())) {
//存在子节点 //存在子节点
List<TestPlanResponse> list = collect.get(item.getId()); List<TestPlanResponse> list = collect.get(item.getId());
if (CollectionUtils.isNotEmpty(includeItemTestPlanId)) {
list = list.stream().filter(child -> includeItemTestPlanId.contains(child.getId())).toList();
}
item.setChildren(list); item.setChildren(list);
item.setChildrenCount(list.size()); item.setChildrenCount(list.size());
} }
@ -328,8 +498,13 @@ public class TestPlanManagementService {
List<String> doneIds = new ArrayList<>(); List<String> doneIds = new ArrayList<>();
List<String> extraChildIds = new ArrayList<>(); List<String> extraChildIds = new ArrayList<>();
// 筛选出已完成/进行中的计划或计划组 // 筛选出已完成/进行中的计划或计划组
List<String> completePlanOrGroupIds = selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), List.of(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)); List<String> statusList = new ArrayList<>();
List<String> underwayPlanOrGroupIds = selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), List.of(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)); statusList.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED);
statusList.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY);
TestPlanCalculationDTO calculationDTO = this.selectTestPlanIdByProjectIdUnionConditions(request.getProjectId(), "ALL", statusList, null);
List<String> completePlanOrGroupIds = calculationDTO.getCompletedTestPlanIds();
List<String> underwayPlanOrGroupIds = calculationDTO.getUnderwayTestPlanIds();
if (CollectionUtils.isNotEmpty(completePlanOrGroupIds) || CollectionUtils.isNotEmpty(underwayPlanOrGroupIds)) { if (CollectionUtils.isNotEmpty(completePlanOrGroupIds) || CollectionUtils.isNotEmpty(underwayPlanOrGroupIds)) {
TestPlanExample example = new TestPlanExample(); TestPlanExample example = new TestPlanExample();
example.createCriteria().andIdIn(ListUtils.union(completePlanOrGroupIds, underwayPlanOrGroupIds)); example.createCriteria().andIdIn(ListUtils.union(completePlanOrGroupIds, underwayPlanOrGroupIds));

View File

@ -109,6 +109,8 @@ public abstract class TestPlanResourceService extends TestPlanSortService {
public abstract List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(List<String> testPlanIds); public abstract List<TestPlanResourceExecResultDTO> selectLastExecResultByTestPlanIds(List<String> testPlanIds);
public abstract List<TestPlanResourceExecResultDTO> selectLastExecResultByProjectId(String projectId);
/** /**
* 关联用例 * 关联用例
* *

View File

@ -1058,7 +1058,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
returnDTO.unSuccessAutoIncrement(isArchived); returnDTO.unSuccessAutoIncrement(isArchived);
} }
} else { } else {
if (passphrase > executeRage) { if (passphrase >= executeRage) {
if (calculateList.contains(ExecStatus.PENDING.name())) { if (calculateList.contains(ExecStatus.PENDING.name())) {
// 通过却未完成 // 通过却未完成
returnDTO.passAndNotFinishedAutoIncrement(isArchived); returnDTO.passAndNotFinishedAutoIncrement(isArchived);

View File

@ -0,0 +1,30 @@
package io.metersphere.plan.utils;
import io.metersphere.plan.domain.TestPlan;
import io.metersphere.sdk.constants.TestPlanConstants;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestPlanUtils {
public static Map<String, List<String>> parseGroupIdMap(List<TestPlan> testPlanList) {
Map<String, List<String>> testPlanGroupIdMap = new HashMap<>();
for (TestPlan testPlan : testPlanList) {
if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP) && !testPlanGroupIdMap.containsKey(testPlan.getId())) {
testPlanGroupIdMap.put(testPlan.getId(), new ArrayList<>());
} else {
if (testPlanGroupIdMap.containsKey(testPlan.getGroupId())) {
testPlanGroupIdMap.get(testPlan.getGroupId()).add(testPlan.getId());
} else {
testPlanGroupIdMap.put(testPlan.getGroupId(), new ArrayList<>() {{
this.add(testPlan.getId());
}});
}
}
}
return testPlanGroupIdMap;
}
}

View File

@ -82,7 +82,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc @AutoConfigureMockMvc
public class TestPlanTests extends BaseTest { public class TestPlanControllerTests extends BaseTest {
private static Project project; private static Project project;
private static List<BaseTreeNode> preliminaryTreeNodes = new ArrayList<>(); private static List<BaseTreeNode> preliminaryTreeNodes = new ArrayList<>();
@ -145,8 +145,6 @@ public class TestPlanTests extends BaseTest {
//普通测试计划 //普通测试计划
private static TestPlan simpleTestPlan; private static TestPlan simpleTestPlan;
//允许重复添加用例的测试计划
private static TestPlan repeatCaseTestPlan;
private static final String[] PROJECT_MODULE = new String[]{"workstation", "testPlan", "bugManagement", "caseManagement", "apiTest", "uiTest", "loadTest"}; private static final String[] PROJECT_MODULE = new String[]{"workstation", "testPlan", "bugManagement", "caseManagement", "apiTest", "uiTest", "loadTest"};
@Resource @Resource
@ -156,7 +154,7 @@ public class TestPlanTests extends BaseTest {
@Resource @Resource
private FunctionalCaseMapper functionalCaseMapper; private FunctionalCaseMapper functionalCaseMapper;
private static List<String> functionalCaseId = new ArrayList<>(); private static final List<String> functionalCaseId = new ArrayList<>();
@BeforeEach @BeforeEach
public void initTestData() { public void initTestData() {
@ -184,12 +182,6 @@ public class TestPlanTests extends BaseTest {
} }
} }
private static long a1NodeCount = 0;
private static long a2NodeCount = 0;
private static long a3NodeCount = 0;
private static long a1a1NodeCount = 0;
private static long a1b1NodeCount = 0;
@Test @Test
@Order(1) @Order(1)
public void emptyDataTest() throws Exception { public void emptyDataTest() throws Exception {
@ -567,25 +559,20 @@ public class TestPlanTests extends BaseTest {
if (i == 7 || i == 15 || i == 35 || i == 45 || i == 46) { 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++;
} else if (i < 100) { } else if (i < 100) {
moduleId = a2Node.getId(); moduleId = a2Node.getId();
request.setPlannedStartTime(System.currentTimeMillis()); request.setPlannedStartTime(System.currentTimeMillis());
request.setPlannedEndTime(System.currentTimeMillis() + 20000); request.setPlannedEndTime(System.currentTimeMillis() + 20000);
a2NodeCount++;
} else if (i < 150) { } else if (i < 150) {
moduleId = a3Node.getId(); moduleId = a3Node.getId();
request.setRepeatCase(true); request.setRepeatCase(true);
request.setAutomaticStatusUpdate(true); request.setAutomaticStatusUpdate(true);
a3NodeCount++;
} else if (i < 200) { } else if (i < 200) {
moduleId = a1a1Node.getId(); moduleId = a1a1Node.getId();
request.setPassThreshold((double) i / 3); request.setPassThreshold((double) i / 3);
request.setDescription("test plan desc " + i); request.setDescription("test plan desc " + i);
a1a1NodeCount++;
} else { } else {
moduleId = a1b1Node.getId(); moduleId = a1b1Node.getId();
a1b1NodeCount++;
} }
//添加测试计划 //添加测试计划
@ -666,7 +653,7 @@ public class TestPlanTests extends BaseTest {
*/ */
testPlanTestService.checkTestPlanByAddTest(); testPlanTestService.checkTestPlanByAddTest();
simpleTestPlan = testPlanTestService.selectTestPlanByName("testPlan_13"); simpleTestPlan = testPlanTestService.selectTestPlanByName("testPlan_13");
repeatCaseTestPlan = testPlanTestService.selectTestPlanByName("testPlan_123"); // repeatCaseTestPlan = testPlanTestService.selectTestPlanByName("testPlan_123");
//在groupTestPlanId7groupTestPlanId15下面各创建20条数据并且校验第21条不能创建成功 //在groupTestPlanId7groupTestPlanId15下面各创建20条数据并且校验第21条不能创建成功
for (int i = 0; i < 21; i++) { for (int i = 0; i < 21; i++) {
@ -886,6 +873,7 @@ public class TestPlanTests extends BaseTest {
Assertions.assertTrue(tableList.get(1).getId().equals(posRequest.getMoveId())); Assertions.assertTrue(tableList.get(1).getId().equals(posRequest.getMoveId()));
Assertions.assertTrue(tableList.get(2).getId().equals(posRequest.getTargetId())); Assertions.assertTrue(tableList.get(2).getId().equals(posRequest.getTargetId()));
} }
protected void checkTestPlanSortInGroup(String groupId) throws Exception { protected void checkTestPlanSortInGroup(String groupId) throws Exception {
/* /*
排序校验用例设计 排序校验用例设计
@ -1111,94 +1099,299 @@ public class TestPlanTests extends BaseTest {
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 已完成的测试计划 6
进行中的 16 已完成的测试计划组 46
已归档的 35 进行中的测试计划 16
没有测试子计划的组 45
已归档的1个 35
*/ */
//进行状态筛选 -- 未开始 int finishedPlan = 1;
statusRequest.setFilter(new HashMap<>() {{ int finishedGroup = 1;
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)); int underwayPlan = 1;
}}); int noPlanGroup = 1;
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( int archivedPlan = 1;
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(), int testPlanCount = 994;
dataRequest.getPageSize(), int testPlanGroupCount = 5;
999 - 1 - 1 - 2);
//进行状态筛选 -- 已完成 // 测试通过
statusRequest.setFilter(new HashMap<>() {{ {
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)); statusRequest.setType("ALL");
}}); statusRequest.setFilter(new HashMap<>() {{
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( this.put("passed", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED));
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(
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), dataRequest.getCurrent(),
dataRequest.getCurrent(), dataRequest.getPageSize(),
dataRequest.getPageSize(), finishedPlan + finishedGroup);
999 - 1 - 1); statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
//进行状态筛选 -- 已完成和进行中 testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
statusRequest.setFilter(new HashMap<>() {{ URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
this.put("status", new ArrayList<String>() {{ dataRequest.getCurrent(),
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); dataRequest.getPageSize(),
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); finishedPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
finishedGroup);
}
//测试不通过
{
statusRequest.setType("ALL");
statusRequest.setFilter(new HashMap<>() {{
this.put("passed", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_NOT_PASSED));
}}); }});
}}); testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
testPlanCount + testPlanGroupCount - archivedPlan - finishedPlan - finishedGroup);
statusRequest.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(),
testPlanCount - finishedPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
testPlanGroupCount - archivedPlan - finishedGroup);
}
//进行状态筛选 -- 空状态
statusRequest.setType("ALL");
statusRequest.setFilter(null);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(), dataRequest.getCurrent(),
dataRequest.getPageSize(), dataRequest.getPageSize(),
3); testPlanCount + testPlanGroupCount - archivedPlan);
//进行状态筛选 -- 进行中和未开始
statusRequest.setFilter(new HashMap<>() {{
this.put("status", new ArrayList<String>() {{ //进行状态筛选 -- 未开始 并且检查不同的tab页
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); {
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); statusRequest.setType("ALL");
statusRequest.setFilter(new HashMap<>() {{
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED));
}}); }});
}}); testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), dataRequest.getCurrent(),
dataRequest.getCurrent(), dataRequest.getPageSize(),
dataRequest.getPageSize(), testPlanCount + testPlanGroupCount - archivedPlan - underwayPlan - finishedPlan - finishedGroup);
999 - 1 - 2); statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
//进行状态筛选 -- 已完成未开始进行中 testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
statusRequest.setFilter(new HashMap<>() {{ URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
this.put("status", new ArrayList<String>() {{ dataRequest.getCurrent(),
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); dataRequest.getPageSize(),
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); testPlanCount - underwayPlan - finishedPlan);
this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
testPlanGroupCount - archivedPlan - finishedGroup);
}
{
//进行状态筛选 -- 已完成
statusRequest.setType("ALL");
statusRequest.setFilter(new HashMap<>() {{
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED));
}}); }});
}}); testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), dataRequest.getCurrent(),
dataRequest.getCurrent(), dataRequest.getPageSize(),
dataRequest.getPageSize(), finishedPlan + finishedGroup);
999 - 1);
statusRequest.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(),
finishedPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
finishedGroup);
}
{
//进行状态筛选 -- 进行中
statusRequest.setType("ALL");
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(),
underwayPlan);
statusRequest.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(),
underwayPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
0);
}
{
//进行状态筛选 已完成和未开始
statusRequest.setType("ALL");
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(),
testPlanCount + testPlanGroupCount - archivedPlan - underwayPlan);
statusRequest.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(),
testPlanCount - underwayPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
testPlanGroupCount - archivedPlan);
//配合状态进行筛选
statusRequest.setType("ALL");
statusRequest.setFilter(new HashMap<>() {{
this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED));
this.put("passed", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED));
}});
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
finishedPlan + finishedGroup);
statusRequest.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(),
finishedPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
finishedGroup);
}
{
//进行状态筛选 -- 已完成和进行中
statusRequest.setType("ALL");
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(),
finishedPlan + finishedGroup + underwayPlan);
statusRequest.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(),
finishedPlan + underwayPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
finishedGroup);
}
{
//进行状态筛选 -- 进行中和未开始
statusRequest.setType("ALL");
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(),
testPlanCount + testPlanGroupCount - archivedPlan - finishedPlan - finishedGroup);
statusRequest.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(),
testPlanCount - finishedPlan);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
testPlanGroupCount - archivedPlan - finishedGroup);
}
{
//进行状态筛选 -- 已完成未开始进行中
statusRequest.setType("ALL");
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(),
testPlanGroupCount + testPlanCount - archivedPlan);
statusRequest.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(),
testPlanCount);
statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn(
URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8),
dataRequest.getCurrent(),
dataRequest.getPageSize(),
testPlanGroupCount - archivedPlan);
}
statusRequest.setType("ALL");
BaseTreeNode a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1"); BaseTreeNode a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1");
BaseTreeNode a2Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a2"); BaseTreeNode a2Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a2");
@ -1438,11 +1631,9 @@ public class TestPlanTests extends BaseTest {
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_91").getId()); updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_91").getId());
updateRequest.setGroupId(groupTestPlanId45); updateRequest.setGroupId(groupTestPlanId45);
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest); this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
a2NodeCount--;
updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_92").getId()); updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_92").getId());
updateRequest.setGroupId(groupTestPlanId45); updateRequest.setGroupId(groupTestPlanId45);
this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest); this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest);
a2NodeCount--;
TestPlan updatePlan = new TestPlan(); TestPlan updatePlan = new TestPlan();
updatePlan.setId(groupTestPlanId7); updatePlan.setId(groupTestPlanId7);
@ -2238,29 +2429,29 @@ public class TestPlanTests extends BaseTest {
} }
private void checkModuleCount(Map<String, Object> moduleCountMap, long a1NodeCount, long a2NodeCount, long a3NodeCount, long a1a1NodeCount, long a1b1NodeCount) throws Exception { // private void checkModuleCount(Map<String, Object> moduleCountMap, long a1NodeCount, long a2NodeCount, long a3NodeCount, long a1a1NodeCount, long a1b1NodeCount) throws Exception {
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");
BaseTreeNode a1a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-a1"); // BaseTreeNode a1a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-a1");
BaseTreeNode a1b1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-b1"); // BaseTreeNode a1b1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-b1");
assert a1Node != null & a2Node != null & a3Node != null & a1a1Node != null & a1b1Node != null; // assert a1Node != null & a2Node != null & a3Node != null & a1a1Node != null & a1b1Node != null;
//检查每个节点下的数据是否匹配的上父节点的统计会一并添加上子节点的数据 // //检查每个节点下的数据是否匹配的上父节点的统计会一并添加上子节点的数据
moduleCountMap.forEach((k, v) -> { // moduleCountMap.forEach((k, v) -> {
long value = Long.parseLong(String.valueOf(v)); // long value = Long.parseLong(String.valueOf(v));
if (StringUtils.equals(k, a1Node.getId())) { // if (StringUtils.equals(k, a1Node.getId())) {
Assertions.assertEquals(value, a1NodeCount + a1a1NodeCount + a1b1NodeCount); // Assertions.assertEquals(value, a1NodeCount + a1a1NodeCount + a1b1NodeCount);
} else if (StringUtils.equals(k, a2Node.getId())) { // } else if (StringUtils.equals(k, a2Node.getId())) {
Assertions.assertEquals(value, a2NodeCount); // Assertions.assertEquals(value, a2NodeCount);
} else if (StringUtils.equals(k, a3Node.getId())) { // } else if (StringUtils.equals(k, a3Node.getId())) {
Assertions.assertEquals(value, a3NodeCount); // Assertions.assertEquals(value, a3NodeCount);
} else if (StringUtils.equals(k, a1a1Node.getId())) { // } else if (StringUtils.equals(k, a1a1Node.getId())) {
Assertions.assertEquals(value, a1a1NodeCount); // Assertions.assertEquals(value, a1a1NodeCount);
} else if (StringUtils.equals(k, a1b1Node.getId())) { // } else if (StringUtils.equals(k, a1b1Node.getId())) {
Assertions.assertEquals(value, a1b1NodeCount); // Assertions.assertEquals(value, a1b1NodeCount);
} // }
}); // });
} // }
@Resource @Resource
private TestPlanService testPlanService; private TestPlanService testPlanService;
@ -2541,9 +2732,12 @@ public class TestPlanTests extends BaseTest {
testPlanService.deletePlanCollectionResource(List.of("init_collection-delete-1", "init_collection-delete-2", "init_collection-delete-3")); testPlanService.deletePlanCollectionResource(List.of("init_collection-delete-1", "init_collection-delete-2", "init_collection-delete-3"));
} }
/**
* 方法层面的测试
*/
@Test @Test
@Order(310) @Order(310)
void testStatusSelectMethod() { void testForFunctions() {
//initSQL中功能用例idoasis_fc_1 的数据关联到了测试计划 //initSQL中功能用例idoasis_fc_1 的数据关联到了测试计划
List<String> testPlanStatusList = new ArrayList<>(); List<String> testPlanStatusList = new ArrayList<>();
testPlanStatusList.add(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED); testPlanStatusList.add(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
@ -2595,6 +2789,8 @@ public class TestPlanTests extends BaseTest {
Assertions.assertEquals(1, underwayTestPlanIds.size()); Assertions.assertEquals(1, underwayTestPlanIds.size());
Assertions.assertEquals("test3", underwayTestPlanIds.getFirst()); Assertions.assertEquals("test3", underwayTestPlanIds.getFirst());
testPlanManagementService.selectTestPlanIdByProjectIdUnionConditions(null, null, null, null);
} }
} }