feat(测试计划): 测试计划批量执行方法开发
This commit is contained in:
parent
f5ae0cd2a2
commit
791432f490
|
@ -27,17 +27,23 @@ public class TestPlanConfig implements Serializable {
|
||||||
@NotNull(message = "{test_plan_config.repeat_case.not_blank}", groups = {Created.class})
|
@NotNull(message = "{test_plan_config.repeat_case.not_blank}", groups = {Created.class})
|
||||||
private Boolean repeatCase;
|
private Boolean repeatCase;
|
||||||
|
|
||||||
@Schema(description = "测试计划通过阈值; 0-100, 保留两位小数", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@NotNull(message = "{test_plan_config.pass_threshold.not_blank}", groups = {Created.class})
|
@NotNull(message = "{test_plan_config.pass_threshold.not_blank}", groups = {Created.class})
|
||||||
private Double passThreshold;
|
private Double passThreshold;
|
||||||
|
|
||||||
|
@Schema(description = "不同用例之间的执行方式(串行/并行)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{test_plan_config.case_run_mode.not_blank}", groups = {Created.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{test_plan_config.case_run_mode.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String caseRunMode;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public enum Column {
|
public enum Column {
|
||||||
testPlanId("test_plan_id", "testPlanId", "VARCHAR", false),
|
testPlanId("test_plan_id", "testPlanId", "VARCHAR", false),
|
||||||
automaticStatusUpdate("automatic_status_update", "automaticStatusUpdate", "BIT", false),
|
automaticStatusUpdate("automatic_status_update", "automaticStatusUpdate", "BIT", false),
|
||||||
repeatCase("repeat_case", "repeatCase", "BIT", false),
|
repeatCase("repeat_case", "repeatCase", "BIT", false),
|
||||||
passThreshold("pass_threshold", "passThreshold", "DECIMAL", false);
|
passThreshold("pass_threshold", "passThreshold", "DECIMAL", false),
|
||||||
|
caseRunMode("case_run_mode", "caseRunMode", "VARCHAR", false);
|
||||||
|
|
||||||
private static final String BEGINNING_DELIMITER = "`";
|
private static final String BEGINNING_DELIMITER = "`";
|
||||||
|
|
||||||
|
|
|
@ -354,6 +354,76 @@ public class TestPlanConfigExample {
|
||||||
addCriterion("pass_threshold not between", value1, value2, "passThreshold");
|
addCriterion("pass_threshold not between", value1, value2, "passThreshold");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeIsNull() {
|
||||||
|
addCriterion("case_run_mode is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeIsNotNull() {
|
||||||
|
addCriterion("case_run_mode is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeEqualTo(String value) {
|
||||||
|
addCriterion("case_run_mode =", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeNotEqualTo(String value) {
|
||||||
|
addCriterion("case_run_mode <>", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeGreaterThan(String value) {
|
||||||
|
addCriterion("case_run_mode >", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("case_run_mode >=", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeLessThan(String value) {
|
||||||
|
addCriterion("case_run_mode <", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("case_run_mode <=", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeLike(String value) {
|
||||||
|
addCriterion("case_run_mode like", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeNotLike(String value) {
|
||||||
|
addCriterion("case_run_mode not like", value, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeIn(List<String> values) {
|
||||||
|
addCriterion("case_run_mode in", values, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeNotIn(List<String> values) {
|
||||||
|
addCriterion("case_run_mode not in", values, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeBetween(String value1, String value2) {
|
||||||
|
addCriterion("case_run_mode between", value1, value2, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCaseRunModeNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("case_run_mode not between", value1, value2, "caseRunMode");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Criteria extends GeneratedCriteria {
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<result column="automatic_status_update" jdbcType="BIT" property="automaticStatusUpdate" />
|
<result column="automatic_status_update" jdbcType="BIT" property="automaticStatusUpdate" />
|
||||||
<result column="repeat_case" jdbcType="BIT" property="repeatCase" />
|
<result column="repeat_case" jdbcType="BIT" property="repeatCase" />
|
||||||
<result column="pass_threshold" jdbcType="DECIMAL" property="passThreshold" />
|
<result column="pass_threshold" jdbcType="DECIMAL" property="passThreshold" />
|
||||||
|
<result column="case_run_mode" jdbcType="VARCHAR" property="caseRunMode" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<sql id="Example_Where_Clause">
|
<sql id="Example_Where_Clause">
|
||||||
<where>
|
<where>
|
||||||
|
@ -66,7 +67,7 @@
|
||||||
</where>
|
</where>
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
test_plan_id, automatic_status_update, repeat_case, pass_threshold
|
test_plan_id, automatic_status_update, repeat_case, pass_threshold, case_run_mode
|
||||||
</sql>
|
</sql>
|
||||||
<select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanConfigExample" resultMap="BaseResultMap">
|
<select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanConfigExample" resultMap="BaseResultMap">
|
||||||
select
|
select
|
||||||
|
@ -100,9 +101,9 @@
|
||||||
</delete>
|
</delete>
|
||||||
<insert id="insert" parameterType="io.metersphere.plan.domain.TestPlanConfig">
|
<insert id="insert" parameterType="io.metersphere.plan.domain.TestPlanConfig">
|
||||||
insert into test_plan_config (test_plan_id, automatic_status_update, repeat_case,
|
insert into test_plan_config (test_plan_id, automatic_status_update, repeat_case,
|
||||||
pass_threshold)
|
pass_threshold, case_run_mode)
|
||||||
values (#{testPlanId,jdbcType=VARCHAR}, #{automaticStatusUpdate,jdbcType=BIT}, #{repeatCase,jdbcType=BIT},
|
values (#{testPlanId,jdbcType=VARCHAR}, #{automaticStatusUpdate,jdbcType=BIT}, #{repeatCase,jdbcType=BIT},
|
||||||
#{passThreshold,jdbcType=DECIMAL})
|
#{passThreshold,jdbcType=DECIMAL}, #{caseRunMode,jdbcType=VARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanConfig">
|
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanConfig">
|
||||||
insert into test_plan_config
|
insert into test_plan_config
|
||||||
|
@ -119,6 +120,9 @@
|
||||||
<if test="passThreshold != null">
|
<if test="passThreshold != null">
|
||||||
pass_threshold,
|
pass_threshold,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="caseRunMode != null">
|
||||||
|
case_run_mode,
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="testPlanId != null">
|
<if test="testPlanId != null">
|
||||||
|
@ -133,6 +137,9 @@
|
||||||
<if test="passThreshold != null">
|
<if test="passThreshold != null">
|
||||||
#{passThreshold,jdbcType=DECIMAL},
|
#{passThreshold,jdbcType=DECIMAL},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="caseRunMode != null">
|
||||||
|
#{caseRunMode,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
<select id="countByExample" parameterType="io.metersphere.plan.domain.TestPlanConfigExample" resultType="java.lang.Long">
|
<select id="countByExample" parameterType="io.metersphere.plan.domain.TestPlanConfigExample" resultType="java.lang.Long">
|
||||||
|
@ -156,6 +163,9 @@
|
||||||
<if test="record.passThreshold != null">
|
<if test="record.passThreshold != null">
|
||||||
pass_threshold = #{record.passThreshold,jdbcType=DECIMAL},
|
pass_threshold = #{record.passThreshold,jdbcType=DECIMAL},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.caseRunMode != null">
|
||||||
|
case_run_mode = #{record.caseRunMode,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
</set>
|
</set>
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
@ -166,7 +176,8 @@
|
||||||
set test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
|
set test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
|
||||||
automatic_status_update = #{record.automaticStatusUpdate,jdbcType=BIT},
|
automatic_status_update = #{record.automaticStatusUpdate,jdbcType=BIT},
|
||||||
repeat_case = #{record.repeatCase,jdbcType=BIT},
|
repeat_case = #{record.repeatCase,jdbcType=BIT},
|
||||||
pass_threshold = #{record.passThreshold,jdbcType=DECIMAL}
|
pass_threshold = #{record.passThreshold,jdbcType=DECIMAL},
|
||||||
|
case_run_mode = #{record.caseRunMode,jdbcType=VARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -183,6 +194,9 @@
|
||||||
<if test="passThreshold != null">
|
<if test="passThreshold != null">
|
||||||
pass_threshold = #{passThreshold,jdbcType=DECIMAL},
|
pass_threshold = #{passThreshold,jdbcType=DECIMAL},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="caseRunMode != null">
|
||||||
|
case_run_mode = #{caseRunMode,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
</set>
|
</set>
|
||||||
where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
|
where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
|
@ -190,16 +204,19 @@
|
||||||
update test_plan_config
|
update test_plan_config
|
||||||
set automatic_status_update = #{automaticStatusUpdate,jdbcType=BIT},
|
set automatic_status_update = #{automaticStatusUpdate,jdbcType=BIT},
|
||||||
repeat_case = #{repeatCase,jdbcType=BIT},
|
repeat_case = #{repeatCase,jdbcType=BIT},
|
||||||
pass_threshold = #{passThreshold,jdbcType=DECIMAL}
|
pass_threshold = #{passThreshold,jdbcType=DECIMAL},
|
||||||
|
case_run_mode = #{caseRunMode,jdbcType=VARCHAR}
|
||||||
where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
|
where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
<insert id="batchInsert" parameterType="map">
|
<insert id="batchInsert" parameterType="map">
|
||||||
insert into test_plan_config
|
insert into test_plan_config
|
||||||
(test_plan_id, automatic_status_update, repeat_case, pass_threshold)
|
(test_plan_id, automatic_status_update, repeat_case, pass_threshold, case_run_mode
|
||||||
|
)
|
||||||
values
|
values
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.testPlanId,jdbcType=VARCHAR}, #{item.automaticStatusUpdate,jdbcType=BIT},
|
(#{item.testPlanId,jdbcType=VARCHAR}, #{item.automaticStatusUpdate,jdbcType=BIT},
|
||||||
#{item.repeatCase,jdbcType=BIT}, #{item.passThreshold,jdbcType=DECIMAL})
|
#{item.repeatCase,jdbcType=BIT}, #{item.passThreshold,jdbcType=DECIMAL}, #{item.caseRunMode,jdbcType=VARCHAR}
|
||||||
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="batchInsertSelective" parameterType="map">
|
<insert id="batchInsertSelective" parameterType="map">
|
||||||
|
@ -224,6 +241,9 @@
|
||||||
<if test="'pass_threshold'.toString() == column.value">
|
<if test="'pass_threshold'.toString() == column.value">
|
||||||
#{item.passThreshold,jdbcType=DECIMAL}
|
#{item.passThreshold,jdbcType=DECIMAL}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="'case_run_mode'.toString() == column.value">
|
||||||
|
#{item.caseRunMode,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
</foreach>
|
</foreach>
|
||||||
)
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
|
|
|
@ -159,8 +159,12 @@ ALTER TABLE api_scenario_report DROP INDEX idx_test_plan_id;
|
||||||
CREATE INDEX idx_test_plan_scenario_id ON api_scenario_report(test_plan_scenario_id);
|
CREATE INDEX idx_test_plan_scenario_id ON api_scenario_report(test_plan_scenario_id);
|
||||||
ALTER TABLE api_scenario_report ADD COLUMN `plan` BIT(1) NOT NULL DEFAULT 0 COMMENT '是否是测试计划整体执行';
|
ALTER TABLE api_scenario_report ADD COLUMN `plan` BIT(1) NOT NULL DEFAULT 0 COMMENT '是否是测试计划整体执行';
|
||||||
CREATE INDEX idx_plan ON api_scenario_report(`plan`);
|
CREATE INDEX idx_plan ON api_scenario_report(`plan`);
|
||||||
|
|
||||||
|
-- 测试计划配置 增加运行模式
|
||||||
|
ALTER table test_plan_config
|
||||||
|
ADD COLUMN `case_run_mode` VARCHAR(50) NOT NULL DEFAULT 'PARALLEL' COMMENT '不同用例之间的执行方式(串行/并行)';
|
||||||
|
|
||||||
-- set innodb lock wait timeout to default
|
-- set innodb lock wait timeout to default
|
||||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,5 @@ public enum ApiExecuteRunMode {
|
||||||
/**
|
/**
|
||||||
* 定时任务
|
* 定时任务
|
||||||
*/
|
*/
|
||||||
SCENARIO
|
SCHEDULE
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
package io.metersphere.sdk.dto.queue;
|
package io.metersphere.sdk.dto.queue;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class TestPlanExecutionQueue {
|
public class TestPlanExecutionQueue {
|
||||||
private String queueId;
|
private String queueId;
|
||||||
|
private String parentQueueId;
|
||||||
private String testPlanId;
|
private String testPlanId;
|
||||||
|
//顺序
|
||||||
private long pos;
|
private long pos;
|
||||||
|
//执行模式
|
||||||
private String runMode;
|
private String runMode;
|
||||||
|
//执行来源
|
||||||
|
private String executionSource;
|
||||||
|
//预生成的报告ID (不一定会用到)
|
||||||
private String prepareReportId;
|
private String prepareReportId;
|
||||||
private String createUser;
|
private String createUser;
|
||||||
private long createTime;
|
private long createTime;
|
||||||
|
|
|
@ -101,6 +101,7 @@ log.test_plan.api_scenario=接口场景
|
||||||
test_plan.type.not_blank=测试计划类型不能为空
|
test_plan.type.not_blank=测试计划类型不能为空
|
||||||
test_plan.group.not_plan=当前测试计划组没有可归档计划
|
test_plan.group.not_plan=当前测试计划组没有可归档计划
|
||||||
test_plan.group.error=不是合法的测试计划组
|
test_plan.group.error=不是合法的测试计划组
|
||||||
|
test_plan.error=测试计划不合法
|
||||||
test_plan_group.batch.log={0}测试计划组
|
test_plan_group.batch.log={0}测试计划组
|
||||||
test_plan.batch.log={0}测试计划
|
test_plan.batch.log={0}测试计划
|
||||||
test_plan_report_not_exist=测试计划报告不存在
|
test_plan_report_not_exist=测试计划报告不存在
|
||||||
|
|
|
@ -103,6 +103,7 @@ log.test_plan.api_scenario=Api scenario
|
||||||
test_plan.type.not_blank=Test plan type cannot be empty
|
test_plan.type.not_blank=Test plan type cannot be empty
|
||||||
test_plan.group.not_plan=There are no archived plans in the current testing plan group
|
test_plan.group.not_plan=There are no archived plans in the current testing plan group
|
||||||
test_plan.group.error=Test plan group error
|
test_plan.group.error=Test plan group error
|
||||||
|
test_plan.error=Test plan error
|
||||||
test_plan_group.batch.log={0} test plan group
|
test_plan_group.batch.log={0} test plan group
|
||||||
test_plan.batch.log={0} plan
|
test_plan.batch.log={0} plan
|
||||||
test_plan_report_not_exist=The test plan report does not exist
|
test_plan_report_not_exist=The test plan report does not exist
|
||||||
|
|
|
@ -103,6 +103,7 @@ log.test_plan.api_scenario=接口场景
|
||||||
test_plan.type.not_blank=测试计划类型不能为空
|
test_plan.type.not_blank=测试计划类型不能为空
|
||||||
test_plan.group.not_plan=当前测试计划组没有可归档计划
|
test_plan.group.not_plan=当前测试计划组没有可归档计划
|
||||||
test_plan.group.error=不是合法的测试计划组
|
test_plan.group.error=不是合法的测试计划组
|
||||||
|
test_plan.error=测试计划不合法
|
||||||
test_plan_group.batch.log={0}测试计划组
|
test_plan_group.batch.log={0}测试计划组
|
||||||
test_plan.batch.log={0}测试计划
|
test_plan.batch.log={0}测试计划
|
||||||
test_plan_report_not_exist=测试计划报告不存在
|
test_plan_report_not_exist=测试计划报告不存在
|
||||||
|
|
|
@ -102,6 +102,7 @@ log.test_plan.api_scenario=接口場景
|
||||||
test_plan.type.not_blank=測試計劃類型不能為空
|
test_plan.type.not_blank=測試計劃類型不能為空
|
||||||
test_plan.group.not_plan=當前測試計劃組沒有可歸檔計劃
|
test_plan.group.not_plan=當前測試計劃組沒有可歸檔計劃
|
||||||
test_plan.group.error=不是合法的測試計劃組
|
test_plan.group.error=不是合法的測試計劃組
|
||||||
|
test_plan.error=測試計劃不合法
|
||||||
test_plan_group.batch.log={0}測試計劃組
|
test_plan_group.batch.log={0}測試計劃組
|
||||||
test_plan.batch.log={0}測試計劃
|
test_plan.batch.log={0}測試計劃
|
||||||
test_plan_report_not_exist=測試計劃報告不存在
|
test_plan_report_not_exist=測試計劃報告不存在
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class ApiScenarioScheduleJob extends BaseScheduleJob {
|
||||||
|
|
||||||
ApiResourceRunRequest runRequest = apiScenarioRunService.getApiResourceRunRequest(msScenario, tmpParam);
|
ApiResourceRunRequest runRequest = apiScenarioRunService.getApiResourceRunRequest(msScenario, tmpParam);
|
||||||
|
|
||||||
TaskRequestDTO taskRequest = apiScenarioRunService.getTaskRequest(IDGenerator.nextStr(), apiScenarioDetail.getId(), apiScenarioDetail.getProjectId(), ApiExecuteRunMode.SCENARIO.name());
|
TaskRequestDTO taskRequest = apiScenarioRunService.getTaskRequest(IDGenerator.nextStr(), apiScenarioDetail.getId(), apiScenarioDetail.getProjectId(), ApiExecuteRunMode.SCHEDULE.name());
|
||||||
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
TaskInfo taskInfo = taskRequest.getTaskInfo();
|
||||||
TaskItem taskItem = taskRequest.getTaskItem();
|
TaskItem taskItem = taskRequest.getTaskItem();
|
||||||
taskInfo.getRunModeConfig().setPoolId(apiRunModeConfigDTO.getPoolId());
|
taskInfo.getRunModeConfig().setPoolId(apiRunModeConfigDTO.getPoolId());
|
||||||
|
|
|
@ -835,7 +835,7 @@ public class ApiDefinitionModuleControllerTests extends BaseTest {
|
||||||
planConfig.setRepeatCase(false);
|
planConfig.setRepeatCase(false);
|
||||||
planConfig.setAutomaticStatusUpdate(false);
|
planConfig.setAutomaticStatusUpdate(false);
|
||||||
request.setTestPlanId("wx_123");
|
request.setTestPlanId("wx_123");
|
||||||
testPlanConfigMapper.insert(planConfig);
|
testPlanConfigMapper.insertSelective(planConfig);
|
||||||
this.requestPostWithOkAndReturn(URL_FILE_MODULE_COUNT, request);
|
this.requestPostWithOkAndReturn(URL_FILE_MODULE_COUNT, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -520,7 +520,7 @@ public class FunctionalCaseControllerTests extends BaseTest {
|
||||||
Assertions.assertTrue(moduleCount.containsKey("all"));
|
Assertions.assertTrue(moduleCount.containsKey("all"));
|
||||||
|
|
||||||
//不开启用例重复的测试计划入库,再次调用
|
//不开启用例重复的测试计划入库,再次调用
|
||||||
testPlanConfigMapper.insert(testPlanConfig);
|
testPlanConfigMapper.insertSelective(testPlanConfig);
|
||||||
|
|
||||||
mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_MODULE_COUNT, request);
|
mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_MODULE_COUNT, request);
|
||||||
returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
|
|
|
@ -113,14 +113,26 @@ public class ScheduleService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeIfExist(String resourceId, JobKey jobKey, TriggerKey triggerKey, Class clazz) {
|
public void updateIfExist(String resourceId, boolean enable, JobKey jobKey, TriggerKey triggerKey, Class clazz, String operator) {
|
||||||
ScheduleExample example = new ScheduleExample();
|
ScheduleExample example = new ScheduleExample();
|
||||||
example.createCriteria().andResourceIdEqualTo(resourceId).andJobEqualTo(clazz.getName());
|
example.createCriteria().andResourceIdEqualTo(resourceId).andJobEqualTo(clazz.getName());
|
||||||
Schedule updateSchedule = new Schedule();
|
List<Schedule> scheduleList = scheduleMapper.selectByExample(example);
|
||||||
updateSchedule.setEnable(false);
|
if (CollectionUtils.isNotEmpty(scheduleList)) {
|
||||||
scheduleMapper.updateByExampleSelective(updateSchedule, example);
|
Schedule schedule = scheduleList.getFirst();
|
||||||
|
if (!schedule.getEnable().equals(enable)) {
|
||||||
|
schedule.setEnable(enable);
|
||||||
|
schedule.setUpdateTime(System.currentTimeMillis());
|
||||||
|
scheduleMapper.updateByExampleSelective(schedule, example);
|
||||||
|
apiScheduleNoticeService.sendScheduleNotice(schedule, operator);
|
||||||
|
if (enable) {
|
||||||
|
scheduleManager.addCronJob(jobKey, triggerKey, clazz, schedule.getValue(),
|
||||||
|
scheduleManager.getDefaultJobDataMap(schedule, schedule.getValue(), schedule.getCreateUser()));
|
||||||
|
} else {
|
||||||
scheduleManager.removeJob(jobKey, triggerKey);
|
scheduleManager.removeJob(jobKey, triggerKey);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String scheduleConfig(ScheduleConfig scheduleConfig, JobKey jobKey, TriggerKey triggerKey, Class clazz, String operator) {
|
public String scheduleConfig(ScheduleConfig scheduleConfig, JobKey jobKey, TriggerKey triggerKey, Class clazz, String operator) {
|
||||||
Schedule schedule;
|
Schedule schedule;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.plan.controller;
|
package io.metersphere.plan.controller;
|
||||||
|
|
||||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||||
|
import io.metersphere.plan.dto.request.TestPlanBatchExecuteRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
|
import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
|
||||||
import io.metersphere.plan.service.TestPlanExecuteService;
|
import io.metersphere.plan.service.TestPlanExecuteService;
|
||||||
import io.metersphere.plan.service.TestPlanLogService;
|
import io.metersphere.plan.service.TestPlanLogService;
|
||||||
|
@ -33,13 +34,23 @@ public class TestPlanExecuteController {
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanExecuteService testPlanExecuteService;
|
private TestPlanExecuteService testPlanExecuteService;
|
||||||
|
|
||||||
@PostMapping("/start")
|
@PostMapping("/single")
|
||||||
@Operation(summary = "测试计划-开始自行")
|
@Operation(summary = "测试计划单独执行")
|
||||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
|
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#request.getExecuteId()", resourceType = "test_plan")
|
||||||
@Log(type = OperationLogType.EXECUTE, expression = "#msClass.batchEditLog(#request)", msClass = TestPlanLogService.class)
|
@Log(type = OperationLogType.EXECUTE, expression = "#msClass.executeLog(#request)", msClass = TestPlanLogService.class)
|
||||||
public void startExecute(@Validated @RequestBody TestPlanExecuteRequest request) {
|
public void startExecute(@Validated @RequestBody TestPlanExecuteRequest request) {
|
||||||
|
testPlanManagementService.checkModuleIsOpen(request.getExecuteId(), TestPlanResourceConfig.CONFIG_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
||||||
|
testPlanExecuteService.singleExecuteTestPlan(request, SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch")
|
||||||
|
@Operation(summary = "测试计划-开始自行")
|
||||||
|
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
|
||||||
|
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||||
|
@Log(type = OperationLogType.EXECUTE, expression = "#msClass.batchExecuteLog(#request)", msClass = TestPlanLogService.class)
|
||||||
|
public void startExecute(@Validated @RequestBody TestPlanBatchExecuteRequest request) {
|
||||||
testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
testPlanManagementService.checkModuleIsOpen(request.getProjectId(), TestPlanResourceConfig.CHECK_TYPE_PROJECT, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN));
|
||||||
testPlanExecuteService.execute(request, SessionUtils.getUserId());
|
testPlanExecuteService.batchExecuteTestPlan(request, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,9 @@ public class TestPlanBatchEditRequest extends TestPlanBatchProcessRequest {
|
||||||
@Schema(description = "标签")
|
@Schema(description = "标签")
|
||||||
private List<String> tags;
|
private List<String> tags;
|
||||||
|
|
||||||
|
@Schema(description = "定时任务是否开启")
|
||||||
|
private boolean scheduleOpen;
|
||||||
|
|
||||||
|
@Schema(description = "本次编辑的字段", allowableValues = {"TAGS", "SCHEDULE"})
|
||||||
|
private String editColumn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package io.metersphere.plan.dto.request;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||||
|
import io.metersphere.sdk.constants.ApiExecuteRunMode;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TestPlanBatchExecuteRequest {
|
||||||
|
|
||||||
|
@Schema(description = "项目ID")
|
||||||
|
@NotBlank(message = "project_is_not_exist")
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "执行ID")
|
||||||
|
@NotEmpty(message = "test_plan.not.exist")
|
||||||
|
private List<String> executeIds;
|
||||||
|
|
||||||
|
@Schema(description = "执行模式", allowableValues = {"SERIAL", "PARALLEL"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String runMode = ApiBatchRunMode.SERIAL.name();
|
||||||
|
|
||||||
|
@Schema(description = "执行来源", allowableValues = {"JENKINS", "SCENARIO", "RUN"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String executionSource = ApiExecuteRunMode.RUN.name();
|
||||||
|
|
||||||
|
}
|
|
@ -1,26 +1,22 @@
|
||||||
package io.metersphere.plan.dto.request;
|
package io.metersphere.plan.dto.request;
|
||||||
|
|
||||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||||
|
import io.metersphere.sdk.constants.ApiExecuteRunMode;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author wx
|
|
||||||
*/
|
|
||||||
@Data
|
@Data
|
||||||
public class TestPlanExecuteRequest {
|
public class TestPlanExecuteRequest {
|
||||||
|
|
||||||
@Schema(description = "项目ID", required = true)
|
|
||||||
@NotBlank(message = "{project.id.not_blank}")
|
|
||||||
private String projectId;
|
|
||||||
|
|
||||||
@Schema(description = "执行ID")
|
@Schema(description = "执行ID")
|
||||||
List<String> executeIds;
|
@NotBlank(message = "test_plan.not.exist")
|
||||||
|
private String executeId;
|
||||||
|
|
||||||
@Schema(description = "执行模式", allowableValues = {"SERIAL", "PARALLEL"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "执行模式", allowableValues = {"SERIAL", "PARALLEL"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String executeMode = ApiBatchRunMode.SERIAL.name();
|
private String runMode = ApiBatchRunMode.SERIAL.name();
|
||||||
|
|
||||||
|
@Schema(description = "执行来源", allowableValues = {"JENKINS", "SCENARIO", "RUN"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String executionSource = ApiExecuteRunMode.RUN.name();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@ import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class TestPlanResponse extends TestPlanStatisticsResponse {
|
public class TestPlanResponse extends TestPlanStatisticsResponse {
|
||||||
|
@Schema(description = "父Id")
|
||||||
|
private String parent;
|
||||||
|
|
||||||
@Schema(description = "项目ID")
|
@Schema(description = "项目ID")
|
||||||
private String projectId;
|
private String projectId;
|
||||||
@Schema(description = "测试计划编号")
|
@Schema(description = "测试计划编号")
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package io.metersphere.plan.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试计划执行队列类型
|
||||||
|
*/
|
||||||
|
public enum TestPlanExecuteQueueType {
|
||||||
|
TEST_PLAN, TEST_PLAN_GROUP, TEST_COLLECTION
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package io.metersphere.plan.job;
|
||||||
import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
|
import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
|
||||||
import io.metersphere.plan.service.TestPlanExecuteService;
|
import io.metersphere.plan.service.TestPlanExecuteService;
|
||||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||||
|
import io.metersphere.sdk.constants.ApiExecuteRunMode;
|
||||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.system.schedule.BaseScheduleJob;
|
import io.metersphere.system.schedule.BaseScheduleJob;
|
||||||
|
@ -10,7 +11,6 @@ import org.quartz.JobExecutionContext;
|
||||||
import org.quartz.JobKey;
|
import org.quartz.JobKey;
|
||||||
import org.quartz.TriggerKey;
|
import org.quartz.TriggerKey;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TestPlanScheduleJob extends BaseScheduleJob {
|
public class TestPlanScheduleJob extends BaseScheduleJob {
|
||||||
|
@ -21,9 +21,10 @@ public class TestPlanScheduleJob extends BaseScheduleJob {
|
||||||
assert testPlanExecuteService != null;
|
assert testPlanExecuteService != null;
|
||||||
Map<String, String> runConfig = JSON.parseObject(context.getJobDetail().getJobDataMap().get("config").toString(), Map.class);
|
Map<String, String> runConfig = JSON.parseObject(context.getJobDetail().getJobDataMap().get("config").toString(), Map.class);
|
||||||
String runMode = runConfig.containsKey("runMode") ? runConfig.get("runMode") : ApiBatchRunMode.SERIAL.name();
|
String runMode = runConfig.containsKey("runMode") ? runConfig.get("runMode") : ApiBatchRunMode.SERIAL.name();
|
||||||
testPlanExecuteService.execute(new TestPlanExecuteRequest() {{
|
testPlanExecuteService.singleExecuteTestPlan(new TestPlanExecuteRequest() {{
|
||||||
this.setExecuteIds(Collections.singletonList(resourceId));
|
this.setExecuteId(resourceId);
|
||||||
this.setExecuteMode(runMode);
|
this.setRunMode(runMode);
|
||||||
|
this.setExecutionSource(ApiExecuteRunMode.SCHEDULE.name());
|
||||||
}}, userId);
|
}}, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public interface ExtTestPlanApiScenarioMapper {
|
||||||
|
|
||||||
List<String> selectIdByTestPlanIdOrderByPos(String testPlanId);
|
List<String> selectIdByTestPlanIdOrderByPos(String testPlanId);
|
||||||
|
|
||||||
Long getMaxPosByTestPlanId(String testPlanId);
|
Long getMaxPosByRangeId(String testPlanId);
|
||||||
|
|
||||||
List<String> getIdByParam(ResourceSelectParam resourceSelectParam);
|
List<String> getIdByParam(ResourceSelectParam resourceSelectParam);
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
WHERE test_plan_id = #{testPlanId}
|
WHERE test_plan_id = #{testPlanId}
|
||||||
ORDER BY pos ASC
|
ORDER BY pos ASC
|
||||||
</select>
|
</select>
|
||||||
<select id="getMaxPosByTestPlanId" resultType="java.lang.Long">
|
<select id="getMaxPosByRangeId" resultType="java.lang.Long">
|
||||||
SELECT max(pos)
|
SELECT max(pos)
|
||||||
FROM test_plan_api_scenario
|
FROM test_plan_api_scenario
|
||||||
WHERE test_plan_id = #{0}
|
WHERE test_plan_collection_Id = #{0}
|
||||||
</select>
|
</select>
|
||||||
<select id="getIdByParam"
|
<select id="getIdByParam"
|
||||||
parameterType="io.metersphere.plan.dto.ResourceSelectParam"
|
parameterType="io.metersphere.plan.dto.ResourceSelectParam"
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
t.type,
|
t.type,
|
||||||
t.description,
|
t.description,
|
||||||
t.pos,
|
t.pos,
|
||||||
|
t.group_id AS parent,
|
||||||
t.tags
|
t.tags
|
||||||
FROM test_plan t
|
FROM test_plan t
|
||||||
INNER JOIN user createUser ON t.create_user = createUser.id
|
INNER JOIN user createUser ON t.create_user = createUser.id
|
||||||
|
|
|
@ -12,29 +12,31 @@ import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
|
||||||
import io.metersphere.functional.dto.ProjectOptionDTO;
|
import io.metersphere.functional.dto.ProjectOptionDTO;
|
||||||
import io.metersphere.plan.constants.AssociateCaseType;
|
import io.metersphere.plan.constants.AssociateCaseType;
|
||||||
import io.metersphere.plan.constants.TreeTypeEnums;
|
import io.metersphere.plan.constants.TreeTypeEnums;
|
||||||
import io.metersphere.plan.domain.TestPlanApiCase;
|
import io.metersphere.plan.domain.*;
|
||||||
import io.metersphere.plan.domain.TestPlanApiCaseExample;
|
|
||||||
import io.metersphere.plan.domain.TestPlanCollection;
|
|
||||||
import io.metersphere.plan.domain.TestPlanCollectionExample;
|
|
||||||
import io.metersphere.plan.dto.ApiCaseModuleDTO;
|
import io.metersphere.plan.dto.ApiCaseModuleDTO;
|
||||||
|
import io.metersphere.plan.dto.ResourceLogInsertModule;
|
||||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||||
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
||||||
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
||||||
import io.metersphere.plan.dto.request.*;
|
import io.metersphere.plan.dto.request.*;
|
||||||
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
|
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
|
||||||
import io.metersphere.plan.dto.response.TestPlanAssociationResponse;
|
import io.metersphere.plan.dto.response.TestPlanAssociationResponse;
|
||||||
|
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||||
import io.metersphere.plan.mapper.ExtTestPlanApiCaseMapper;
|
import io.metersphere.plan.mapper.ExtTestPlanApiCaseMapper;
|
||||||
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
|
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
|
||||||
import io.metersphere.plan.mapper.TestPlanCollectionMapper;
|
import io.metersphere.plan.mapper.TestPlanCollectionMapper;
|
||||||
|
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||||
import io.metersphere.project.domain.Project;
|
import io.metersphere.project.domain.Project;
|
||||||
import io.metersphere.project.domain.ProjectExample;
|
import io.metersphere.project.domain.ProjectExample;
|
||||||
import io.metersphere.project.dto.ModuleCountDTO;
|
import io.metersphere.project.dto.ModuleCountDTO;
|
||||||
|
import io.metersphere.project.dto.MoveNodeSortDTO;
|
||||||
import io.metersphere.project.mapper.ProjectMapper;
|
import io.metersphere.project.mapper.ProjectMapper;
|
||||||
import io.metersphere.sdk.constants.CaseType;
|
import io.metersphere.sdk.constants.CaseType;
|
||||||
import io.metersphere.sdk.constants.ModuleConstants;
|
import io.metersphere.sdk.constants.ModuleConstants;
|
||||||
import io.metersphere.sdk.constants.TestPlanResourceConstants;
|
import io.metersphere.sdk.constants.TestPlanResourceConstants;
|
||||||
import io.metersphere.sdk.domain.Environment;
|
import io.metersphere.sdk.domain.Environment;
|
||||||
import io.metersphere.sdk.domain.EnvironmentExample;
|
import io.metersphere.sdk.domain.EnvironmentExample;
|
||||||
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
import io.metersphere.sdk.util.Translator;
|
import io.metersphere.sdk.util.Translator;
|
||||||
|
@ -63,6 +65,9 @@ import java.util.stream.Collectors;
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class TestPlanApiCaseService extends TestPlanResourceService {
|
public class TestPlanApiCaseService extends TestPlanResourceService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TestPlanMapper testPlanMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -86,6 +91,8 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
||||||
private TestPlanCollectionMapper testPlanCollectionMapper;
|
private TestPlanCollectionMapper testPlanCollectionMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiTestCaseMapper apiTestCaseMapper;
|
private ApiTestCaseMapper apiTestCaseMapper;
|
||||||
|
@Resource
|
||||||
|
private TestPlanResourceLogService testPlanResourceLogService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
||||||
|
@ -106,8 +113,7 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePos(String id, long pos) {
|
public void updatePos(String id, long pos) {
|
||||||
// todo
|
extTestPlanApiCaseMapper.updatePos(id, pos);
|
||||||
// extTestPlanApiCaseMapper.updatePos(id, pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -142,15 +148,14 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshPos(String testPlanId) {
|
public void refreshPos(String testPlanId) {
|
||||||
// todo
|
List<String> caseIdList = extTestPlanApiCaseMapper.selectIdByTestPlanIdOrderByPos(testPlanId);
|
||||||
// List<String> caseIdList = extTestPlanApiCaseMapper.selectIdByTestPlanIdOrderByPos(testPlanId);
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
// SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
ExtTestPlanApiCaseMapper batchUpdateMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class);
|
||||||
// ExtTestPlanApiCaseMapper batchUpdateMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class);
|
for (int i = 0; i < caseIdList.size(); i++) {
|
||||||
// for (int i = 0; i < caseIdList.size(); i++) {
|
batchUpdateMapper.updatePos(caseIdList.get(i), i * DEFAULT_NODE_INTERVAL_POS);
|
||||||
// batchUpdateMapper.updatePos(caseIdList.get(i), i * DEFAULT_NODE_INTERVAL_POS);
|
}
|
||||||
// }
|
sqlSession.flushStatements();
|
||||||
// sqlSession.flushStatements();
|
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||||
// SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -541,4 +546,23 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
|
||||||
apiCaseExample.createCriteria().andTestPlanIdEqualTo(planId);
|
apiCaseExample.createCriteria().andTestPlanIdEqualTo(planId);
|
||||||
apiBatchMapper.updateByExampleSelective(record, apiCaseExample);
|
apiBatchMapper.updateByExampleSelective(record, apiCaseExample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TestPlanOperationResponse sortNode(ResourceSortRequest request, LogInsertModule logInsertModule) {
|
||||||
|
TestPlanApiCase dragNode = testPlanApiCaseMapper.selectByPrimaryKey(request.getMoveId());
|
||||||
|
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestCollectionId());
|
||||||
|
if (dragNode == null) {
|
||||||
|
throw new MSException(Translator.get("test_plan.drag.node.error"));
|
||||||
|
}
|
||||||
|
TestPlanOperationResponse response = new TestPlanOperationResponse();
|
||||||
|
MoveNodeSortDTO sortDTO = super.getNodeSortDTO(
|
||||||
|
request.getTestCollectionId(),
|
||||||
|
super.getNodeMoveRequest(request, true),
|
||||||
|
extTestPlanApiCaseMapper::selectDragInfoById,
|
||||||
|
extTestPlanApiCaseMapper::selectNodeByPosOperator
|
||||||
|
);
|
||||||
|
super.sort(sortDTO);
|
||||||
|
response.setOperationCount(1);
|
||||||
|
testPlanResourceLogService.saveSortLog(testPlan, request.getMoveId(), new ResourceLogInsertModule(TestPlanResourceConstants.RESOURCE_API_CASE, logInsertModule));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,26 @@ package io.metersphere.plan.service;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
|
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
|
||||||
import io.metersphere.api.service.scenario.ApiScenarioService;
|
import io.metersphere.api.service.scenario.ApiScenarioService;
|
||||||
import io.metersphere.plan.constants.AssociateCaseType;
|
import io.metersphere.plan.constants.AssociateCaseType;
|
||||||
|
import io.metersphere.plan.domain.TestPlan;
|
||||||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||||
import io.metersphere.plan.domain.TestPlanApiScenarioExample;
|
import io.metersphere.plan.domain.TestPlanApiScenarioExample;
|
||||||
|
import io.metersphere.plan.dto.ResourceLogInsertModule;
|
||||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||||
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
||||||
import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
|
import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
|
||||||
|
import io.metersphere.plan.dto.request.ResourceSortRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
||||||
import io.metersphere.plan.mapper.ExtTestPlanApiScenarioMapper;
|
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||||
import io.metersphere.plan.mapper.TestPlanApiScenarioMapper;
|
import io.metersphere.plan.mapper.*;
|
||||||
import io.metersphere.plan.mapper.TestPlanCollectionMapper;
|
import io.metersphere.project.dto.MoveNodeSortDTO;
|
||||||
import io.metersphere.sdk.constants.CaseType;
|
import io.metersphere.sdk.constants.CaseType;
|
||||||
|
import io.metersphere.sdk.constants.TestPlanResourceConstants;
|
||||||
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
|
import io.metersphere.sdk.util.Translator;
|
||||||
|
import io.metersphere.system.dto.LogInsertModule;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
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.apache.ibatis.session.ExecutorType;
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
|
@ -43,6 +49,10 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
||||||
private TestPlanCollectionMapper testPlanCollectionMapper;
|
private TestPlanCollectionMapper testPlanCollectionMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioService apiScenarioService;
|
private ApiScenarioService apiScenarioService;
|
||||||
|
@Resource
|
||||||
|
private TestPlanMapper testPlanMapper;
|
||||||
|
@Resource
|
||||||
|
private TestPlanResourceLogService testPlanResourceLogService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
|
||||||
|
@ -52,14 +62,18 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNextOrder(String projectId) {
|
public long getNextOrder(String collectionId) {
|
||||||
|
Long maxPos = extTestPlanApiScenarioMapper.getMaxPosByRangeId(collectionId);
|
||||||
|
if (maxPos == null) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
return maxPos + DEFAULT_NODE_INTERVAL_POS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePos(String id, long pos) {
|
public void updatePos(String id, long pos) {
|
||||||
// todo
|
extTestPlanApiScenarioMapper.updatePos(id, pos);
|
||||||
// extTestPlanApiScenarioMapper.updatePos(id, pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,15 +108,14 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshPos(String testPlanId) {
|
public void refreshPos(String testPlanId) {
|
||||||
// todo
|
List<String> caseIdList = extTestPlanApiScenarioMapper.selectIdByTestPlanIdOrderByPos(testPlanId);
|
||||||
// List<String> caseIdList = extTestPlanApiScenarioMapper.selectIdByTestPlanIdOrderByPos(testPlanId);
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
// SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
ExtTestPlanApiCaseMapper batchUpdateMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class);
|
||||||
// ExtTestPlanApiCaseMapper batchUpdateMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class);
|
for (int i = 0; i < caseIdList.size(); i++) {
|
||||||
// for (int i = 0; i < caseIdList.size(); i++) {
|
batchUpdateMapper.updatePos(caseIdList.get(i), i * DEFAULT_NODE_INTERVAL_POS);
|
||||||
// batchUpdateMapper.updatePos(caseIdList.get(i), i * DEFAULT_NODE_INTERVAL_POS);
|
}
|
||||||
// }
|
sqlSession.flushStatements();
|
||||||
// sqlSession.flushStatements();
|
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||||
// SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -136,4 +149,22 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
|
||||||
List<ApiScenarioDTO> scenarioPage = apiScenarioService.getScenarioPage(request, isRepeat, request.getTestPlanId());
|
List<ApiScenarioDTO> scenarioPage = apiScenarioService.getScenarioPage(request, isRepeat, request.getTestPlanId());
|
||||||
return scenarioPage;
|
return scenarioPage;
|
||||||
}
|
}
|
||||||
|
public TestPlanOperationResponse sortNode(ResourceSortRequest request, LogInsertModule logInsertModule) {
|
||||||
|
TestPlanApiScenario dragNode = testPlanApiScenarioMapper.selectByPrimaryKey(request.getMoveId());
|
||||||
|
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestCollectionId());
|
||||||
|
if (dragNode == null) {
|
||||||
|
throw new MSException(Translator.get("test_plan.drag.node.error"));
|
||||||
|
}
|
||||||
|
TestPlanOperationResponse response = new TestPlanOperationResponse();
|
||||||
|
MoveNodeSortDTO sortDTO = super.getNodeSortDTO(
|
||||||
|
request.getTestCollectionId(),
|
||||||
|
super.getNodeMoveRequest(request, true),
|
||||||
|
extTestPlanApiScenarioMapper::selectDragInfoById,
|
||||||
|
extTestPlanApiScenarioMapper::selectNodeByPosOperator
|
||||||
|
);
|
||||||
|
super.sort(sortDTO);
|
||||||
|
response.setOperationCount(1);
|
||||||
|
testPlanResourceLogService.saveSortLog(testPlan, request.getMoveId(), new ResourceLogInsertModule(TestPlanResourceConstants.RESOURCE_API_CASE, logInsertModule));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ public class TestPlanBatchOperationService extends TestPlanBaseUtilsService {
|
||||||
TestPlanConfig newTestPlanConfig = new TestPlanConfig();
|
TestPlanConfig newTestPlanConfig = new TestPlanConfig();
|
||||||
BeanUtils.copyBean(newTestPlanConfig, originalTestPlanConfig);
|
BeanUtils.copyBean(newTestPlanConfig, originalTestPlanConfig);
|
||||||
newTestPlanConfig.setTestPlanId(testPlan.getId());
|
newTestPlanConfig.setTestPlanId(testPlan.getId());
|
||||||
testPlanConfigMapper.insert(newTestPlanConfig);
|
testPlanConfigMapper.insertSelective(newTestPlanConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo 测试规划信息
|
//todo 测试规划信息
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package io.metersphere.plan.service;
|
package io.metersphere.plan.service;
|
||||||
|
|
||||||
import io.metersphere.plan.domain.TestPlan;
|
import io.metersphere.plan.domain.TestPlan;
|
||||||
|
import io.metersphere.plan.dto.request.TestPlanBatchExecuteRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
|
import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
|
||||||
|
import io.metersphere.plan.enums.TestPlanExecuteQueueType;
|
||||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||||
|
import io.metersphere.sdk.constants.TestPlanConstants;
|
||||||
import io.metersphere.sdk.dto.queue.TestPlanExecutionQueue;
|
import io.metersphere.sdk.dto.queue.TestPlanExecutionQueue;
|
||||||
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
@ -30,70 +34,137 @@ public class TestPlanExecuteService {
|
||||||
@Resource
|
@Resource
|
||||||
private RedisTemplate<String, String> redisTemplate;
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
public static final String TEST_PLAN_QUEUE_PREFIX = "queue:test-plan:";
|
public static final String QUEUE_PREFIX_TEST_PLAN = "test-plan-execute:";
|
||||||
|
public static final String QUEUE_PREFIX_TEST_PLAN_GROUP = "test-plan-group-execute:";
|
||||||
|
public static final String QUEUE_PREFIX_TEST_COLLECTION = "test-collection-execute:";
|
||||||
|
|
||||||
private TestPlanExecutionQueue genQueue(String testPlanId, String queueId, long pos, String userId, String executeMode) {
|
public void executeTestPlan(TestPlan testPlan, String executionSource, String userId) {
|
||||||
TestPlanExecutionQueue testPlanExecutionQueue = new TestPlanExecutionQueue();
|
//todo 查询执行配置,配置下一步的队列
|
||||||
testPlanExecutionQueue.setTestPlanId(testPlanId);
|
|
||||||
testPlanExecutionQueue.setQueueId(queueId);
|
|
||||||
testPlanExecutionQueue.setPos(pos);
|
|
||||||
testPlanExecutionQueue.setPrepareReportId(IDGenerator.nextStr());
|
|
||||||
testPlanExecutionQueue.setCreateUser(userId);
|
|
||||||
testPlanExecutionQueue.setCreateTime(System.currentTimeMillis());
|
|
||||||
testPlanExecutionQueue.setRunMode(executeMode);
|
|
||||||
return testPlanExecutionQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(TestPlanExecuteRequest request, String userId) {
|
|
||||||
|
|
||||||
List<String> rightfulIds = testPlanService.selectRightfulIds(request.getExecuteIds());
|
|
||||||
|
|
||||||
if (CollectionUtils.isNotEmpty(rightfulIds)) {
|
|
||||||
//遍历原始ID,只挑选符合条件的ID进行。防止顺序错乱。
|
|
||||||
String executeMode = request.getExecuteMode();
|
|
||||||
String queueId = IDGenerator.nextStr();
|
|
||||||
long pos = 1;
|
|
||||||
List<TestPlanExecutionQueue> testPlanExecutionQueues = new ArrayList<>();
|
|
||||||
for (String testPlanId : request.getExecuteIds()) {
|
|
||||||
List<TestPlan> childList = testPlanService.selectChildPlanByGroupId(testPlanId);
|
|
||||||
if (CollectionUtils.isNotEmpty(childList)) {
|
|
||||||
for (TestPlan child : childList) {
|
|
||||||
testPlanExecutionQueues.add(genQueue(child.getId(), queueId, pos++, userId, executeMode));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
testPlanExecutionQueues.add(genQueue(testPlanId, queueId, pos++, userId, executeMode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (StringUtils.equalsIgnoreCase(request.getExecuteMode(), ApiBatchRunMode.SERIAL.name())) {
|
|
||||||
//串行
|
|
||||||
testPlanExecutionQueues.forEach(testPlanExecutionQueue -> {
|
|
||||||
redisTemplate.opsForList().rightPush(TEST_PLAN_QUEUE_PREFIX + queueId, JSON.toJSONString(testPlanExecutionQueue));
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
executeByExecutionQueue(getNextDetail(queueId));
|
|
||||||
} catch (Exception ignore) {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//并行
|
|
||||||
testPlanExecutionQueues.forEach(testPlanExecutionQueue -> {
|
|
||||||
executeByExecutionQueue(testPlanExecutionQueue);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeByExecutionQueue(TestPlanExecutionQueue queue) {
|
|
||||||
Thread.startVirtualThread(() -> {
|
|
||||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(queue.getTestPlanId());
|
|
||||||
// todo 获取测试规划,通过测试规划执行方式确定用例的执行方式
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下一个节点
|
* 预执行执行测试计划
|
||||||
*/
|
*/
|
||||||
public TestPlanExecutionQueue getNextDetail(String queueId) throws Exception {
|
private void prepareExecuteTestPlan(TestPlan testPlan, String parentQueueId, String runMode, String executionSource, String userId) {
|
||||||
String queueKey = TEST_PLAN_QUEUE_PREFIX + queueId;
|
if (testPlan == null || StringUtils.equalsIgnoreCase(testPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) {
|
||||||
|
throw new MSException("test_plan.error");
|
||||||
|
}
|
||||||
|
if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||||
|
List<TestPlan> children = testPlanService.selectNotArchivedChildren(testPlan.getId());
|
||||||
|
|
||||||
|
long pos = 0;
|
||||||
|
List<TestPlanExecutionQueue> childrenQueue = new ArrayList<>();
|
||||||
|
for (TestPlan child : children) {
|
||||||
|
childrenQueue.add(
|
||||||
|
new TestPlanExecutionQueue(child.getGroupId(), parentQueueId, child.getId(), pos++, runMode, executionSource, IDGenerator.nextStr(), userId, System.currentTimeMillis())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.equalsIgnoreCase(runMode, ApiBatchRunMode.SERIAL.name())) {
|
||||||
|
//串行
|
||||||
|
childrenQueue.forEach(childQueue -> {
|
||||||
|
redisTemplate.opsForList().rightPush(QUEUE_PREFIX_TEST_PLAN_GROUP + testPlan.getId(), JSON.toJSONString(childrenQueue));
|
||||||
|
});
|
||||||
|
executeNextTestPlanByGroupQueueId(testPlan.getId(), parentQueueId);
|
||||||
|
} else {
|
||||||
|
//并行
|
||||||
|
childrenQueue.forEach(childQueue -> {
|
||||||
|
executeTestPlan(testPlanMapper.selectByPrimaryKey(childQueue.getTestPlanId()), childQueue.getExecutionSource(), childQueue.getCreateUser());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.executeTestPlan(testPlan, executionSource, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个执行测试计划
|
||||||
|
*/
|
||||||
|
public void singleExecuteTestPlan(TestPlanExecuteRequest request, String userId) {
|
||||||
|
prepareExecuteTestPlan(testPlanMapper.selectByPrimaryKey(request.getExecuteId()), null, request.getRunMode(), request.getExecutionSource(), userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量执行测试计划
|
||||||
|
*/
|
||||||
|
public void batchExecuteTestPlan(TestPlanBatchExecuteRequest request, String userId) {
|
||||||
|
List<String> rightfulIds = testPlanService.selectRightfulIds(request.getExecuteIds());
|
||||||
|
if (CollectionUtils.isNotEmpty(rightfulIds)) {
|
||||||
|
|
||||||
|
String runMode = request.getRunMode();
|
||||||
|
String queueId = IDGenerator.nextStr();
|
||||||
|
long pos = 0;
|
||||||
|
List<TestPlanExecutionQueue> testPlanExecutionQueues = new ArrayList<>();
|
||||||
|
|
||||||
|
//遍历原始ID,只挑选符合条件的ID进行。防止顺序错乱。
|
||||||
|
for (String testPlanId : request.getExecuteIds()) {
|
||||||
|
if (rightfulIds.contains(testPlanId)) {
|
||||||
|
testPlanExecutionQueues.add(
|
||||||
|
new TestPlanExecutionQueue(queueId, null, testPlanId, pos++, runMode, request.getExecutionSource(), IDGenerator.nextStr(), userId, System.currentTimeMillis())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.equalsIgnoreCase(request.getRunMode(), ApiBatchRunMode.SERIAL.name())) {
|
||||||
|
//串行
|
||||||
|
testPlanExecutionQueues.forEach(testPlanExecutionQueue -> {
|
||||||
|
redisTemplate.opsForList().rightPush(QUEUE_PREFIX_TEST_PLAN + queueId, JSON.toJSONString(testPlanExecutionQueue));
|
||||||
|
});
|
||||||
|
executeNextTestPlanByQueueId(queueId);
|
||||||
|
} else {
|
||||||
|
//并行
|
||||||
|
testPlanExecutionQueues.forEach(testPlanExecutionQueue -> {
|
||||||
|
prepareExecuteTestPlan(testPlanMapper.selectByPrimaryKey(testPlanExecutionQueue.getTestPlanId()),
|
||||||
|
null,
|
||||||
|
testPlanExecutionQueue.getRunMode(),
|
||||||
|
testPlanExecutionQueue.getExecutionSource(),
|
||||||
|
testPlanExecutionQueue.getCreateUser());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//执行下一个测试计划组节点的测试计划
|
||||||
|
private void executeNextTestPlanByGroupQueueId(String groupQueueId, String parentQueueId) {
|
||||||
|
TestPlanExecutionQueue nextQueue = getNextDetail(groupQueueId, QUEUE_PREFIX_TEST_PLAN_GROUP, TestPlanExecutionQueue.class);
|
||||||
|
if (nextQueue != null) {
|
||||||
|
try {
|
||||||
|
executeTestPlan(testPlanMapper.selectByPrimaryKey(nextQueue.getTestPlanId()), nextQueue.getExecutionSource(), nextQueue.getCreateUser());
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.executeNextTestPlanByQueueId(groupQueueId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// todo 测试计划组执行完成
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(parentQueueId)) {
|
||||||
|
// 如果测试计划组是在批量执行时处理的,继续进行批量执行队列里的下个节点
|
||||||
|
executeNextTestPlanByQueueId(parentQueueId);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//执行下一个批量执行节点的测试计划
|
||||||
|
private void executeNextTestPlanByQueueId(String queueId) {
|
||||||
|
TestPlanExecutionQueue nextQueue = getNextDetail(queueId, QUEUE_PREFIX_TEST_PLAN, TestPlanExecutionQueue.class);
|
||||||
|
if (nextQueue != null) {
|
||||||
|
try {
|
||||||
|
prepareExecuteTestPlan(
|
||||||
|
testPlanMapper.selectByPrimaryKey(nextQueue.getTestPlanId()),
|
||||||
|
queueId,
|
||||||
|
nextQueue.getRunMode(),
|
||||||
|
nextQueue.getExecutionSource(),
|
||||||
|
nextQueue.getCreateUser());
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.executeNextTestPlanByQueueId(queueId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取下一个队列节点
|
||||||
|
*/
|
||||||
|
private <T> T getNextDetail(String queueId, String queueType, Class<T> formatClass) {
|
||||||
|
String queueKey = this.genQueueKey(queueId, queueType);
|
||||||
ListOperations<String, String> listOps = redisTemplate.opsForList();
|
ListOperations<String, String> listOps = redisTemplate.opsForList();
|
||||||
String queueDetail = listOps.leftPop(queueKey);
|
String queueDetail = listOps.leftPop(queueKey);
|
||||||
if (StringUtils.isBlank(queueDetail)) {
|
if (StringUtils.isBlank(queueDetail)) {
|
||||||
|
@ -103,32 +174,46 @@ public class TestPlanExecuteService {
|
||||||
if (StringUtils.isNotBlank(queueDetail)) {
|
if (StringUtils.isNotBlank(queueDetail)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(queueDetail)) {
|
if (StringUtils.isNotBlank(queueDetail)) {
|
||||||
Long size = size(queueId);
|
Long size = getQueueSize(queueId);
|
||||||
if (size == null || size == 0) {
|
if (size == null || size == 0) {
|
||||||
// 最后一个节点清理队列
|
// 最后一个节点清理队列
|
||||||
deleteQueue(queueId);
|
deleteQueue(queueKey);
|
||||||
}
|
}
|
||||||
return JSON.parseObject(queueDetail, TestPlanExecutionQueue.class);
|
return JSON.parseObject(queueDetail, formatClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 整体获取完,清理队列
|
// 整体获取完,清理队列
|
||||||
deleteQueue(queueId);
|
deleteQueue(queueKey);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteQueue(String queueId) {
|
private void deleteQueue(String queueKey) {
|
||||||
redisTemplate.delete(TEST_PLAN_QUEUE_PREFIX + queueId);
|
redisTemplate.delete(queueKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long size(String queueId) {
|
private Long getQueueSize(String queueKey) {
|
||||||
ListOperations<String, String> listOps = redisTemplate.opsForList();
|
ListOperations<String, String> listOps = redisTemplate.opsForList();
|
||||||
String queueKey = TEST_PLAN_QUEUE_PREFIX + queueId;
|
|
||||||
return listOps.size(queueKey);
|
return listOps.size(queueKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//生成队列key
|
||||||
|
private String genQueueKey(String queueId, String queueType) {
|
||||||
|
String key = "";
|
||||||
|
if (StringUtils.equalsIgnoreCase(queueType, TestPlanExecuteQueueType.TEST_PLAN.name())) {
|
||||||
|
key = QUEUE_PREFIX_TEST_PLAN;
|
||||||
|
} else if (StringUtils.equalsIgnoreCase(queueType, TestPlanExecuteQueueType.TEST_PLAN_GROUP.name())) {
|
||||||
|
key = QUEUE_PREFIX_TEST_PLAN_GROUP;
|
||||||
|
} else if (StringUtils.equalsIgnoreCase(queueType, TestPlanExecuteQueueType.TEST_COLLECTION.name())) {
|
||||||
|
key = QUEUE_PREFIX_TEST_COLLECTION;
|
||||||
|
}
|
||||||
|
return key + queueId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
handleAssociateCase(createOrCopyRequest.getBaseAssociateCaseRequest(), operator, createTestPlan);
|
handleAssociateCase(createOrCopyRequest.getBaseAssociateCaseRequest(), operator, createTestPlan);
|
||||||
|
|
||||||
testPlanMapper.insert(createTestPlan);
|
testPlanMapper.insert(createTestPlan);
|
||||||
testPlanConfigMapper.insert(testPlanConfig);
|
testPlanConfigMapper.insertSelective(testPlanConfig);
|
||||||
return createTestPlan;
|
return createTestPlan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,10 +307,8 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
|
|
||||||
//删除测试计划报告 todo: 正式版增加接口用例报告、接口场景报告的清理
|
//删除测试计划报告 todo: 正式版增加接口用例报告、接口场景报告的清理
|
||||||
testPlanReportService.deleteByTestPlanIds(testPlanIds);
|
testPlanReportService.deleteByTestPlanIds(testPlanIds);
|
||||||
/*
|
//删除定时任务
|
||||||
todo
|
scheduleService.deleteByResourceIds(testPlanIds, TestPlanScheduleJob.class.getName());
|
||||||
删除计划定时任务
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -622,14 +620,27 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
* @param userId
|
* @param userId
|
||||||
*/
|
*/
|
||||||
public void batchEdit(TestPlanBatchEditRequest request, String userId) {
|
public void batchEdit(TestPlanBatchEditRequest request, String userId) {
|
||||||
|
|
||||||
// 目前计划的批量操作不支持全选所有页
|
// 目前计划的批量操作不支持全选所有页
|
||||||
List<String> ids = request.getSelectIds();
|
List<String> ids = request.getSelectIds();
|
||||||
if (CollectionUtils.isNotEmpty(ids)) {
|
if (CollectionUtils.isNotEmpty(ids)) {
|
||||||
|
if (StringUtils.equalsIgnoreCase(request.getEditColumn(), "SCHEDULE")) {
|
||||||
|
TestPlanExample example = new TestPlanExample();
|
||||||
|
example.createCriteria().andIdIn(ids).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||||
|
List<TestPlan> testPlanList = testPlanMapper.selectByExample(example);
|
||||||
|
//批量编辑定时任务
|
||||||
|
for (TestPlan testPlan : testPlanList) {
|
||||||
|
scheduleService.updateIfExist(testPlan.getId(), request.isScheduleOpen(), TestPlanScheduleJob.getJobKey(testPlan.getId()),
|
||||||
|
TestPlanScheduleJob.getTriggerKey(testPlan.getId()), TestPlanScheduleJob.class, userId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//默认编辑tags
|
||||||
User user = userMapper.selectByPrimaryKey(userId);
|
User user = userMapper.selectByPrimaryKey(userId);
|
||||||
handleTags(request, userId, ids);
|
handleTags(request, userId, ids);
|
||||||
testPlanSendNoticeService.batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
|
testPlanSendNoticeService.batchSendNotice(request.getProjectId(), ids, user, NoticeConstants.Event.UPDATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理标签
|
* 处理标签
|
||||||
|
@ -750,7 +761,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
testPlan.setStatus(testPlanFinalStatus);
|
testPlan.setStatus(testPlanFinalStatus);
|
||||||
testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||||
|
|
||||||
List<TestPlan> childPlan = this.selectChildPlanByGroupId(testPlanId);
|
List<TestPlan> childPlan = this.selectNotArchivedChildren(testPlanId);
|
||||||
if (CollectionUtils.isNotEmpty(childPlan)) {
|
if (CollectionUtils.isNotEmpty(childPlan)) {
|
||||||
TestPlan updateGroupPlan = new TestPlan();
|
TestPlan updateGroupPlan = new TestPlan();
|
||||||
updateGroupPlan.setId(testPlanId);
|
updateGroupPlan.setId(testPlanId);
|
||||||
|
@ -787,11 +798,11 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
|
|
||||||
if (request.isEnable() && StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
if (request.isEnable() && StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||||
//配置开启的测试计划组定时任务,要将组下的所有测试计划定时任务都关闭掉
|
//配置开启的测试计划组定时任务,要将组下的所有测试计划定时任务都关闭掉
|
||||||
List<TestPlan> children = this.selectChildPlanByGroupId(testPlan.getId());
|
List<TestPlan> children = this.selectNotArchivedChildren(testPlan.getId());
|
||||||
for (TestPlan child : children) {
|
for (TestPlan child : children) {
|
||||||
scheduleService.closeIfExist(child.getId(), TestPlanScheduleJob.getJobKey(testPlan.getId()),
|
scheduleService.updateIfExist(child.getId(), false, TestPlanScheduleJob.getJobKey(testPlan.getId()),
|
||||||
TestPlanScheduleJob.getTriggerKey(testPlan.getId()),
|
TestPlanScheduleJob.getTriggerKey(testPlan.getId()),
|
||||||
TestPlanScheduleJob.class);
|
TestPlanScheduleJob.class, operator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,7 +822,7 @@ public class TestPlanService extends TestPlanBaseUtilsService {
|
||||||
return extTestPlanMapper.selectNotArchivedIds(executeIds);
|
return extTestPlanMapper.selectNotArchivedIds(executeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TestPlan> selectChildPlanByGroupId(String testPlanGroupId) {
|
public List<TestPlan> selectNotArchivedChildren(String testPlanGroupId) {
|
||||||
TestPlanExample example = new TestPlanExample();
|
TestPlanExample example = new TestPlanExample();
|
||||||
example.createCriteria().andGroupIdEqualTo(testPlanGroupId).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
example.createCriteria().andGroupIdEqualTo(testPlanGroupId).andStatusNotEqualTo(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED);
|
||||||
example.setOrderByClause("pos asc");
|
example.setOrderByClause("pos asc");
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
<!-- typeHandler="io.metersphere.handler.ListTypeHandler"/>-->
|
<!-- typeHandler="io.metersphere.handler.ListTypeHandler"/>-->
|
||||||
<!-- </table>-->
|
<!-- </table>-->
|
||||||
|
|
||||||
<!-- <table tableName="test_plan_functional_case"/>-->
|
<table tableName="test_plan_config"/>
|
||||||
<!-- <table tableName="test_plan_api_case"/>-->
|
<!-- <table tableName="test_plan_api_case"/>-->
|
||||||
<!-- <table tableName="test_plan_api_scenario"/>-->
|
<!-- <table tableName="test_plan_api_scenario"/>-->
|
||||||
<!-- <table tableName="test_plan_report"/>-->
|
<!-- <table tableName="test_plan_report"/>-->
|
||||||
|
|
|
@ -119,7 +119,8 @@ public class TestPlanTests extends BaseTest {
|
||||||
private static final String URL_POST_TEST_PLAN_BATCH_DELETE = "/test-plan/batch-delete";
|
private static final String URL_POST_TEST_PLAN_BATCH_DELETE = "/test-plan/batch-delete";
|
||||||
private static final String URL_POST_TEST_PLAN_SCHEDULE = "/test-plan/schedule-config";
|
private static final String URL_POST_TEST_PLAN_SCHEDULE = "/test-plan/schedule-config";
|
||||||
private static final String URL_POST_TEST_PLAN_SCHEDULE_DELETE = "/test-plan/schedule-config-delete/%s";
|
private static final String URL_POST_TEST_PLAN_SCHEDULE_DELETE = "/test-plan/schedule-config-delete/%s";
|
||||||
private static final String URL_POST_TEST_PLAN_EXECUTE = "/test-plan-execute/start";
|
private static final String URL_POST_TEST_PLAN_SINGLE_EXECUTE = "/test-plan-execute/single";
|
||||||
|
private static final String URL_POST_TEST_PLAN_BATCH_EXECUTE = "/test-plan-execute/batch";
|
||||||
|
|
||||||
//测试计划资源-功能用例
|
//测试计划资源-功能用例
|
||||||
private static final String URL_POST_RESOURCE_CASE_ASSOCIATION = "/test-plan/association";
|
private static final String URL_POST_RESOURCE_CASE_ASSOCIATION = "/test-plan/association";
|
||||||
|
@ -1492,13 +1493,21 @@ public class TestPlanTests extends BaseTest {
|
||||||
@Order(71)
|
@Order(71)
|
||||||
public void executeTest() throws Exception {
|
public void executeTest() throws Exception {
|
||||||
TestPlanExecuteRequest executeRequest = new TestPlanExecuteRequest();
|
TestPlanExecuteRequest executeRequest = new TestPlanExecuteRequest();
|
||||||
executeRequest.setExecuteIds(Collections.singletonList(groupTestPlanId7));
|
executeRequest.setExecuteId(groupTestPlanId7);
|
||||||
executeRequest.setProjectId(project.getId());
|
|
||||||
//串行
|
//串行
|
||||||
this.requestPostWithOk(URL_POST_TEST_PLAN_EXECUTE, executeRequest);
|
this.requestPostWithOk(URL_POST_TEST_PLAN_SINGLE_EXECUTE, executeRequest);
|
||||||
//并行
|
//并行
|
||||||
executeRequest.setExecuteMode(ApiBatchRunMode.PARALLEL.name());
|
executeRequest.setRunMode(ApiBatchRunMode.PARALLEL.name());
|
||||||
this.requestPostWithOk(URL_POST_TEST_PLAN_EXECUTE, executeRequest);
|
this.requestPostWithOk(URL_POST_TEST_PLAN_SINGLE_EXECUTE, executeRequest);
|
||||||
|
|
||||||
|
TestPlanBatchExecuteRequest batchExecuteRequest = new TestPlanBatchExecuteRequest();
|
||||||
|
batchExecuteRequest.setExecuteIds(Collections.singletonList(groupTestPlanId7));
|
||||||
|
batchExecuteRequest.setProjectId(project.getId());
|
||||||
|
//串行
|
||||||
|
this.requestPostWithOk(URL_POST_TEST_PLAN_BATCH_EXECUTE, batchExecuteRequest);
|
||||||
|
//并行
|
||||||
|
batchExecuteRequest.setRunMode(ApiBatchRunMode.PARALLEL.name());
|
||||||
|
this.requestPostWithOk(URL_POST_TEST_PLAN_BATCH_EXECUTE, batchExecuteRequest);
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
@Order(81)
|
@Order(81)
|
||||||
|
|
|
@ -4,10 +4,10 @@ VALUES
|
||||||
('wxxx_2', 10000, 'wxx_1234', 'NONE', '1', 'eeew', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
('wxxx_2', 10000, 'wxx_1234', 'NONE', '1', 'eeew', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`)
|
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`,
|
||||||
VALUES
|
`case_run_mode`)
|
||||||
('wxxx_1', b'0', b'0', 100),
|
VALUES ('wxxx_1', b'0', b'0', 100, 'PARALLEL'),
|
||||||
('wxxx_2', b'0', b'0', 100);
|
('wxxx_2', b'0', b'0', 100, 'PARALLEL');
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `api_definition`(`id`, `name`, `protocol`, `method`, `path`, `status`, `num`, `tags`, `pos`, `project_id`, `module_id`, `latest`, `version_id`, `ref_id`, `description`, `create_time`, `create_user`, `update_time`, `update_user`, `delete_user`, `delete_time`, `deleted`)
|
INSERT INTO `api_definition`(`id`, `name`, `protocol`, `method`, `path`, `status`, `num`, `tags`, `pos`, `project_id`, `module_id`, `latest`, `version_id`, `ref_id`, `description`, `create_time`, `create_user`, `update_time`, `update_user`, `delete_user`, `delete_time`, `deleted`)
|
||||||
|
|
|
@ -4,10 +4,10 @@ VALUES
|
||||||
('wxx_2', 10000, 'wx_1234', 'NONE', '1', 'eeew', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
('wxx_2', 10000, 'wx_1234', 'NONE', '1', 'eeew', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`)
|
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`,
|
||||||
VALUES
|
'case_run_mode')
|
||||||
('wxx_1', b'0', b'0', 100),
|
VALUES ('wxx_1', b'0', b'0', 100, 'PARALLEL'),
|
||||||
('wxx_2', b'0', b'0', 100);
|
('wxx_2', b'0', b'0', 100, 'PARALLEL');
|
||||||
|
|
||||||
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`, `test_plan_collection_id`)
|
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`, `test_plan_collection_id`)
|
||||||
VALUES ('wxx_tpfc_1', 'wxx_1', 'wxx_test_1', 1714980158000, 'admin', NULL, NULL, NULL, 1, '123');
|
VALUES ('wxx_tpfc_1', 'wxx_1', 'wxx_test_1', 1714980158000, 'admin', NULL, NULL, NULL, 1, '123');
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`) VALUES
|
INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`) VALUES
|
||||||
('plan_id_for_gen_report', 100001, '100001100001', 'NONE', '1', 'gen-report-plan', 'PREPARED', 'TEST_PLAN', NULL, CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '11'),
|
('plan_id_for_gen_report', 100001, '100001100001', 'NONE', '1', 'gen-report-plan', 'PREPARED', 'TEST_PLAN', NULL, CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '11'),
|
||||||
('plan_id_for_gen_report_1', 100001, '100001100001', 'NONE', '1', 'gen-report-plan-1', 'PREPARED', 'TEST_PLAN', NULL, CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '11');
|
('plan_id_for_gen_report_1', 100001, '100001100001', 'NONE', '1', 'gen-report-plan-1', 'PREPARED', 'TEST_PLAN', NULL, CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '11');
|
||||||
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`) VALUES
|
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`,
|
||||||
('plan_id_for_gen_report', b'0', b'0', 100.00),
|
'case_run_mode')
|
||||||
('plan_id_for_gen_report_1', b'0', b'0', 0.00);
|
VALUES ('plan_id_for_gen_report', b'0', b'0', 100.00, 'PARALLEL'),
|
||||||
|
('plan_id_for_gen_report_1', b'0', b'0', 0.00, 'PARALLEL');
|
||||||
|
|
||||||
-- 计划关联用例执行的测试数据
|
-- 计划关联用例执行的测试数据
|
||||||
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`, `test_plan_collection_id`) VALUES
|
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`, `test_plan_collection_id`) VALUES
|
||||||
|
|
|
@ -43,11 +43,11 @@ INSERT INTO `test_plan_module`(`id`, `project_id`, `name`, `parent_id`, `pos`, `
|
||||||
VALUES ('1', 'songtianyang-fix-wx', 'wx_测试模块名称', 'ROOT', 1, 1714980158000, 1714980158000, 'admin', 'admin');
|
VALUES ('1', 'songtianyang-fix-wx', 'wx_测试模块名称', 'ROOT', 1, 1714980158000, 1714980158000, 'admin', 'admin');
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`)
|
INSERT INTO `test_plan_config`(`test_plan_id`, `automatic_status_update`, `repeat_case`, `pass_threshold`,
|
||||||
VALUES
|
'case_run_mode')
|
||||||
('wx_test_plan_id_1', b'0', b'0', 100),
|
VALUES ('wx_test_plan_id_1', b'0', b'0', 100, 'PARALLEL'),
|
||||||
('wx_test_plan_id_4', b'0', b'0', 100),
|
('wx_test_plan_id_4', b'0', b'0', 100, 'PARALLEL'),
|
||||||
('wx_test_plan_id_7', b'0', b'0', 100);
|
('wx_test_plan_id_7', b'0', b'0', 100, 'PARALLEL');
|
||||||
|
|
||||||
|
|
||||||
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)
|
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)
|
||||||
|
|
Loading…
Reference in New Issue