refactor(测试计划): 优化计划列表统计

This commit is contained in:
song-cc-rock 2024-06-07 17:57:14 +08:00 committed by Craftsman
parent b29118595d
commit bad708148a
9 changed files with 135 additions and 76 deletions

View File

@ -77,28 +77,6 @@ CREATE INDEX idx_pos ON test_plan_api_scenario(pos);
ALTER TABLE test_plan_functional_case ADD COLUMN test_plan_collection_id VARCHAR(50) NOT NULL DEFAULT 'NONE' COMMENT '测试计划集id';
CREATE INDEX idx_test_plan_collection_id ON test_plan_functional_case(test_plan_collection_id);
-- 修改测试规划配置表
ALTER TABLE test_plan_allocation DROP `run_mode_config`;
ALTER TABLE test_plan_allocation ADD `test_resource_pool_id` VARCHAR(50) NOT NULL COMMENT '资源池ID';
ALTER TABLE test_plan_allocation ADD `retry_on_fail` BIT NOT NULL DEFAULT 0 COMMENT '是否失败重试' ;
ALTER TABLE test_plan_allocation ADD `retry_type` VARCHAR(50) NOT NULL COMMENT '失败重试类型(步骤/场景)' ;
ALTER TABLE test_plan_allocation ADD `retry_times` INT NOT NULL DEFAULT 1 COMMENT '失败重试次数' ;
ALTER TABLE test_plan_allocation ADD `retry_interval` INT NOT NULL DEFAULT 1000 COMMENT '失败重试间隔(单位: ms)' ;
ALTER TABLE test_plan_allocation ADD `stop_on_fail` BIT NOT NULL DEFAULT 0 COMMENT '是否失败停止' ;
CREATE INDEX idx_resource_pool_id ON test_plan_allocation(test_resource_pool_id);
-- 测试规划集类型
CREATE TABLE IF NOT EXISTS test_plan_allocation_type(
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
`test_plan_id` VARCHAR(50) NOT NULL COMMENT '测试计划ID' ,
`name` VARCHAR(255) NOT NULL COMMENT '测试集类型名称' ,
`type` VARCHAR(50) NOT NULL COMMENT '测试集类型(功能/接口/场景)' ,
`execute_method` VARCHAR(50) NOT NULL COMMENT '执行方式(串行/并行)' ,
`pos` BIGINT NOT NULL COMMENT '自定义排序间隔为2的N次幂' ,
PRIMARY KEY (id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试集类型';
CREATE INDEX idx_test_plan_id ON test_plan_allocation_type(test_plan_id);
-- 测试集
CREATE TABLE IF NOT EXISTS test_plan_collection(
`id` VARCHAR(50) NOT NULL COMMENT 'ID' ,

View File

@ -30,7 +30,7 @@ public class TestPlanStatisticsResponse {
private Double executeRate;
/**
* 执行进度中的用例数量统计 (暂定)
* 执行进度中的用例数量统计
*/
@Schema(description = "成功用例数量")
private Integer successCount = 0;
@ -44,7 +44,7 @@ public class TestPlanStatisticsResponse {
private Integer pendingCount = 0;
/**
* 用例数中用例数量统计 (暂定)
* 用例数中用例数量统计
*/
@Schema(description = "用例总数")
private Integer caseTotal = 0;

View File

@ -57,4 +57,12 @@ public interface ExtTestPlanApiCaseMapper {
List<ModuleCountDTO> collectionCountByRequest(@Param("testPlanId") String testPlanId);
Long getMaxPosByCollectionId(String collectionId);
/**
* 获取计划下的功能用例集合
*
* @param planIds 测试计划ID集合
* @return 计划功能用例集合
*/
List<TestPlanApiCase> getPlanApiCaseByIds(@Param("planIds") List<String> planIds);
}

View File

@ -656,4 +656,18 @@
FROM test_plan_api_case
WHERE test_plan_collection_id = #{0}
</select>
<select id="getPlanApiCaseByIds" resultType="io.metersphere.plan.domain.TestPlanApiCase">
select tpac.test_plan_id testPlanId, tpac.api_case_id apiCaseId, tpac.last_exec_result lastExecResult
from test_plan_api_case tpac join api_test_case atc on atc.id = tpac.api_case_id
<where>
atc.deleted = false
<if test="planIds != null and planIds.size() > 0">
and tpac.test_plan_id in
<foreach collection="planIds" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</if>
</where>
</select>
</mapper>

View File

@ -3,7 +3,6 @@ package io.metersphere.plan.mapper;
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
import io.metersphere.functional.dto.ProjectOptionDTO;
import io.metersphere.plan.domain.TestPlanApiScenario;
import io.metersphere.plan.dto.ApiCaseModuleDTO;
import io.metersphere.plan.dto.ApiScenarioModuleDTO;
import io.metersphere.plan.dto.ResourceSelectParam;
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
@ -48,4 +47,12 @@ public interface ExtTestPlanApiScenarioMapper {
List<ProjectOptionDTO> selectRootIdByTestPlanId(@Param("testPlanId") String testPlanId);
List<ApiScenarioModuleDTO> selectBaseByProjectIdAndTestPlanId(@Param("testPlanId") String testPlanId);
/**
* 获取计划下的功能用例集合
*
* @param planIds 测试计划ID集合
* @return 计划功能用例集合
*/
List<TestPlanApiScenario> getPlanApiScenarioByIds(@Param("planIds") List<String> planIds);
}

View File

@ -373,4 +373,17 @@
(SELECT api_scenario.module_id FROM api_scenario LEFT JOIN test_plan_api_scenario ON api_scenario.id = test_plan_api_scenario.api_scenario_id WHERE test_plan_api_scenario.test_plan_id = #{testPlanId} AND api_scenario.deleted = false)
ORDER BY pos
</select>
<select id="getPlanApiScenarioByIds" resultType="io.metersphere.plan.domain.TestPlanApiScenario">
select tpas.test_plan_id testPlanId, tpas.api_scenario_id apiScenarioId, tpas.last_exec_result lastExecResult
from test_plan_api_scenario tpas join api_scenario asce on asce.id = tpas.api_scenario_id
<where>
<if test="planIds != null and planIds.size() > 0">
tpas.test_plan_id in
<foreach collection="planIds" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</if>
</where>
</select>
</mapper>

View File

@ -508,9 +508,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
public void initResourceDefaultCollection(String planId, List<TestPlanCollectionDTO> allCollections) {
// 批处理旧数据
List<TestPlanCollectionDTO> defaultCollections = new ArrayList<>();
allCollections.forEach(allCollection -> {
defaultCollections.addAll(allCollection.getChildren());
});
allCollections.forEach(allCollection -> defaultCollections.addAll(allCollection.getChildren()));
Map<String, TestPlanResourceService> beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class);
beansOfType.forEach((k, v) -> v.initResourceDefaultCollection(planId, defaultCollections));
}
@ -860,7 +858,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
defaultCollection.setStopOnFail(false);
defaultCollection.setCreateUser(currentUser);
defaultCollection.setCreateTime(System.currentTimeMillis());
Long initPos = 1L;
long initPos = 1L;
for (CaseType caseType : CaseType.values()) {
// 测试集分类
TestPlanCollectionDTO parentCollectionDTO = new TestPlanCollectionDTO();

View File

@ -1,13 +1,9 @@
package io.metersphere.plan.service;
import io.metersphere.plan.domain.TestPlanConfig;
import io.metersphere.plan.domain.TestPlanConfigExample;
import io.metersphere.plan.domain.TestPlanFunctionalCase;
import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.response.TestPlanBugPageResponse;
import io.metersphere.plan.dto.response.TestPlanStatisticsResponse;
import io.metersphere.plan.mapper.ExtTestPlanBugMapper;
import io.metersphere.plan.mapper.ExtTestPlanFunctionalCaseMapper;
import io.metersphere.plan.mapper.TestPlanConfigMapper;
import io.metersphere.plan.mapper.*;
import io.metersphere.plan.utils.RateCalculateUtils;
import io.metersphere.sdk.constants.ExecStatus;
import io.metersphere.sdk.constants.ScheduleResourceType;
@ -35,52 +31,52 @@ public class TestPlanStatisticsService {
@Resource
private ExtTestPlanFunctionalCaseMapper extTestPlanFunctionalCaseMapper;
@Resource
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@Resource
private ExtTestPlanApiScenarioMapper extTestPlanApiScenarioMapper;
@Resource
private ExtTestPlanBugMapper extTestPlanBugMapper;
@Resource
private ScheduleMapper scheduleMapper;
/**
* 计划的用例统计数据
* 计划/计划组的用例统计数据
*
* @param plans 计划集合
*/
public void calculateCaseCount(List<? extends TestPlanStatisticsResponse> plans) {
// TODO 计算计划下各种维度的用例统计数目 (待定)
/*
* 1. 查询计划下的用例数据集合(目前只有功能用例)
* 2. 根据执行结果统计(结果小数保留两位)
* 1. 查询计划下的用例数据集合
*/
List<String> planIds = plans.stream().map(TestPlanStatisticsResponse::getId).toList();
// 计划-功能用例的关联数据
List<TestPlanFunctionalCase> planFunctionalCases = extTestPlanFunctionalCaseMapper.getPlanFunctionalCaseByIds(planIds);
Map<String, List<TestPlanFunctionalCase>> planFunctionalCaseMap = planFunctionalCases.stream().collect(Collectors.groupingBy(TestPlanFunctionalCase::getTestPlanId));
Map<String, List<TestPlanFunctionalCase>> planFunctionalCaseMap = getFunctionalCaseMapByPlanIds(planIds);
Map<String, List<TestPlanApiCase>> planApiCaseMap = getApiCaseMapByPlanIds(planIds);
Map<String, List<TestPlanApiScenario>> planApiScenarioMap = getApiScenarioByPlanIds(planIds);
// 计划-缺陷的关联数据
List<TestPlanBugPageResponse> planBugs = extTestPlanBugMapper.countBugByIds(planIds);
Map<String, List<TestPlanBugPageResponse>> planBugMap = planBugs.stream().collect(Collectors.groupingBy(TestPlanBugPageResponse::getTestPlanId));
// TODO: 计划-接口用例的关联数据
plans.forEach(plan -> {
// 功能用例统计开始
List<TestPlanFunctionalCase> functionalCases = planFunctionalCaseMap.get(plan.getId());
plan.setFunctionalCaseCount(CollectionUtils.isNotEmpty(functionalCases) ? functionalCases.size() : 0);
List<TestPlanApiCase> apiCases = planApiCaseMap.get(plan.getId());
plan.setApiCaseCount(CollectionUtils.isNotEmpty(apiCases) ? apiCases.size() : 0);
List<TestPlanApiScenario> apiScenarios = planApiScenarioMap.get(plan.getId());
plan.setApiScenarioCount(CollectionUtils.isNotEmpty(apiScenarios) ? apiScenarios.size() : 0);
List<TestPlanBugPageResponse> bugs = planBugMap.get(plan.getId());
plan.setBugCount(CollectionUtils.isNotEmpty(bugs) ? bugs.size() : 0);
// TODO: 接口用例统计开始
// FIXME: CaseTotal后续会补充接口用例及场景的统计数据
plan.setCaseTotal(plan.getFunctionalCaseCount());
plan.setCaseTotal(plan.getFunctionalCaseCount() + plan.getApiCaseCount() + plan.getApiScenarioCount());
});
}
/**
* 计划{通过率, 执行进度}统计数据
* 计划/计划组{通过率, 执行进度}统计数据
*
* @param planIds 计划ID集合
*/
public List<TestPlanStatisticsResponse> calculateRate(List<String> planIds) {
List<TestPlanStatisticsResponse> planStatisticsResponses = new ArrayList<>();
// TODO 计算计划下的用例通过率, 执行进度 (待定)
/*
* 1. 查询计划下的用例数据集合(目前只有功能用例)
* 1. 查询计划下的用例数据集合
* 2. 根据执行结果统计(结果小数保留两位)
*/
@ -89,9 +85,10 @@ public class TestPlanStatisticsService {
example.createCriteria().andTestPlanIdIn(planIds);
List<TestPlanConfig> testPlanConfigList = testPlanConfigMapper.selectByExample(example);
Map<String, TestPlanConfig> planConfigMap = testPlanConfigList.stream().collect(Collectors.toMap(TestPlanConfig::getTestPlanId, p -> p));
// 计划-功能用例的关联数据
List<TestPlanFunctionalCase> planFunctionalCases = extTestPlanFunctionalCaseMapper.getPlanFunctionalCaseByIds(planIds);
Map<String, List<TestPlanFunctionalCase>> planFunctionalCaseMap = planFunctionalCases.stream().collect(Collectors.groupingBy(TestPlanFunctionalCase::getTestPlanId));
// 关联的用例数据
Map<String, List<TestPlanFunctionalCase>> planFunctionalCaseMap = getFunctionalCaseMapByPlanIds(planIds);
Map<String, List<TestPlanApiCase>> planApiCaseMap = getApiCaseMapByPlanIds(planIds);
Map<String, List<TestPlanApiScenario>> planApiScenarioMap = getApiScenarioByPlanIds(planIds);
//查询定时任务
ScheduleExample scheduleExample = new ScheduleExample();
@ -99,34 +96,32 @@ public class TestPlanStatisticsService {
List<Schedule> schedules = scheduleMapper.selectByExample(scheduleExample);
Map<String, Schedule> scheduleMap = schedules.stream().collect(Collectors.toMap(Schedule::getResourceId, t -> t));
// TODO: 计划-接口用例的关联数据
planIds.forEach(planId -> {
TestPlanStatisticsResponse statisticsResponse = new TestPlanStatisticsResponse();
statisticsResponse.setId(planId);
statisticsResponse.setPassThreshold(planConfigMap.get(planId).getPassThreshold());
int success = 0, error = 0, fakeError = 0, block = 0, pending = 0;
// 功能用例统计开始
// 功能用例分组统计开始 (为空时, 默认为未执行)
List<TestPlanFunctionalCase> functionalCases = planFunctionalCaseMap.get(planId);
statisticsResponse.setFunctionalCaseCount(CollectionUtils.isNotEmpty(functionalCases) ? functionalCases.size() : 0);
// 根据执行结果分组(为空, 默认为未执行)
Map<String, List<TestPlanFunctionalCase>> functionalCaseResultMap = CollectionUtils.isEmpty(functionalCases) ? new HashMap<>(16) : functionalCases.stream().collect(
Collectors.groupingBy(functionalCase -> Optional.ofNullable(functionalCase.getLastExecResult()).orElse(ExecStatus.PENDING.name())));
success += functionalCaseResultMap.containsKey(ExecStatus.SUCCESS.name()) ? functionalCaseResultMap.get(ExecStatus.SUCCESS.name()).size() : 0;
error += functionalCaseResultMap.containsKey(ExecStatus.ERROR.name()) ? functionalCaseResultMap.get(ExecStatus.ERROR.name()).size() : 0;
fakeError += functionalCaseResultMap.containsKey(ExecStatus.FAKE_ERROR.name()) ? functionalCaseResultMap.get(ExecStatus.FAKE_ERROR.name()).size() : 0;
block += functionalCaseResultMap.containsKey(ExecStatus.BLOCKED.name()) ? functionalCaseResultMap.get(ExecStatus.BLOCKED.name()).size() : 0;
pending += functionalCaseResultMap.containsKey(ExecStatus.PENDING.name()) ? functionalCaseResultMap.get(ExecStatus.PENDING.name()).size() : 0;
// TODO: 接口用例统计开始
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(success);
statisticsResponse.setErrorCount(error);
statisticsResponse.setFakeErrorCount(fakeError);
statisticsResponse.setBlockCount(block);
statisticsResponse.setPendingCount(pending);
// FIXME: CaseTotal后续会补充接口用例及场景的统计数据
statisticsResponse.setCaseTotal(statisticsResponse.getFunctionalCaseCount());
statisticsResponse.setSuccessCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ExecStatus.SUCCESS.name()));
statisticsResponse.setErrorCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ExecStatus.ERROR.name()));
statisticsResponse.setFakeErrorCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ExecStatus.FAKE_ERROR.name()));
statisticsResponse.setBlockCount(countCaseMap(functionalCaseResultCountMap, apiCaseResultCountMap, apiScenarioResultCountMap, ExecStatus.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));
@ -151,4 +146,37 @@ public class TestPlanStatisticsService {
});
return planStatisticsResponses;
}
private Map<String, List<TestPlanFunctionalCase>> getFunctionalCaseMapByPlanIds(List<String> planIds) {
// 计划或者组-功能用例的关联数据
List<TestPlanFunctionalCase> planFunctionalCases = extTestPlanFunctionalCaseMapper.getPlanFunctionalCaseByIds(planIds);
return planFunctionalCases.stream().collect(Collectors.groupingBy(TestPlanFunctionalCase::getTestPlanId));
}
private Map<String, List<TestPlanApiCase>> getApiCaseMapByPlanIds(List<String> planIds) {
// 计划或者组-接口用例的关联数据
List<TestPlanApiCase> planApiCases = extTestPlanApiCaseMapper.getPlanApiCaseByIds(planIds);
return planApiCases.stream().collect(Collectors.groupingBy(TestPlanApiCase::getTestPlanId));
}
private Map<String, List<TestPlanApiScenario>> getApiScenarioByPlanIds(List<String> planIds) {
// 计划或者组-场景用例的关联数据
List<TestPlanApiScenario> planApiScenarios = extTestPlanApiScenarioMapper.getPlanApiScenarioByIds(planIds);
return planApiScenarios.stream().collect(Collectors.groupingBy(TestPlanApiScenario::getTestPlanId));
}
/**
* 汇总计划下所有的用例的集合
* @param functionalCaseMap 功能用例
* @param apiCaseMap 接口用例
* @param apiScenarioMap 接口场景
* @param countKey 汇总的key
* @return 总数
*/
private Integer countCaseMap(Map<String, Long> functionalCaseMap, Map<String, Long> apiCaseMap, Map<String, Long> apiScenarioMap, String countKey) {
return (functionalCaseMap.containsKey(countKey) ? functionalCaseMap.get(countKey).intValue() : 0) +
(apiCaseMap.containsKey(countKey) ? apiCaseMap.get(countKey).intValue() : 0) +
(apiScenarioMap.containsKey(countKey) ? apiScenarioMap.get(countKey).intValue() : 0);
}
}

View File

@ -38,6 +38,18 @@ INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, r
('oasis_fc_4', 10004, 'TEST_MODULE_ID', 'project-associate-case-test', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'BLOCKED', b'0', b'0', b'1', 'admin', 'admin', '', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
('oasis_fc_5', 10005, 'TEST_MODULE_ID', 'project-associate-case-test', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'FAKE_ERROR', b'0', b'0', b'1', 'admin', 'admin', '', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL);
INSERT INTO test_plan_api_case(`id`, `test_plan_id`, `api_case_id`, `environment_id`, `last_exec_result`, `last_exec_report_id`, `execute_user`, `create_time`, `create_user`, `pos`, `test_plan_collection_id`) VALUES
('oasis_1', 'wx_test_plan_id_7', 'oasis_ac_1', '1', 'PASSED', NULL, 'admin', 1716370415311, 'admin', 1, '123');
INSERT INTO api_test_case(id, name, priority, num, tags, status, last_report_status, last_report_id, pos, project_id, api_definition_id, version_id, environment_id, create_time, create_user, update_time, update_user, delete_time, delete_user, deleted) VALUES
('oasis_ac_1', 'oasis_ac', 'P0', 1001, null, 'Underway', 'PENDING', null, 100, 'project-associate-case-test', 'oasis_ac_definition', 'oasis_ac_version_id', 'oasis_ac_env_id', 1698058347559, 'admin', 1698058347559, 'admin', null, null, false);
INSERT INTO test_plan_api_scenario (id, test_plan_id, api_scenario_id, environment_id, execute_user, last_exec_result, last_exec_report_id, create_time, create_user, pos, test_plan_collection_id, grouped) VALUES
('oasis_1', 'wx_test_plan_id_7', 'oasis_as_1', '1', 'admin', 'PASSED', NULL, 1716370415311, 'admin', 1, '123', false);
INSERT INTO api_scenario(id, name, priority, status, last_report_status, last_report_id, num, pos, version_id, ref_id, project_id, module_id, description, tags, create_user, create_time, delete_time, delete_user, update_user, update_time, deleted) VALUES
('oasis_as_1', 'oasis_as', 'P0', 'Underway', 'PENDING', null, 1000001, 1, 'oasis_as_version_id', 'as-rid', 'test-associate-pro', 'root', null, null, 'admin', UNIX_TIMESTAMP() * 1000, null, null, 'admin', UNIX_TIMESTAMP() * 1000, false);
INSERT INTO `test_plan_module`(`id`, `project_id`, `name`, `parent_id`, `pos`, `create_time`, `update_time`, `create_user`, `update_user`)
VALUES ('1', 'songtianyang-fix-wx', 'wx_测试模块名称', 'ROOT', 1, 1714980158000, 1714980158000, 'admin', 'admin');
@ -72,3 +84,4 @@ INSERT INTO `test_plan_collection`(`id`, `test_plan_id`, `name`, `type`, `enviro
('init_collection-delete-2', 'init_plan_id', '接口功能点', 'API', '1', '1', 1, 'admin', unix_timestamp() * 1000),
('init_collection-delete-3', 'init_plan_id', '场景功能点', 'SCENARIO', '1', '1', 1, 'admin', unix_timestamp() * 1000),
('init_collection-delete-4', 'init_plan_id', '未知的功能点', 'UNKNOWN', '1', '1', 1, 'admin', unix_timestamp() * 1000);