feat(测试计划): 补充报告详情功能

This commit is contained in:
song-cc-rock 2024-05-16 21:16:58 +08:00 committed by Craftsman
parent 0ff9b831cd
commit 2a3421f91d
9 changed files with 341 additions and 17 deletions

View File

@ -2,11 +2,15 @@ package io.metersphere.plan.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.functional.dto.FunctionalCasePageDTO;
import io.metersphere.plan.constants.TestPlanResourceConfig;
import io.metersphere.plan.domain.TestPlanReport;
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
import io.metersphere.plan.dto.request.TestPlanReportDetailPageRequest;
import io.metersphere.plan.dto.request.TestPlanReportGenRequest;
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
import io.metersphere.plan.dto.response.TestPlanReportDetailResponse;
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
import io.metersphere.plan.service.TestPlanManagementService;
import io.metersphere.plan.service.TestPlanReportLogService;
@ -87,4 +91,32 @@ public class TestPlanReportController {
public TestPlanReport genReportByManual(@Validated @RequestBody TestPlanReportGenRequest request) {
return testPlanReportService.genReportByManual(request, SessionUtils.getUserId());
}
@GetMapping("/get/{id}")
@Operation(summary = "测试计划-报告-详情")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#id", resourceType = "test_plan_report")
public TestPlanReportDetailResponse get(@PathVariable String id) {
return testPlanReportService.getReport(id);
}
@PostMapping("/detail/bug/page")
@Operation(summary = "测试计划-报告-详情-缺陷分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#request.getReportId()", resourceType = "test_plan_report")
public Pager<List<BugDTO>> pageBug(@Validated @RequestBody TestPlanReportDetailPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "b.num desc");
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailBugs(request));
}
@PostMapping("/detail/functional/case/page")
@Operation(summary = "测试计划-报告-详情-功能用例分页查询")
@RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ)
@CheckOwner(resourceId = "#request.getReportId()", resourceType = "test_plan_report")
public Pager<List<FunctionalCasePageDTO>> pageFunctionalCase(@Validated @RequestBody TestPlanReportDetailPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "fc.num desc");
return PageUtils.setPageInfo(page, testPlanReportService.listReportDetailFunctionalCases(request));
}
}

View File

@ -0,0 +1,10 @@
package io.metersphere.plan.dto;
import lombok.Data;
@Data
public class CaseStatusCountMap {
private String status;
private Long count;
}

View File

@ -0,0 +1,20 @@
package io.metersphere.plan.dto.request;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class TestPlanReportDetailPageRequest extends BasePageRequest {
@Schema(description = "报告ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan.report_id.not_blank}")
private String reportId;
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan.report_id.not_blank}")
private String projectId;
}

View File

@ -0,0 +1,73 @@
package io.metersphere.plan.dto.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TestPlanReportDetailResponse {
@Schema(description = "报告ID")
private String id;
@Schema(description = "报告名称")
private String name;
@Schema(description = "报告开始时间")
private Long startTime;
@Schema(description = "报告执行开始时间")
private Long executeTime;
@Schema(description = "报告结束(执行)时间")
private Long ednTime;
/**
* 报告分析
*/
@Schema(description = "通过阈值")
private Double passThreshold;
@Schema(description = "通过率")
private Double passRate;
@Schema(description = "执行完成率")
private Double executeRate;
@Schema(description = "缺陷总数")
private Integer bugCount;
@Schema(description = "用例总数")
private Integer caseTotal = 0;
/**
* 执行分析
*/
@Schema(description = "执行分析-用例数")
private CaseCount executeCount;
/**
* 功能用例分析
*/
@Schema(description = "功能用例分析-用例数")
private CaseCount functionalCount;
/**
* 接口用例分析
*/
@Schema(description = "接口用例分析-用例数")
private CaseCount apiCaseCount;
/**
* 接口场景用例分析
*/
@Schema(description = "接口场景用例分析-用例数")
private CaseCount apiScenarioCount;
/**
* 功能, 接口, 场景
*/
@Data
public static class CaseCount {
@Schema(description = "成功用例数量")
private Integer success = 0;
@Schema(description = "失败用例数量")
private Integer error = 0;
@Schema(description = "误报用例数量")
private Integer fakeError = 0;
@Schema(description = "阻塞用例数量")
private Integer block = 0;
@Schema(description = "未执行用例数量")
private Integer pending = 0;
}
}

View File

@ -1,7 +1,11 @@
package io.metersphere.plan.mapper;
import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.functional.dto.FunctionalCasePageDTO;
import io.metersphere.plan.domain.TestPlanReport;
import io.metersphere.plan.dto.CaseStatusCountMap;
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
import io.metersphere.plan.dto.request.TestPlanReportDetailPageRequest;
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
import io.metersphere.system.dto.sdk.ApiReportMessageDTO;
@ -37,4 +41,25 @@ public interface ExtTestPlanReportMapper {
List<TestPlanReport> selectReportByIds(@Param("ids") List<String> ids);
List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> subList);
/**
* 统计报告中功能用例执行情况
* @param reportId 报告ID
* @return 用例数量
*/
List<CaseStatusCountMap> countFunctionalCaseExecuteResult(@Param("id") String reportId);
/**
* 分页查询报告关联的缺陷
* @param request 请求参数
* @return 关联的缺陷集合
*/
List<BugDTO> listReportBugs(@Param("request")TestPlanReportDetailPageRequest request);
/**
* 分页查询报告关联的用例
* @param request 请求参数
* @return 关联的用例集合
*/
List<FunctionalCasePageDTO> listReportFunctionalCases(@Param("request")TestPlanReportDetailPageRequest request);
}

View File

@ -21,6 +21,24 @@
where tprfc.test_plan_report_id = #{id} and tprfc.execute_result = 'SUCCESS'
</select>
<select id="countFunctionalCaseExecuteResult" resultType="io.metersphere.plan.dto.CaseStatusCountMap">
select execute_result as status, count(*) as count from test_plan_report_function_case
where test_plan_report_id = #{id}
group by execute_result
</select>
<select id="listReportBugs" resultType="io.metersphere.bug.dto.response.BugDTO">
select distinct b.id as id, b.num as num, b.title as title, b.status as status, b.handle_user as handleUser
from test_plan_report_bug tprb inner join bug b on tprb.bug_id = b.id
where tprb.test_plan_report_id = #{request.reportId}
</select>
<select id="listReportFunctionalCases" resultType="io.metersphere.functional.dto.FunctionalCasePageDTO">
select distinct fc.id as id, fc.num as num, fc.name as name, tprfc.execute_result as lastExecuteResult
from test_plan_report_function_case tprfc inner join functional_case fc on tprfc.function_case_id = fc.id
where tprfc.test_plan_report_id = #{request.reportId}
</select>
<select id="selectReportByIds" resultType="io.metersphere.plan.domain.TestPlanReport">
select * from test_plan_report where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">

View File

@ -1,19 +1,21 @@
package io.metersphere.plan.service;
import io.metersphere.bug.mapper.BugRelationCaseMapper;
import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.bug.mapper.ExtBugRelateCaseMapper;
import io.metersphere.bug.service.BugService;
import io.metersphere.functional.dto.FunctionalCasePageDTO;
import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.CaseStatusCountMap;
import io.metersphere.plan.dto.TestPlanReportGenPreParam;
import io.metersphere.plan.dto.TestPlanReportPostParam;
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
import io.metersphere.plan.dto.request.TestPlanReportDetailPageRequest;
import io.metersphere.plan.dto.request.TestPlanReportGenRequest;
import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
import io.metersphere.plan.dto.response.TestPlanReportDetailResponse;
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
import io.metersphere.plan.mapper.*;
import io.metersphere.sdk.constants.ExecStatus;
import io.metersphere.sdk.constants.ReportStatus;
import io.metersphere.sdk.constants.TaskTriggerMode;
import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.DateUtils;
@ -37,6 +39,7 @@ import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class TestPlanReportService {
@ -48,6 +51,8 @@ public class TestPlanReportService {
@Resource
private SqlSessionFactory sqlSessionFactory;
@Resource
private BugService bugService;
@Resource
private TestPlanMapper testPlanMapper;
@Resource
private TestPlanConfigMapper testPlanConfigMapper;
@ -56,8 +61,6 @@ public class TestPlanReportService {
@Resource
private ExtBugRelateCaseMapper extBugRelateCaseMapper;
@Resource
private BugRelationCaseMapper bugRelationCaseMapper;
@Resource
private ExtTestPlanReportMapper extTestPlanReportMapper;
@Resource
private TestPlanReportLogService testPlanReportLogService;
@ -153,6 +156,10 @@ public class TestPlanReportService {
TestPlanReportPostParam postParam = new TestPlanReportPostParam();
BeanUtils.copyBean(postParam, request);
postParam.setReportId(preReport.getId());
// 手动生成报告, 执行状态为已完成, 执行及结束时间为当前时间
postParam.setExecuteTime(System.currentTimeMillis());
postParam.setEndTime(System.currentTimeMillis());
postParam.setExecStatus(ExecStatus.COMPLETED.name());
return postHandleReport(postParam);
}
@ -253,15 +260,15 @@ public class TestPlanReportService {
example.createCriteria().andTestPlanReportIdEqualTo(postParam.getReportId());
TestPlanReportSummary reportSummary = testPlanReportSummaryMapper.selectByExample(example).get(0);
DecimalFormat rateFormat = new DecimalFormat("#0.0000");
rateFormat.setMinimumFractionDigits(2);
rateFormat.setMaximumFractionDigits(2);
rateFormat.setMinimumFractionDigits(4);
rateFormat.setMaximumFractionDigits(4);
// 通过的功能用例数
// TODO: 接口用例, 场景用例
long functionalCasePassCount = extTestPlanReportMapper.countExecuteSuccessFunctionalCase(postParam.getReportId());
// 用例总数
long caseTotal = reportSummary.getFunctionalCaseCount() + reportSummary.getApiCaseCount() + reportSummary.getApiScenarioCount();
// 通过率 {通过用例数/总用例数}
double passRate = (functionalCasePassCount == 0 || caseTotal == 0) ? 0.00 :
double passRate = (functionalCasePassCount == 0 || caseTotal == 0) ? 0.0000 :
Double.parseDouble(rateFormat.format((double) functionalCasePassCount / (double) caseTotal));
// FIXME: 后续替换成PASS_COUNT {保留该逻辑, 四舍五入导致的边界值数据展示偏差}
if (passRate == 0 && functionalCasePassCount > 0) {
@ -275,6 +282,93 @@ public class TestPlanReportService {
return planReport;
}
/**
* 获取报告分析详情
* @param reportId 报告ID
* @return 报告分析详情
*/
public TestPlanReportDetailResponse getReport(String reportId) {
TestPlanReport planReport = checkReport(reportId);
TestPlanReportSummaryExample example = new TestPlanReportSummaryExample();
example.createCriteria().andTestPlanReportIdEqualTo(reportId);
TestPlanReportSummary reportSummary = testPlanReportSummaryMapper.selectByExample(example).get(0);
TestPlanReportDetailResponse planReportDetail = new TestPlanReportDetailResponse();
BeanUtils.copyBean(planReportDetail, planReport);
int caseTotal = (int) (reportSummary.getFunctionalCaseCount() + reportSummary.getApiCaseCount() + reportSummary.getApiScenarioCount());
planReportDetail.setCaseTotal(caseTotal);
planReportDetail.setBugCount(reportSummary.getBugCount().intValue());
/*
* 统计用例执行数据
*/
return statisticsCase(planReportDetail);
}
/**
* 分页查询报告详情-缺陷分页数据
* @param request 请求参数
* @return 缺陷分页数据
*/
public List<BugDTO> listReportDetailBugs(TestPlanReportDetailPageRequest request) {
List<BugDTO> bugs = extTestPlanReportMapper.listReportBugs(request);
return bugService.handleCustomField(bugs, request.getProjectId());
}
/**
* 分页查询报告详情-缺陷分页数据
* @param request 请求参数
* @return 缺陷分页数据
*/
public List<FunctionalCasePageDTO> listReportDetailFunctionalCases(TestPlanReportDetailPageRequest request) {
return extTestPlanReportMapper.listReportFunctionalCases(request);
}
/**
* 统计用例执行数据 (目前只统计功能用例)
* @param reportDetail 用例详情
*/
private TestPlanReportDetailResponse statisticsCase(TestPlanReportDetailResponse reportDetail) {
// 功能用例 (无误报状态)
List<CaseStatusCountMap> functionalCaseCountMap = extTestPlanReportMapper.countFunctionalCaseExecuteResult(reportDetail.getId());
Map<String, Long> functionalCaseResultMap = functionalCaseCountMap.stream().collect(Collectors.toMap(CaseStatusCountMap::getStatus, CaseStatusCountMap::getCount));
TestPlanReportDetailResponse.CaseCount functionalCaseCount = new TestPlanReportDetailResponse.CaseCount();
functionalCaseCount.setSuccess(functionalCaseResultMap.getOrDefault(FunctionalCaseExecuteResult.SUCCESS.name(), 0L).intValue());
functionalCaseCount.setError(functionalCaseResultMap.getOrDefault(FunctionalCaseExecuteResult.ERROR.name(), 0L).intValue());
functionalCaseCount.setPending(functionalCaseResultMap.getOrDefault(FunctionalCaseExecuteResult.PENDING.name(), 0L).intValue());
functionalCaseCount.setBlock(functionalCaseResultMap.getOrDefault(FunctionalCaseExecuteResult.BLOCKED.name(), 0L).intValue());
// TODO: 接口用例, 场景用例
// FIXME: 目前只有功能用例
TestPlanReportDetailResponse.CaseCount executeCaseCount = new TestPlanReportDetailResponse.CaseCount();
executeCaseCount.setSuccess(functionalCaseCount.getSuccess());
executeCaseCount.setError(functionalCaseCount.getError());
executeCaseCount.setFakeError(functionalCaseCount.getFakeError());
executeCaseCount.setPending(functionalCaseCount.getPending());
executeCaseCount.setBlock(functionalCaseCount.getBlock());
// 计算执行完成率
DecimalFormat rateFormat = new DecimalFormat("#0.00");
rateFormat.setMinimumFractionDigits(2);
rateFormat.setMaximumFractionDigits(2);
// 执行完成率 {已执行用例数/总用例数}
double executeRate = (executeCaseCount.getPending().equals(reportDetail.getCaseTotal()) || reportDetail.getCaseTotal() == 0) ? 0.00 :
Double.parseDouble(rateFormat.format((double) (reportDetail.getCaseTotal() - executeCaseCount.getPending()) / (double) reportDetail.getCaseTotal()));
// FIXME: 后续替换成PASS_COUNT {保留该逻辑, 四舍五入导致的边界值数据展示偏差}
if (executeRate == 0 && reportDetail.getCaseTotal() - executeCaseCount.getPending() > 0) {
executeRate = 0.01;
} else if (executeRate == 100 && executeCaseCount.getPending() > 0) {
executeRate = 99.99;
}
// 详情数据
reportDetail.setExecuteRate(executeRate);
reportDetail.setFunctionalCount(functionalCaseCount);
reportDetail.setExecuteCount(executeCaseCount);
return reportDetail;
}
/**
* 通过请求参数获取批量操作的ID集合
*

View File

@ -1,5 +1,6 @@
package io.metersphere.plan.controller;
import io.metersphere.plan.domain.TestPlanReport;
import io.metersphere.plan.dto.TestPlanShareInfo;
import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
@ -33,10 +34,15 @@ public class TestPlanReportControllerTests extends BaseTest {
private static final String DELETE_PLAN_REPORT = "/test-plan/report/delete";
private static final String BATCH_DELETE_PLAN_REPORT = "/test-plan/report/batch-delete";
private static final String GEN_PLAN_REPORT = "/test-plan/report/gen";
private static final String GET_PLAN_REPORT = "/test-plan/report/get";
private static final String GET_PLAN_REPORT_DETAIL_BUG_PAGE = "/test-plan/report/detail/bug/page";
private static final String GET_PLAN_REPORT_DETAIL_FUNCTIONAL_PAGE = "/test-plan/report/detail/functional/case/page";
private static final String GEN_AND_SHARE = "/test-plan/report/share/gen";
private static final String GET_SHARE_INFO = "/test-plan/report/share/get";
private static final String GET_SHARE_TIME = "/test-plan/report/share/get-share-time";
private static String GEN_REPORT_ID;
@Test
@Order(1)
@Sql(scripts = {"/dml/init_test_plan_report.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
@ -181,6 +187,44 @@ public class TestPlanReportControllerTests extends BaseTest {
genRequest.setTestPlanId("plan_id_for_gen_report_1");
this.requestPost(GEN_PLAN_REPORT, genRequest);
genRequest.setTestPlanId("plan_id_for_gen_report");
this.requestPost(GEN_PLAN_REPORT, genRequest);
MvcResult mvcResult = this.requestPostAndReturn(GEN_PLAN_REPORT, genRequest);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
//返回请求正常
Assertions.assertNotNull(resultHolder);
TestPlanReport report = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanReport.class);
GEN_REPORT_ID = report.getId();
}
@Test
@Order(12)
void testGetReportSuccess() throws Exception {
this.requestGet(GET_PLAN_REPORT + "/" + GEN_REPORT_ID);
}
@Test
@Order(13)
void testPageReportDetailBugSuccess() throws Exception {
TestPlanReportDetailPageRequest request = new TestPlanReportDetailPageRequest();
request.setReportId(GEN_REPORT_ID);
request.setProjectId("100001100001");
request.setCurrent(1);
request.setPageSize(10);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_BUG_PAGE, request);
request.setSort(Map.of("num", "asc"));
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_BUG_PAGE, request);
}
@Test
@Order(14)
void testPageReportDetailFunctionalCaseSuccess() throws Exception {
TestPlanReportDetailPageRequest request = new TestPlanReportDetailPageRequest();
request.setReportId(GEN_REPORT_ID);
request.setProjectId("100001100001");
request.setCurrent(1);
request.setPageSize(10);
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_FUNCTIONAL_PAGE, request);
request.setSort(Map.of("num", "asc"));
this.requestPostWithOk(GET_PLAN_REPORT_DETAIL_FUNCTIONAL_PAGE, request);
}
}

View File

@ -8,12 +8,20 @@ INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repea
-- 计划关联用例执行的测试数据
INSERT INTO `test_plan_functional_case` (`id`, `test_plan_id`, `functional_case_id`, `create_time`, `create_user`, `execute_user`, `last_exec_time`, `last_exec_result`, `pos`) VALUES
('plan_id_for_gen_report_case_1', 'plan_id_for_gen_report', 'f1', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'PENDING', 1),
('plan_id_for_gen_report_case_2', 'plan_id_for_gen_report', 'f2', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'SUCCESS', 2),
('plan_id_for_gen_report_case_3', 'plan_id_for_gen_report', 'f3', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'ERROR', 3),
('plan_id_for_gen_report_case_4', 'plan_id_for_gen_report', 'f4', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'BLOCKED', 4),
('plan_id_for_gen_report_case_5', 'plan_id_for_gen_report', 'f5', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'FAKE_ERROR', 5);
('plan_id_for_gen_report_case_1', 'plan_id_for_gen_report', 'f1_gen', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'PENDING', 1),
('plan_id_for_gen_report_case_2', 'plan_id_for_gen_report', 'f2_gen', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'SUCCESS', 2),
('plan_id_for_gen_report_case_3', 'plan_id_for_gen_report', 'f3_gen', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'ERROR', 3),
('plan_id_for_gen_report_case_4', 'plan_id_for_gen_report', 'f4_gen', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'BLOCKED', 4),
('plan_id_for_gen_report_case_5', 'plan_id_for_gen_report', 'f5_gen', CURRENT_TIMESTAMP, 'admin', 'admin', CURRENT_TIMESTAMP, 'FAKE_ERROR', 5);
-- 计划关联缺陷的测试数据
INSERT INTO `bug_relation_case`(`id`, `case_id`, `bug_id`, `case_type`, `test_plan_id`, `test_plan_case_id`, `create_user`, `create_time`, `update_time`) VALUES
('test-plan-bug-relate-case-1', 'f1', 'test-plan-bug-id', 'FUNCTIONAL', 'plan_id_for_gen_report', 'f1', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
('test-plan-bug-relate-case-1', 'f1', 'test-plan-bug-for-gen', 'FUNCTIONAL', 'plan_id_for_gen_report', 'f1', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-- 缺陷的测试数据
INSERT INTO bug (id, num, title, handle_users, handle_user, create_user, create_time, update_user, update_time, delete_user, delete_time, project_id, template_id, platform, status, tags, platform_bug_id, deleted, pos) VALUES
('test-plan-bug-for-gen', 100000, 'default-bug-gen', 'oasis', 'admin', 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, '100001100001', 'bug-template-id', 'Local', 'new', '["default-tag"]', null, 0, 5000);
-- 用例的测试数据
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('f1_gen', 100001, 'TEST_MODULE_ID', '100001100001', '100001', 'functional_case_gen', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'PENDING', b'0', b'0', b'1', 'admin', 'admin', 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);