feat(测试计划): 补充生成报告功能

This commit is contained in:
song-cc-rock 2024-05-16 16:44:14 +08:00 committed by Craftsman
parent 0d60b03697
commit f0afd5241c
24 changed files with 780 additions and 346 deletions

View File

@ -1,12 +1,16 @@
package io.metersphere.plan.domain; package io.metersphere.plan.domain;
import io.metersphere.validation.groups.*; import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import lombok.Data;
@Data @Data
public class TestPlanConfig implements Serializable { public class TestPlanConfig implements Serializable {
@ -23,23 +27,22 @@ 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.test_planning.not_blank}", groups = {Created.class})
private Boolean testPlanning;
@Schema(title = "测试计划通过阈值; 0-100, 保留两位小数", 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.test_planning.not_blank}", groups = {Created.class})
@Size(min = 1, max = 1, message = "{test_plan_config.test_planning.length_range}", groups = {Created.class, Updated.class})
private Boolean testPlanning;
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", "DOUBLE", false), testPlanning("test_planning", "testPlanning", "BIT", false),
testPlanning("test_planning", "testPlanning", "BIT", false); passThreshold("pass_threshold", "passThreshold", "DECIMAL", false);
private static final String BEGINNING_DELIMITER = "`"; private static final String BEGINNING_DELIMITER = "`";

View File

@ -294,66 +294,6 @@ public class TestPlanConfigExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPassThresholdIsNull() {
addCriterion("pass_threshold is null");
return (Criteria) this;
}
public Criteria andPassThresholdIsNotNull() {
addCriterion("pass_threshold is not null");
return (Criteria) this;
}
public Criteria andPassThresholdEqualTo(Double value) {
addCriterion("pass_threshold =", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotEqualTo(Double value) {
addCriterion("pass_threshold <>", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThan(Double value) {
addCriterion("pass_threshold >", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThanOrEqualTo(Double value) {
addCriterion("pass_threshold >=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThan(Double value) {
addCriterion("pass_threshold <", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThanOrEqualTo(Double value) {
addCriterion("pass_threshold <=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdIn(List<Double> values) {
addCriterion("pass_threshold in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotIn(List<Double> values) {
addCriterion("pass_threshold not in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdBetween(Double value1, Double value2) {
addCriterion("pass_threshold between", value1, value2, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotBetween(Double value1, Double value2) {
addCriterion("pass_threshold not between", value1, value2, "passThreshold");
return (Criteria) this;
}
public Criteria andTestPlanningIsNull() { public Criteria andTestPlanningIsNull() {
addCriterion("test_planning is null"); addCriterion("test_planning is null");
return (Criteria) this; return (Criteria) this;
@ -413,6 +353,66 @@ public class TestPlanConfigExample {
addCriterion("test_planning not between", value1, value2, "testPlanning"); addCriterion("test_planning not between", value1, value2, "testPlanning");
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPassThresholdIsNull() {
addCriterion("pass_threshold is null");
return (Criteria) this;
}
public Criteria andPassThresholdIsNotNull() {
addCriterion("pass_threshold is not null");
return (Criteria) this;
}
public Criteria andPassThresholdEqualTo(Long value) {
addCriterion("pass_threshold =", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotEqualTo(Long value) {
addCriterion("pass_threshold <>", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThan(Long value) {
addCriterion("pass_threshold >", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThanOrEqualTo(Long value) {
addCriterion("pass_threshold >=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThan(Long value) {
addCriterion("pass_threshold <", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThanOrEqualTo(Long value) {
addCriterion("pass_threshold <=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdIn(List<Long> values) {
addCriterion("pass_threshold in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotIn(List<Long> values) {
addCriterion("pass_threshold not in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdBetween(Long value1, Long value2) {
addCriterion("pass_threshold between", value1, value2, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotBetween(Long value1, Long value2) {
addCriterion("pass_threshold not between", value1, value2, "passThreshold");
return (Criteria) this;
}
} }
public static class Criteria extends GeneratedCriteria { public static class Criteria extends GeneratedCriteria {

View File

@ -1,12 +1,16 @@
package io.metersphere.plan.domain; package io.metersphere.plan.domain;
import io.metersphere.validation.groups.*; import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import lombok.Data;
@Data @Data
public class TestPlanReport implements Serializable { public class TestPlanReport implements Serializable {
@ -31,30 +35,36 @@ public class TestPlanReport implements Serializable {
@Schema(description = "创建时间") @Schema(description = "创建时间")
private Long createTime; private Long createTime;
@Schema(description = "开始时间") @Schema(description = "执行时间;计划真正执行的时间")
private Long executeTime;
@Schema(description = "开始时间;计划开始执行的时间")
private Long startTime; private Long startTime;
@Schema(description = "结束时间") @Schema(description = "结束时间;计划执行结束的时间")
private Long endTime; private Long endTime;
@Schema(description = "触发类型") @Schema(description = "执行状态", requiredMode = Schema.RequiredMode.REQUIRED)
private String triggerMode;
@Schema(description = "执行状态: 未执行, 执行中, 已停止, 已完成;", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_report.exec_status.not_blank}", groups = {Created.class}) @NotBlank(message = "{test_plan_report.exec_status.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{test_plan_report.exec_status.length_range}", groups = {Created.class, Updated.class}) @Size(min = 1, max = 50, message = "{test_plan_report.exec_status.length_range}", groups = {Created.class, Updated.class})
private String execStatus; private String execStatus;
@Schema(description = "结果状态: 成功, 失败, 阻塞, 误报") @Schema(description = "结果状态", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_report.result_status.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{test_plan_report.result_status.length_range}", groups = {Created.class, Updated.class})
private String resultStatus; private String resultStatus;
@Schema(description = "通过阈值", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_report.pass_threshold.not_blank}", groups = {Created.class})
@Size(min = 1, max = 100, message = "{test_plan_report.pass_threshold.length_range}", groups = {Created.class, Updated.class})
private String passThreshold;
@Schema(description = "通过率") @Schema(description = "通过率")
private Long passRate; private Double passRate;
@Schema(description = "触发类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_report.trigger_mode.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{test_plan_report.trigger_mode.length_range}", groups = {Created.class, Updated.class})
private String triggerMode;
@Schema(description = "通过阈值", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{test_plan_report.pass_threshold.not_blank}", groups = {Created.class})
private Double passThreshold;
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan_report.project_id.not_blank}", groups = {Created.class}) @NotBlank(message = "{test_plan_report.project_id.not_blank}", groups = {Created.class})
@ -77,13 +87,14 @@ public class TestPlanReport implements Serializable {
name("name", "name", "VARCHAR", true), name("name", "name", "VARCHAR", true),
createUser("create_user", "createUser", "VARCHAR", false), createUser("create_user", "createUser", "VARCHAR", false),
createTime("create_time", "createTime", "BIGINT", false), createTime("create_time", "createTime", "BIGINT", false),
executeTime("execute_time", "executeTime", "BIGINT", false),
startTime("start_time", "startTime", "BIGINT", false), startTime("start_time", "startTime", "BIGINT", false),
endTime("end_time", "endTime", "BIGINT", false), endTime("end_time", "endTime", "BIGINT", false),
triggerMode("trigger_mode", "triggerMode", "VARCHAR", false),
execStatus("exec_status", "execStatus", "VARCHAR", false), execStatus("exec_status", "execStatus", "VARCHAR", false),
resultStatus("result_status", "resultStatus", "VARCHAR", false), resultStatus("result_status", "resultStatus", "VARCHAR", false),
passThreshold("pass_threshold", "passThreshold", "VARCHAR", false),
passRate("pass_rate", "passRate", "DECIMAL", false), passRate("pass_rate", "passRate", "DECIMAL", false),
triggerMode("trigger_mode", "triggerMode", "VARCHAR", false),
passThreshold("pass_threshold", "passThreshold", "DECIMAL", false),
projectId("project_id", "projectId", "VARCHAR", false), projectId("project_id", "projectId", "VARCHAR", false),
integrated("integrated", "integrated", "BIT", false), integrated("integrated", "integrated", "BIT", false),
deleted("deleted", "deleted", "BIT", false); deleted("deleted", "deleted", "BIT", false);

View File

@ -444,6 +444,66 @@ public class TestPlanReportExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andExecuteTimeIsNull() {
addCriterion("execute_time is null");
return (Criteria) this;
}
public Criteria andExecuteTimeIsNotNull() {
addCriterion("execute_time is not null");
return (Criteria) this;
}
public Criteria andExecuteTimeEqualTo(Long value) {
addCriterion("execute_time =", value, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeNotEqualTo(Long value) {
addCriterion("execute_time <>", value, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeGreaterThan(Long value) {
addCriterion("execute_time >", value, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeGreaterThanOrEqualTo(Long value) {
addCriterion("execute_time >=", value, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeLessThan(Long value) {
addCriterion("execute_time <", value, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeLessThanOrEqualTo(Long value) {
addCriterion("execute_time <=", value, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeIn(List<Long> values) {
addCriterion("execute_time in", values, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeNotIn(List<Long> values) {
addCriterion("execute_time not in", values, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeBetween(Long value1, Long value2) {
addCriterion("execute_time between", value1, value2, "executeTime");
return (Criteria) this;
}
public Criteria andExecuteTimeNotBetween(Long value1, Long value2) {
addCriterion("execute_time not between", value1, value2, "executeTime");
return (Criteria) this;
}
public Criteria andStartTimeIsNull() { public Criteria andStartTimeIsNull() {
addCriterion("start_time is null"); addCriterion("start_time is null");
return (Criteria) this; return (Criteria) this;
@ -564,76 +624,6 @@ public class TestPlanReportExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTriggerModeIsNull() {
addCriterion("trigger_mode is null");
return (Criteria) this;
}
public Criteria andTriggerModeIsNotNull() {
addCriterion("trigger_mode is not null");
return (Criteria) this;
}
public Criteria andTriggerModeEqualTo(String value) {
addCriterion("trigger_mode =", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotEqualTo(String value) {
addCriterion("trigger_mode <>", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeGreaterThan(String value) {
addCriterion("trigger_mode >", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeGreaterThanOrEqualTo(String value) {
addCriterion("trigger_mode >=", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeLessThan(String value) {
addCriterion("trigger_mode <", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeLessThanOrEqualTo(String value) {
addCriterion("trigger_mode <=", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeLike(String value) {
addCriterion("trigger_mode like", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotLike(String value) {
addCriterion("trigger_mode not like", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeIn(List<String> values) {
addCriterion("trigger_mode in", values, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotIn(List<String> values) {
addCriterion("trigger_mode not in", values, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeBetween(String value1, String value2) {
addCriterion("trigger_mode between", value1, value2, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotBetween(String value1, String value2) {
addCriterion("trigger_mode not between", value1, value2, "triggerMode");
return (Criteria) this;
}
public Criteria andExecStatusIsNull() { public Criteria andExecStatusIsNull() {
addCriterion("exec_status is null"); addCriterion("exec_status is null");
return (Criteria) this; return (Criteria) this;
@ -774,76 +764,6 @@ public class TestPlanReportExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andPassThresholdIsNull() {
addCriterion("pass_threshold is null");
return (Criteria) this;
}
public Criteria andPassThresholdIsNotNull() {
addCriterion("pass_threshold is not null");
return (Criteria) this;
}
public Criteria andPassThresholdEqualTo(String value) {
addCriterion("pass_threshold =", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotEqualTo(String value) {
addCriterion("pass_threshold <>", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThan(String value) {
addCriterion("pass_threshold >", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThanOrEqualTo(String value) {
addCriterion("pass_threshold >=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThan(String value) {
addCriterion("pass_threshold <", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThanOrEqualTo(String value) {
addCriterion("pass_threshold <=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLike(String value) {
addCriterion("pass_threshold like", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotLike(String value) {
addCriterion("pass_threshold not like", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdIn(List<String> values) {
addCriterion("pass_threshold in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotIn(List<String> values) {
addCriterion("pass_threshold not in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdBetween(String value1, String value2) {
addCriterion("pass_threshold between", value1, value2, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotBetween(String value1, String value2) {
addCriterion("pass_threshold not between", value1, value2, "passThreshold");
return (Criteria) this;
}
public Criteria andPassRateIsNull() { public Criteria andPassRateIsNull() {
addCriterion("pass_rate is null"); addCriterion("pass_rate is null");
return (Criteria) this; return (Criteria) this;
@ -904,6 +824,136 @@ public class TestPlanReportExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andTriggerModeIsNull() {
addCriterion("trigger_mode is null");
return (Criteria) this;
}
public Criteria andTriggerModeIsNotNull() {
addCriterion("trigger_mode is not null");
return (Criteria) this;
}
public Criteria andTriggerModeEqualTo(String value) {
addCriterion("trigger_mode =", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotEqualTo(String value) {
addCriterion("trigger_mode <>", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeGreaterThan(String value) {
addCriterion("trigger_mode >", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeGreaterThanOrEqualTo(String value) {
addCriterion("trigger_mode >=", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeLessThan(String value) {
addCriterion("trigger_mode <", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeLessThanOrEqualTo(String value) {
addCriterion("trigger_mode <=", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeLike(String value) {
addCriterion("trigger_mode like", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotLike(String value) {
addCriterion("trigger_mode not like", value, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeIn(List<String> values) {
addCriterion("trigger_mode in", values, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotIn(List<String> values) {
addCriterion("trigger_mode not in", values, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeBetween(String value1, String value2) {
addCriterion("trigger_mode between", value1, value2, "triggerMode");
return (Criteria) this;
}
public Criteria andTriggerModeNotBetween(String value1, String value2) {
addCriterion("trigger_mode not between", value1, value2, "triggerMode");
return (Criteria) this;
}
public Criteria andPassThresholdIsNull() {
addCriterion("pass_threshold is null");
return (Criteria) this;
}
public Criteria andPassThresholdIsNotNull() {
addCriterion("pass_threshold is not null");
return (Criteria) this;
}
public Criteria andPassThresholdEqualTo(Long value) {
addCriterion("pass_threshold =", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotEqualTo(Long value) {
addCriterion("pass_threshold <>", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThan(Long value) {
addCriterion("pass_threshold >", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdGreaterThanOrEqualTo(Long value) {
addCriterion("pass_threshold >=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThan(Long value) {
addCriterion("pass_threshold <", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdLessThanOrEqualTo(Long value) {
addCriterion("pass_threshold <=", value, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdIn(List<Long> values) {
addCriterion("pass_threshold in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotIn(List<Long> values) {
addCriterion("pass_threshold not in", values, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdBetween(Long value1, Long value2) {
addCriterion("pass_threshold between", value1, value2, "passThreshold");
return (Criteria) this;
}
public Criteria andPassThresholdNotBetween(Long value1, Long value2) {
addCriterion("pass_threshold not between", value1, value2, "passThreshold");
return (Criteria) this;
}
public Criteria andProjectIdIsNull() { public Criteria andProjectIdIsNull() {
addCriterion("project_id is null"); addCriterion("project_id is null");
return (Criteria) this; return (Criteria) this;

View File

@ -5,8 +5,8 @@
<id column="test_plan_id" jdbcType="VARCHAR" property="testPlanId" /> <id column="test_plan_id" jdbcType="VARCHAR" property="testPlanId" />
<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="DOUBLE" property="passThreshold" />
<result column="test_planning" jdbcType="BIT" property="testPlanning" /> <result column="test_planning" jdbcType="BIT" property="testPlanning" />
<result column="pass_threshold" jdbcType="DECIMAL" property="passThreshold" />
</resultMap> </resultMap>
<sql id="Example_Where_Clause"> <sql id="Example_Where_Clause">
<where> <where>
@ -67,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_planning test_plan_id, automatic_status_update, repeat_case, test_planning, pass_threshold
</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
@ -101,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, test_planning) test_planning, pass_threshold)
values (#{testPlanId,jdbcType=VARCHAR}, #{automaticStatusUpdate,jdbcType=BIT}, #{repeatCase,jdbcType=BIT}, values (#{testPlanId,jdbcType=VARCHAR}, #{automaticStatusUpdate,jdbcType=BIT}, #{repeatCase,jdbcType=BIT},
#{passThreshold,jdbcType=DOUBLE}, #{testPlanning,jdbcType=BIT}) #{testPlanning,jdbcType=BIT}, #{passThreshold,jdbcType=DECIMAL})
</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
@ -117,12 +117,12 @@
<if test="repeatCase != null"> <if test="repeatCase != null">
repeat_case, repeat_case,
</if> </if>
<if test="passThreshold != null">
pass_threshold,
</if>
<if test="testPlanning != null"> <if test="testPlanning != null">
test_planning, test_planning,
</if> </if>
<if test="passThreshold != null">
pass_threshold,
</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="testPlanId != null"> <if test="testPlanId != null">
@ -134,12 +134,12 @@
<if test="repeatCase != null"> <if test="repeatCase != null">
#{repeatCase,jdbcType=BIT}, #{repeatCase,jdbcType=BIT},
</if> </if>
<if test="passThreshold != null">
#{passThreshold,jdbcType=DOUBLE},
</if>
<if test="testPlanning != null"> <if test="testPlanning != null">
#{testPlanning,jdbcType=BIT}, #{testPlanning,jdbcType=BIT},
</if> </if>
<if test="passThreshold != null">
#{passThreshold,jdbcType=DECIMAL},
</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">
@ -160,12 +160,12 @@
<if test="record.repeatCase != null"> <if test="record.repeatCase != null">
repeat_case = #{record.repeatCase,jdbcType=BIT}, repeat_case = #{record.repeatCase,jdbcType=BIT},
</if> </if>
<if test="record.passThreshold != null">
pass_threshold = #{record.passThreshold,jdbcType=DOUBLE},
</if>
<if test="record.testPlanning != null"> <if test="record.testPlanning != null">
test_planning = #{record.testPlanning,jdbcType=BIT}, test_planning = #{record.testPlanning,jdbcType=BIT},
</if> </if>
<if test="record.passThreshold != null">
pass_threshold = #{record.passThreshold,jdbcType=DECIMAL},
</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" />
@ -176,8 +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=DOUBLE}, test_planning = #{record.testPlanning,jdbcType=BIT},
test_planning = #{record.testPlanning,jdbcType=BIT} pass_threshold = #{record.passThreshold,jdbcType=DECIMAL}
<if test="_parameter != null"> <if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" /> <include refid="Update_By_Example_Where_Clause" />
</if> </if>
@ -191,12 +191,12 @@
<if test="repeatCase != null"> <if test="repeatCase != null">
repeat_case = #{repeatCase,jdbcType=BIT}, repeat_case = #{repeatCase,jdbcType=BIT},
</if> </if>
<if test="passThreshold != null">
pass_threshold = #{passThreshold,jdbcType=DOUBLE},
</if>
<if test="testPlanning != null"> <if test="testPlanning != null">
test_planning = #{testPlanning,jdbcType=BIT}, test_planning = #{testPlanning,jdbcType=BIT},
</if> </if>
<if test="passThreshold != null">
pass_threshold = #{passThreshold,jdbcType=DECIMAL},
</if>
</set> </set>
where test_plan_id = #{testPlanId,jdbcType=VARCHAR} where test_plan_id = #{testPlanId,jdbcType=VARCHAR}
</update> </update>
@ -204,18 +204,18 @@
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=DOUBLE}, test_planning = #{testPlanning,jdbcType=BIT},
test_planning = #{testPlanning,jdbcType=BIT} pass_threshold = #{passThreshold,jdbcType=DECIMAL}
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_planning (test_plan_id, automatic_status_update, repeat_case, test_planning, pass_threshold
) )
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=DOUBLE}, #{item.testPlanning,jdbcType=BIT} #{item.repeatCase,jdbcType=BIT}, #{item.testPlanning,jdbcType=BIT}, #{item.passThreshold,jdbcType=DECIMAL}
) )
</foreach> </foreach>
</insert> </insert>
@ -238,12 +238,12 @@
<if test="'repeat_case'.toString() == column.value"> <if test="'repeat_case'.toString() == column.value">
#{item.repeatCase,jdbcType=BIT} #{item.repeatCase,jdbcType=BIT}
</if> </if>
<if test="'pass_threshold'.toString() == column.value">
#{item.passThreshold,jdbcType=DOUBLE}
</if>
<if test="'test_planning'.toString() == column.value"> <if test="'test_planning'.toString() == column.value">
#{item.testPlanning,jdbcType=BIT} #{item.testPlanning,jdbcType=BIT}
</if> </if>
<if test="'pass_threshold'.toString() == column.value">
#{item.passThreshold,jdbcType=DECIMAL}
</if>
</foreach> </foreach>
) )
</foreach> </foreach>

View File

@ -7,13 +7,14 @@
<result column="name" jdbcType="VARCHAR" property="name" /> <result column="name" jdbcType="VARCHAR" property="name" />
<result column="create_user" jdbcType="VARCHAR" property="createUser" /> <result column="create_user" jdbcType="VARCHAR" property="createUser" />
<result column="create_time" jdbcType="BIGINT" property="createTime" /> <result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="execute_time" jdbcType="BIGINT" property="executeTime" />
<result column="start_time" jdbcType="BIGINT" property="startTime" /> <result column="start_time" jdbcType="BIGINT" property="startTime" />
<result column="end_time" jdbcType="BIGINT" property="endTime" /> <result column="end_time" jdbcType="BIGINT" property="endTime" />
<result column="trigger_mode" jdbcType="VARCHAR" property="triggerMode" />
<result column="exec_status" jdbcType="VARCHAR" property="execStatus" /> <result column="exec_status" jdbcType="VARCHAR" property="execStatus" />
<result column="result_status" jdbcType="VARCHAR" property="resultStatus" /> <result column="result_status" jdbcType="VARCHAR" property="resultStatus" />
<result column="pass_threshold" jdbcType="VARCHAR" property="passThreshold" />
<result column="pass_rate" jdbcType="DECIMAL" property="passRate" /> <result column="pass_rate" jdbcType="DECIMAL" property="passRate" />
<result column="trigger_mode" jdbcType="VARCHAR" property="triggerMode" />
<result column="pass_threshold" jdbcType="DECIMAL" property="passThreshold" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" /> <result column="project_id" jdbcType="VARCHAR" property="projectId" />
<result column="integrated" jdbcType="BIT" property="integrated" /> <result column="integrated" jdbcType="BIT" property="integrated" />
<result column="deleted" jdbcType="BIT" property="deleted" /> <result column="deleted" jdbcType="BIT" property="deleted" />
@ -77,8 +78,9 @@
</where> </where>
</sql> </sql>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, test_plan_id, `name`, create_user, create_time, start_time, end_time, trigger_mode, id, test_plan_id, `name`, create_user, create_time, execute_time, start_time, end_time,
exec_status, result_status, pass_threshold, pass_rate, project_id, integrated, deleted exec_status, result_status, pass_rate, trigger_mode, pass_threshold, project_id,
integrated, deleted
</sql> </sql>
<select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanReportExample" resultMap="BaseResultMap"> <select id="selectByExample" parameterType="io.metersphere.plan.domain.TestPlanReportExample" resultMap="BaseResultMap">
select select
@ -112,17 +114,17 @@
</delete> </delete>
<insert id="insert" parameterType="io.metersphere.plan.domain.TestPlanReport"> <insert id="insert" parameterType="io.metersphere.plan.domain.TestPlanReport">
insert into test_plan_report (id, test_plan_id, `name`, insert into test_plan_report (id, test_plan_id, `name`,
create_user, create_time, start_time, create_user, create_time, execute_time,
end_time, trigger_mode, exec_status, start_time, end_time, exec_status,
result_status, pass_threshold, pass_rate, result_status, pass_rate, trigger_mode,
project_id, integrated, deleted pass_threshold, project_id, integrated,
) deleted)
values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{createUser,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{startTime,jdbcType=BIGINT}, #{createUser,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{executeTime,jdbcType=BIGINT},
#{endTime,jdbcType=BIGINT}, #{triggerMode,jdbcType=VARCHAR}, #{execStatus,jdbcType=VARCHAR}, #{startTime,jdbcType=BIGINT}, #{endTime,jdbcType=BIGINT}, #{execStatus,jdbcType=VARCHAR},
#{resultStatus,jdbcType=VARCHAR}, #{passThreshold,jdbcType=VARCHAR}, #{passRate,jdbcType=DECIMAL}, #{resultStatus,jdbcType=VARCHAR}, #{passRate,jdbcType=DECIMAL}, #{triggerMode,jdbcType=VARCHAR},
#{projectId,jdbcType=VARCHAR}, #{integrated,jdbcType=BIT}, #{deleted,jdbcType=BIT} #{passThreshold,jdbcType=DECIMAL}, #{projectId,jdbcType=VARCHAR}, #{integrated,jdbcType=BIT},
) #{deleted,jdbcType=BIT})
</insert> </insert>
<insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanReport"> <insert id="insertSelective" parameterType="io.metersphere.plan.domain.TestPlanReport">
insert into test_plan_report insert into test_plan_report
@ -142,27 +144,30 @@
<if test="createTime != null"> <if test="createTime != null">
create_time, create_time,
</if> </if>
<if test="executeTime != null">
execute_time,
</if>
<if test="startTime != null"> <if test="startTime != null">
start_time, start_time,
</if> </if>
<if test="endTime != null"> <if test="endTime != null">
end_time, end_time,
</if> </if>
<if test="triggerMode != null">
trigger_mode,
</if>
<if test="execStatus != null"> <if test="execStatus != null">
exec_status, exec_status,
</if> </if>
<if test="resultStatus != null"> <if test="resultStatus != null">
result_status, result_status,
</if> </if>
<if test="passThreshold != null">
pass_threshold,
</if>
<if test="passRate != null"> <if test="passRate != null">
pass_rate, pass_rate,
</if> </if>
<if test="triggerMode != null">
trigger_mode,
</if>
<if test="passThreshold != null">
pass_threshold,
</if>
<if test="projectId != null"> <if test="projectId != null">
project_id, project_id,
</if> </if>
@ -189,27 +194,30 @@
<if test="createTime != null"> <if test="createTime != null">
#{createTime,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT},
</if> </if>
<if test="executeTime != null">
#{executeTime,jdbcType=BIGINT},
</if>
<if test="startTime != null"> <if test="startTime != null">
#{startTime,jdbcType=BIGINT}, #{startTime,jdbcType=BIGINT},
</if> </if>
<if test="endTime != null"> <if test="endTime != null">
#{endTime,jdbcType=BIGINT}, #{endTime,jdbcType=BIGINT},
</if> </if>
<if test="triggerMode != null">
#{triggerMode,jdbcType=VARCHAR},
</if>
<if test="execStatus != null"> <if test="execStatus != null">
#{execStatus,jdbcType=VARCHAR}, #{execStatus,jdbcType=VARCHAR},
</if> </if>
<if test="resultStatus != null"> <if test="resultStatus != null">
#{resultStatus,jdbcType=VARCHAR}, #{resultStatus,jdbcType=VARCHAR},
</if> </if>
<if test="passThreshold != null">
#{passThreshold,jdbcType=VARCHAR},
</if>
<if test="passRate != null"> <if test="passRate != null">
#{passRate,jdbcType=DECIMAL}, #{passRate,jdbcType=DECIMAL},
</if> </if>
<if test="triggerMode != null">
#{triggerMode,jdbcType=VARCHAR},
</if>
<if test="passThreshold != null">
#{passThreshold,jdbcType=DECIMAL},
</if>
<if test="projectId != null"> <if test="projectId != null">
#{projectId,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
</if> </if>
@ -245,27 +253,30 @@
<if test="record.createTime != null"> <if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT}, create_time = #{record.createTime,jdbcType=BIGINT},
</if> </if>
<if test="record.executeTime != null">
execute_time = #{record.executeTime,jdbcType=BIGINT},
</if>
<if test="record.startTime != null"> <if test="record.startTime != null">
start_time = #{record.startTime,jdbcType=BIGINT}, start_time = #{record.startTime,jdbcType=BIGINT},
</if> </if>
<if test="record.endTime != null"> <if test="record.endTime != null">
end_time = #{record.endTime,jdbcType=BIGINT}, end_time = #{record.endTime,jdbcType=BIGINT},
</if> </if>
<if test="record.triggerMode != null">
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
</if>
<if test="record.execStatus != null"> <if test="record.execStatus != null">
exec_status = #{record.execStatus,jdbcType=VARCHAR}, exec_status = #{record.execStatus,jdbcType=VARCHAR},
</if> </if>
<if test="record.resultStatus != null"> <if test="record.resultStatus != null">
result_status = #{record.resultStatus,jdbcType=VARCHAR}, result_status = #{record.resultStatus,jdbcType=VARCHAR},
</if> </if>
<if test="record.passThreshold != null">
pass_threshold = #{record.passThreshold,jdbcType=VARCHAR},
</if>
<if test="record.passRate != null"> <if test="record.passRate != null">
pass_rate = #{record.passRate,jdbcType=DECIMAL}, pass_rate = #{record.passRate,jdbcType=DECIMAL},
</if> </if>
<if test="record.triggerMode != null">
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
</if>
<if test="record.passThreshold != null">
pass_threshold = #{record.passThreshold,jdbcType=DECIMAL},
</if>
<if test="record.projectId != null"> <if test="record.projectId != null">
project_id = #{record.projectId,jdbcType=VARCHAR}, project_id = #{record.projectId,jdbcType=VARCHAR},
</if> </if>
@ -287,13 +298,14 @@
`name` = #{record.name,jdbcType=VARCHAR}, `name` = #{record.name,jdbcType=VARCHAR},
create_user = #{record.createUser,jdbcType=VARCHAR}, create_user = #{record.createUser,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT}, create_time = #{record.createTime,jdbcType=BIGINT},
execute_time = #{record.executeTime,jdbcType=BIGINT},
start_time = #{record.startTime,jdbcType=BIGINT}, start_time = #{record.startTime,jdbcType=BIGINT},
end_time = #{record.endTime,jdbcType=BIGINT}, end_time = #{record.endTime,jdbcType=BIGINT},
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
exec_status = #{record.execStatus,jdbcType=VARCHAR}, exec_status = #{record.execStatus,jdbcType=VARCHAR},
result_status = #{record.resultStatus,jdbcType=VARCHAR}, result_status = #{record.resultStatus,jdbcType=VARCHAR},
pass_threshold = #{record.passThreshold,jdbcType=VARCHAR},
pass_rate = #{record.passRate,jdbcType=DECIMAL}, pass_rate = #{record.passRate,jdbcType=DECIMAL},
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
pass_threshold = #{record.passThreshold,jdbcType=DECIMAL},
project_id = #{record.projectId,jdbcType=VARCHAR}, project_id = #{record.projectId,jdbcType=VARCHAR},
integrated = #{record.integrated,jdbcType=BIT}, integrated = #{record.integrated,jdbcType=BIT},
deleted = #{record.deleted,jdbcType=BIT} deleted = #{record.deleted,jdbcType=BIT}
@ -316,27 +328,30 @@
<if test="createTime != null"> <if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT},
</if> </if>
<if test="executeTime != null">
execute_time = #{executeTime,jdbcType=BIGINT},
</if>
<if test="startTime != null"> <if test="startTime != null">
start_time = #{startTime,jdbcType=BIGINT}, start_time = #{startTime,jdbcType=BIGINT},
</if> </if>
<if test="endTime != null"> <if test="endTime != null">
end_time = #{endTime,jdbcType=BIGINT}, end_time = #{endTime,jdbcType=BIGINT},
</if> </if>
<if test="triggerMode != null">
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
</if>
<if test="execStatus != null"> <if test="execStatus != null">
exec_status = #{execStatus,jdbcType=VARCHAR}, exec_status = #{execStatus,jdbcType=VARCHAR},
</if> </if>
<if test="resultStatus != null"> <if test="resultStatus != null">
result_status = #{resultStatus,jdbcType=VARCHAR}, result_status = #{resultStatus,jdbcType=VARCHAR},
</if> </if>
<if test="passThreshold != null">
pass_threshold = #{passThreshold,jdbcType=VARCHAR},
</if>
<if test="passRate != null"> <if test="passRate != null">
pass_rate = #{passRate,jdbcType=DECIMAL}, pass_rate = #{passRate,jdbcType=DECIMAL},
</if> </if>
<if test="triggerMode != null">
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
</if>
<if test="passThreshold != null">
pass_threshold = #{passThreshold,jdbcType=DECIMAL},
</if>
<if test="projectId != null"> <if test="projectId != null">
project_id = #{projectId,jdbcType=VARCHAR}, project_id = #{projectId,jdbcType=VARCHAR},
</if> </if>
@ -355,13 +370,14 @@
`name` = #{name,jdbcType=VARCHAR}, `name` = #{name,jdbcType=VARCHAR},
create_user = #{createUser,jdbcType=VARCHAR}, create_user = #{createUser,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=BIGINT},
execute_time = #{executeTime,jdbcType=BIGINT},
start_time = #{startTime,jdbcType=BIGINT}, start_time = #{startTime,jdbcType=BIGINT},
end_time = #{endTime,jdbcType=BIGINT}, end_time = #{endTime,jdbcType=BIGINT},
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
exec_status = #{execStatus,jdbcType=VARCHAR}, exec_status = #{execStatus,jdbcType=VARCHAR},
result_status = #{resultStatus,jdbcType=VARCHAR}, result_status = #{resultStatus,jdbcType=VARCHAR},
pass_threshold = #{passThreshold,jdbcType=VARCHAR},
pass_rate = #{passRate,jdbcType=DECIMAL}, pass_rate = #{passRate,jdbcType=DECIMAL},
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
pass_threshold = #{passThreshold,jdbcType=DECIMAL},
project_id = #{projectId,jdbcType=VARCHAR}, project_id = #{projectId,jdbcType=VARCHAR},
integrated = #{integrated,jdbcType=BIT}, integrated = #{integrated,jdbcType=BIT},
deleted = #{deleted,jdbcType=BIT} deleted = #{deleted,jdbcType=BIT}
@ -369,16 +385,16 @@
</update> </update>
<insert id="batchInsert" parameterType="map"> <insert id="batchInsert" parameterType="map">
insert into test_plan_report insert into test_plan_report
(id, test_plan_id, `name`, create_user, create_time, start_time, end_time, trigger_mode, (id, test_plan_id, `name`, create_user, create_time, execute_time, start_time, end_time,
exec_status, result_status, pass_threshold, pass_rate, project_id, integrated, exec_status, result_status, pass_rate, trigger_mode, pass_threshold, project_id,
deleted) integrated, deleted)
values values
<foreach collection="list" item="item" separator=","> <foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.testPlanId,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, (#{item.id,jdbcType=VARCHAR}, #{item.testPlanId,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR},
#{item.createUser,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.startTime,jdbcType=BIGINT}, #{item.createUser,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.executeTime,jdbcType=BIGINT},
#{item.endTime,jdbcType=BIGINT}, #{item.triggerMode,jdbcType=VARCHAR}, #{item.execStatus,jdbcType=VARCHAR}, #{item.startTime,jdbcType=BIGINT}, #{item.endTime,jdbcType=BIGINT}, #{item.execStatus,jdbcType=VARCHAR},
#{item.resultStatus,jdbcType=VARCHAR}, #{item.passThreshold,jdbcType=VARCHAR}, #{item.resultStatus,jdbcType=VARCHAR}, #{item.passRate,jdbcType=DECIMAL}, #{item.triggerMode,jdbcType=VARCHAR},
#{item.passRate,jdbcType=DECIMAL}, #{item.projectId,jdbcType=VARCHAR}, #{item.integrated,jdbcType=BIT}, #{item.passThreshold,jdbcType=DECIMAL}, #{item.projectId,jdbcType=VARCHAR}, #{item.integrated,jdbcType=BIT},
#{item.deleted,jdbcType=BIT}) #{item.deleted,jdbcType=BIT})
</foreach> </foreach>
</insert> </insert>
@ -407,27 +423,30 @@
<if test="'create_time'.toString() == column.value"> <if test="'create_time'.toString() == column.value">
#{item.createTime,jdbcType=BIGINT} #{item.createTime,jdbcType=BIGINT}
</if> </if>
<if test="'execute_time'.toString() == column.value">
#{item.executeTime,jdbcType=BIGINT}
</if>
<if test="'start_time'.toString() == column.value"> <if test="'start_time'.toString() == column.value">
#{item.startTime,jdbcType=BIGINT} #{item.startTime,jdbcType=BIGINT}
</if> </if>
<if test="'end_time'.toString() == column.value"> <if test="'end_time'.toString() == column.value">
#{item.endTime,jdbcType=BIGINT} #{item.endTime,jdbcType=BIGINT}
</if> </if>
<if test="'trigger_mode'.toString() == column.value">
#{item.triggerMode,jdbcType=VARCHAR}
</if>
<if test="'exec_status'.toString() == column.value"> <if test="'exec_status'.toString() == column.value">
#{item.execStatus,jdbcType=VARCHAR} #{item.execStatus,jdbcType=VARCHAR}
</if> </if>
<if test="'result_status'.toString() == column.value"> <if test="'result_status'.toString() == column.value">
#{item.resultStatus,jdbcType=VARCHAR} #{item.resultStatus,jdbcType=VARCHAR}
</if> </if>
<if test="'pass_threshold'.toString() == column.value">
#{item.passThreshold,jdbcType=VARCHAR}
</if>
<if test="'pass_rate'.toString() == column.value"> <if test="'pass_rate'.toString() == column.value">
#{item.passRate,jdbcType=DECIMAL} #{item.passRate,jdbcType=DECIMAL}
</if> </if>
<if test="'trigger_mode'.toString() == column.value">
#{item.triggerMode,jdbcType=VARCHAR}
</if>
<if test="'pass_threshold'.toString() == column.value">
#{item.passThreshold,jdbcType=DECIMAL}
</if>
<if test="'project_id'.toString() == column.value"> <if test="'project_id'.toString() == column.value">
#{item.projectId,jdbcType=VARCHAR} #{item.projectId,jdbcType=VARCHAR}
</if> </if>

View File

@ -70,13 +70,14 @@ CREATE TABLE IF NOT EXISTS test_plan_report(
`name` VARCHAR(255) NOT NULL COMMENT '报告名称' , `name` VARCHAR(255) NOT NULL COMMENT '报告名称' ,
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' , `create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
`create_time` BIGINT NOT NULL COMMENT '创建时间' , `create_time` BIGINT NOT NULL COMMENT '创建时间' ,
`start_time` BIGINT COMMENT '开始时间' , `execute_time` BIGINT COMMENT '执行时间;计划真正执行的时间' ,
`end_time` BIGINT COMMENT '结束时间' , `start_time` BIGINT COMMENT '开始时间;计划开始执行的时间' ,
`trigger_mode` VARCHAR(50) COMMENT '触发类型' , `end_time` BIGINT COMMENT '结束时间;计划结束执行的时间' ,
`exec_status` VARCHAR(50) NOT NULL DEFAULT 'PENDING' COMMENT '执行状态: 未执行, 执行中, 已停止, 已完成;' , `exec_status` VARCHAR(50) NOT NULL DEFAULT 'PENDING' COMMENT '执行状态' ,
`result_status` VARCHAR(50) DEFAULT '-' COMMENT '结果状态: 成功, 失败, 阻塞, 误报' , `result_status` VARCHAR(50) NOT NULL DEFAULT '-' COMMENT '结果状态' ,
`pass_threshold` VARCHAR(100) NOT NULL COMMENT '通过阈值' , `pass_rate` DECIMAL(10, 4) COMMENT '通过率' ,
`pass_rate` DECIMAL COMMENT '通过率' , `trigger_mode` VARCHAR(50) NOT NULL COMMENT '触发类型' ,
`pass_threshold` DECIMAL(10, 2) NOT NULL COMMENT '通过阈值' ,
`project_id` VARCHAR(50) NOT NULL COMMENT '项目id' , `project_id` VARCHAR(50) NOT NULL COMMENT '项目id' ,
`integrated` BIT NOT NULL DEFAULT 0 COMMENT '是否是集成报告' , `integrated` BIT NOT NULL DEFAULT 0 COMMENT '是否是集成报告' ,
`deleted` BIT NOT NULL DEFAULT 0 COMMENT '是否删除' , `deleted` BIT NOT NULL DEFAULT 0 COMMENT '是否删除' ,
@ -117,20 +118,23 @@ CREATE TABLE IF NOT EXISTS test_plan_report_function_case(
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试计划报告内容功能用例部分'; ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试计划报告内容功能用例部分';
CREATE UNIQUE INDEX idx_test_plan_report_id ON test_plan_report_function_case(test_plan_report_id); CREATE INDEX idx_test_plan_report_id ON test_plan_report_function_case(test_plan_report_id);
CREATE TABLE IF NOT EXISTS test_plan_report_bug( CREATE TABLE IF NOT EXISTS test_plan_report_bug(
`id` VARCHAR(50) COMMENT 'ID' , `id` VARCHAR(50) NOT NULL COMMENT 'ID' ,
`test_plan_report_id` VARCHAR(50) COMMENT '报告ID' , `test_plan_report_id` VARCHAR(50) NOT NULL COMMENT '测试计划报告ID' ,
`bug_id` VARCHAR(50) COMMENT '缺陷ID' `bug_id` VARCHAR(50) NOT NULL COMMENT '缺陷ID' ,
PRIMARY KEY (id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试计划报告内容缺陷部分'; ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试计划报告内容缺陷部分';
CREATE UNIQUE INDEX idx_test_plan_report_id ON test_plan_report_bug(test_plan_report_id); CREATE INDEX idx_test_plan_report_id ON test_plan_report_bug(test_plan_report_id);
-- 场景步骤 csv 表增加场景ID字段 -- 场景步骤 csv 表增加场景ID字段
ALTER TABLE api_scenario_csv_step ADD scenario_id varchar(50) NOT NULL COMMENT '场景ID'; ALTER TABLE api_scenario_csv_step ADD scenario_id varchar(50) NOT NULL COMMENT '场景ID';
CREATE INDEX idx_scenario_id USING BTREE ON api_scenario_csv_step (scenario_id); CREATE INDEX idx_scenario_id USING BTREE ON api_scenario_csv_step (scenario_id);
ALTER TABLE test_plan_config MODIFY pass_threshold DECIMAL(10, 2) NOT NULL;
-- 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;

View File

@ -3,7 +3,7 @@ package io.metersphere.sdk.constants;
/** /**
* 报告执行状态 * 报告执行状态
*/ */
public enum ReportExecStatus { public enum ExecStatus {
/** /**
* 未执行 * 未执行
*/ */

View File

@ -89,4 +89,5 @@ 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=测试计划报告不存在
test_plan_report_id.not_blank=测试计划报告id不能为空 test_plan_report_id.not_blank=测试计划报告id不能为空
test_plan_report_name.not_blank=测试计划报告名称不能为空 test_plan_report_name.not_blank=测试计划报告名称不能为空
test_plan_not_exist=测试计划不存在

View File

@ -101,4 +101,5 @@ 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
test_plan_report_id.not_blank=The test plan report id cannot be empty test_plan_report_id.not_blank=The test plan report id cannot be empty
test_plan_report_name.not_blank=The test plan report name cannot be empty test_plan_report_name.not_blank=The test plan report name cannot be empty
run_functional_case=Run functional case run_functional_case=Run functional case
test_plan_not_exist=The test plan does not exist

View File

@ -101,4 +101,5 @@ test_plan.batch.log={0}测试计划
test_plan_report_not_exist=测试计划报告不存在 test_plan_report_not_exist=测试计划报告不存在
test_plan_report_id.not_blank=测试计划报告id不能为空 test_plan_report_id.not_blank=测试计划报告id不能为空
test_plan_report_name.not_blank=测试计划报告名称不能为空 test_plan_report_name.not_blank=测试计划报告名称不能为空
run_functional_case=执行功能用例 run_functional_case=执行功能用例
test_plan_not_exist=测试计划不存在

View File

@ -101,4 +101,5 @@ test_plan.batch.log={0}測試計劃
test_plan_report_not_exist=測試計劃報告不存在 test_plan_report_not_exist=測試計劃報告不存在
test_plan_report_id.not_blank=測試計劃報告id不能爲空 test_plan_report_id.not_blank=測試計劃報告id不能爲空
test_plan_report_name.not_blank=測試計劃報告名稱不能爲空 test_plan_report_name.not_blank=測試計劃報告名稱不能爲空
run_functional_case=執行功能用例 run_functional_case=執行功能用例
test_plan_not_exist=測試計劃不存在

View File

@ -83,4 +83,11 @@ public interface ExtBugRelateCaseMapper {
List<CaseRelateBugDTO> getBugCountByIds(@Param("ids") List<String> ids); List<CaseRelateBugDTO> getBugCountByIds(@Param("ids") List<String> ids);
List<BugProviderDTO> getTestPlanAssociateBugs(@Param("request") AssociateBugPageRequest request, @Param("sort") String sort); List<BugProviderDTO> getTestPlanAssociateBugs(@Param("request") AssociateBugPageRequest request, @Param("sort") String sort);
/**
* 获取计划关联的缺陷ID集合(去重)
* @param planId 计划ID
* @return 缺陷ID集合
*/
List<String> getPlanRelateBugIds(@Param("id") String planId);
} }

View File

@ -309,4 +309,8 @@
</if> </if>
</where> </where>
</select> </select>
<select id="getPlanRelateBugIds" resultType="java.lang.String">
select distinct bug_id from bug_relation_case where test_plan_id = #{id}
</select>
</mapper> </mapper>

View File

@ -3,7 +3,9 @@ package io.metersphere.plan.controller;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import io.metersphere.plan.constants.TestPlanResourceConfig; import io.metersphere.plan.constants.TestPlanResourceConfig;
import io.metersphere.plan.domain.TestPlanReport;
import io.metersphere.plan.dto.request.TestPlanReportBatchRequest; import io.metersphere.plan.dto.request.TestPlanReportBatchRequest;
import io.metersphere.plan.dto.request.TestPlanReportGenRequest;
import io.metersphere.plan.dto.request.TestPlanReportPageRequest; import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
import io.metersphere.plan.dto.response.TestPlanReportPageResponse; import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
import io.metersphere.plan.service.TestPlanManagementService; import io.metersphere.plan.service.TestPlanManagementService;
@ -77,4 +79,12 @@ public class TestPlanReportController {
public void batchDelete(@Validated @RequestBody TestPlanReportBatchRequest request) { public void batchDelete(@Validated @RequestBody TestPlanReportBatchRequest request) {
testPlanReportService.batchDelete(request, SessionUtils.getUserId()); testPlanReportService.batchDelete(request, SessionUtils.getUserId());
} }
@PostMapping("/gen")
@Operation(summary = "测试计划-详情-生成报告")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
public TestPlanReport genReportByManual(@Validated @RequestBody TestPlanReportGenRequest request) {
return testPlanReportService.genReportByManual(request, SessionUtils.getUserId());
}
} }

View File

@ -0,0 +1,32 @@
package io.metersphere.plan.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TestPlanReportGenPreParam {
@Schema(description = "项目ID")
private String projectId;
@Schema(description = "计划ID")
private String testPlanId;
@Schema(description = "计划名称")
private String testPlanName;
@Schema(description = "计划开始时间")
private Long startTime;
@Schema(description = "触发方式")
private String triggerMode;
@Schema(description = "执行状态")
private String execStatus;
@Schema(description = "结果状态")
private String resultStatus;
@Schema(description = "是否集成报告")
private Boolean integrated;
}

View File

@ -0,0 +1,26 @@
package io.metersphere.plan.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TestPlanReportPostParam {
@Schema(description = "项目ID")
private String projectId;
@Schema(description = "计划ID")
private String testPlanId;
@Schema(description = "报告ID")
private String reportId;
@Schema(description = "计划开始执行时间")
private Long executeTime;
@Schema(description = "计划结束时间")
private Long endTime;
@Schema(description = "执行状态")
private String execStatus;
}

View File

@ -0,0 +1,17 @@
package io.metersphere.plan.dto.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class TestPlanReportGenRequest {
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan.project_id.not_blank}")
private String projectId;
@Schema(description = "计划ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan.id.not_blank}")
private String testPlanId;
}

View File

@ -27,6 +27,13 @@ public interface ExtTestPlanReportMapper {
*/ */
List<String> getReportBatchIdsByParam(@Param("request") TestPlanReportBatchRequest request); List<String> getReportBatchIdsByParam(@Param("request") TestPlanReportBatchRequest request);
/**
* 统计报告中执行通过的功能用例数量
* @param reportId 报告ID
* @return 用例数量
*/
Long countExecuteSuccessFunctionalCase(@Param("id") String reportId);
List<TestPlanReport> selectReportByIds(@Param("ids") List<String> ids); List<TestPlanReport> selectReportByIds(@Param("ids") List<String> ids);
List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> subList); List<ApiReportMessageDTO> getNoticeList(@Param("ids") List<String> subList);

View File

@ -15,6 +15,12 @@
join test_plan tp on tpr.test_plan_id = tp.id join test_plan tp on tpr.test_plan_id = tp.id
<include refid="queryWhereCondition"/> <include refid="queryWhereCondition"/>
</select> </select>
<select id="countExecuteSuccessFunctionalCase" resultType="java.lang.Long">
select count(*) from test_plan_report_function_case tprfc
where tprfc.test_plan_report_id = #{id} and tprfc.execute_result = 'SUCCESS'
</select>
<select id="selectReportByIds" resultType="io.metersphere.plan.domain.TestPlanReport"> <select id="selectReportByIds" resultType="io.metersphere.plan.domain.TestPlanReport">
select * from test_plan_report where id in select * from test_plan_report where id in
<foreach collection="ids" item="id" open="(" close=")" separator=","> <foreach collection="ids" item="id" open="(" close=")" separator=",">

View File

@ -1,23 +1,39 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import io.metersphere.plan.domain.TestPlanReport; import io.metersphere.bug.mapper.BugRelationCaseMapper;
import io.metersphere.plan.domain.TestPlanReportExample; import io.metersphere.bug.mapper.ExtBugRelateCaseMapper;
import io.metersphere.plan.domain.*;
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.TestPlanReportBatchRequest;
import io.metersphere.plan.dto.request.TestPlanReportGenRequest;
import io.metersphere.plan.dto.request.TestPlanReportPageRequest; import io.metersphere.plan.dto.request.TestPlanReportPageRequest;
import io.metersphere.plan.dto.response.TestPlanReportPageResponse; import io.metersphere.plan.dto.response.TestPlanReportPageResponse;
import io.metersphere.plan.mapper.ExtTestPlanReportMapper; import io.metersphere.plan.mapper.*;
import io.metersphere.plan.mapper.TestPlanReportMapper; 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.exception.MSException; import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.DateUtils;
import io.metersphere.sdk.util.SubListUtils; import io.metersphere.sdk.util.SubListUtils;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.User; import io.metersphere.system.domain.User;
import io.metersphere.system.mapper.UserMapper; import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.notice.constants.NoticeConstants; import io.metersphere.system.notice.constants.NoticeConstants;
import io.metersphere.system.service.UserService; import io.metersphere.system.service.UserService;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -25,18 +41,32 @@ import java.util.Map;
@Service @Service
public class TestPlanReportService { public class TestPlanReportService {
@Resource @Resource
private UserService userService; private UserMapper userMapper;
@Resource @Resource
private TestPlanReportMapper testPlanReportMapper; private UserService userService;
@Resource @Resource
private ExtTestPlanReportMapper extTestPlanReportMapper; private SqlSessionFactory sqlSessionFactory;
@Resource @Resource
private TestPlanReportLogService testPlanReportLogService; private TestPlanMapper testPlanMapper;
@Resource @Resource
private TestPlanReportNoticeService testPlanReportNoticeService; private TestPlanConfigMapper testPlanConfigMapper;
@Resource @Resource
private UserMapper userMapper; private TestPlanReportMapper testPlanReportMapper;
@Resource
private ExtBugRelateCaseMapper extBugRelateCaseMapper;
@Resource
private BugRelationCaseMapper bugRelationCaseMapper;
@Resource
private ExtTestPlanReportMapper extTestPlanReportMapper;
@Resource
private TestPlanReportLogService testPlanReportLogService;
@Resource
private TestPlanReportNoticeService testPlanReportNoticeService;
@Resource
private TestPlanReportSummaryMapper testPlanReportSummaryMapper;
@Resource
private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
/** /**
* 分页查询报告列表 * 分页查询报告列表
@ -95,6 +125,155 @@ public class TestPlanReportService {
} }
} }
/**
* 手动生成报告
* @param request 请求参数
* @return 报告
*/
public TestPlanReport genReportByManual(TestPlanReportGenRequest request, String currentUser) {
TestPlan testPlan = checkPlan(request.getTestPlanId());
/*
* 手动生成报告
* 1. 构建预生成报告参数
* 2. 预生成报告
* 3. 报告后置处理
*/
TestPlanReportGenPreParam genPreParam = new TestPlanReportGenPreParam();
BeanUtils.copyBean(genPreParam, request);
genPreParam.setTestPlanName(testPlan.getName());
genPreParam.setStartTime(System.currentTimeMillis());
// 手动触发
genPreParam.setTriggerMode(TaskTriggerMode.MANUAL.name());
// 报告预生成时, 执行状态为未执行, 结果状态为'-'
genPreParam.setExecStatus(ExecStatus.PENDING.name());
genPreParam.setResultStatus("-");
// 是否集成报告, 目前根据是否计划组来区分
genPreParam.setIntegrated(StringUtils.equals(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP));
TestPlanReport preReport = preGenReport(genPreParam, currentUser);
TestPlanReportPostParam postParam = new TestPlanReportPostParam();
BeanUtils.copyBean(postParam, request);
postParam.setReportId(preReport.getId());
return postHandleReport(postParam);
}
/**
* 预生成报告内容(后续拆分优化)
* @return 报告
*/
public TestPlanReport preGenReport(TestPlanReportGenPreParam genParam, String currentUser) {
// 准备计划数据
TestPlanConfig testPlanConfig = testPlanConfigMapper.selectByPrimaryKey(genParam.getTestPlanId());
/*
* 预生成报告(后续执行生成报告复用)
* 1. 生成报告用例数据, 缺陷数据
* 2. 生成或计算报告统计数据
*/
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
String reportId = IDGenerator.nextStr();
// 功能用例
List<TestPlanReportFunctionCase> reportFunctionCases = new ArrayList<>();
TestPlanFunctionalCaseExample functionalCaseExample = new TestPlanFunctionalCaseExample();
functionalCaseExample.createCriteria().andTestPlanIdEqualTo(genParam.getTestPlanId());
List<TestPlanFunctionalCase> testPlanFunctionalCases = testPlanFunctionalCaseMapper.selectByExample(functionalCaseExample);
testPlanFunctionalCases.forEach(functionalCase -> {
TestPlanReportFunctionCase reportFunctionCase = new TestPlanReportFunctionCase();
reportFunctionCase.setId(IDGenerator.nextStr());
reportFunctionCase.setTestPlanReportId(reportId);
reportFunctionCase.setFunctionCaseId(functionalCase.getFunctionalCaseId());
reportFunctionCase.setTestPlanFunctionCaseId(functionalCase.getId());
reportFunctionCase.setExecuteResult(functionalCase.getLastExecResult());
reportFunctionCases.add(reportFunctionCase);
});
if (CollectionUtils.isNotEmpty(reportFunctionCases)) {
// 插入计划功能用例关联数据 -> 报告内容
TestPlanReportFunctionCaseMapper batchMapper = sqlSession.getMapper(TestPlanReportFunctionCaseMapper.class);
batchMapper.batchInsert(reportFunctionCases);
}
// TODO: 接口用例, 场景报告内容 (与接口报告是否能一致)
// 计划报告缺陷内容
List<TestPlanReportBug> reportBugs = new ArrayList<>();
List<String> bugIds = extBugRelateCaseMapper.getPlanRelateBugIds(genParam.getTestPlanId());
bugIds.forEach(bugId -> {
TestPlanReportBug reportBug = new TestPlanReportBug();
reportBug.setId(IDGenerator.nextStr());
reportBug.setTestPlanReportId(reportId);
reportBug.setBugId(bugId);
reportBugs.add(reportBug);
});
if (CollectionUtils.isNotEmpty(reportBugs)) {
// 插入计划关联用例缺陷数据(去重) -> 报告内容
TestPlanReportBugMapper batchMapper = sqlSession.getMapper(TestPlanReportBugMapper.class);
batchMapper.batchInsert(reportBugs);
}
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
// 插入报告统计内容
TestPlanReportSummary reportSummary = new TestPlanReportSummary();
reportSummary.setId(IDGenerator.nextStr());
reportSummary.setTestPlanReportId(reportId);
reportSummary.setFunctionalCaseCount((long) (CollectionUtils.isEmpty(reportFunctionCases) ? 0 : reportFunctionCases.size()));
reportSummary.setApiCaseCount(0L);
reportSummary.setApiScenarioCount(0L);
reportSummary.setBugCount((long) (CollectionUtils.isEmpty(reportBugs) ? 0 : reportBugs.size()));
testPlanReportSummaryMapper.insertSelective(reportSummary);
// 插入报告
TestPlanReport report = new TestPlanReport();
BeanUtils.copyBean(report, genParam);
report.setId(reportId);
report.setName(genParam.getTestPlanName() + "-" + DateUtils.getTimeStr(System.currentTimeMillis()));
report.setCreateUser(currentUser);
report.setCreateTime(System.currentTimeMillis());
report.setDeleted(false);
report.setPassThreshold(testPlanConfig.getPassThreshold());
testPlanReportMapper.insertSelective(report);
return report;
}
/**
* 报告结果后置处理
* @param postParam 后置处理参数
* @return 报告
*/
public TestPlanReport postHandleReport(TestPlanReportPostParam postParam) {
/*
* 处理报告(执行状态, 结束时间)
*/
TestPlanReport planReport = checkReport(postParam.getReportId());
BeanUtils.copyBean(planReport, postParam);
/*
* TODO: 计算报告通过率, 并对比阈值生成报告结果状态(目前只有功能用例参与计算)
*/
TestPlanReportSummaryExample example = new TestPlanReportSummaryExample();
example.createCriteria().andTestPlanReportIdEqualTo(postParam.getReportId());
TestPlanReportSummary reportSummary = testPlanReportSummaryMapper.selectByExample(example).get(0);
DecimalFormat rateFormat = new DecimalFormat("#0.0000");
rateFormat.setMinimumFractionDigits(2);
rateFormat.setMaximumFractionDigits(2);
// 通过的功能用例数
// TODO: 接口用例, 场景用例
long functionalCasePassCount = extTestPlanReportMapper.countExecuteSuccessFunctionalCase(postParam.getReportId());
// 用例总数
long caseTotal = reportSummary.getFunctionalCaseCount() + reportSummary.getApiCaseCount() + reportSummary.getApiScenarioCount();
// 通过率 {通过用例数/总用例数}
double passRate = (functionalCasePassCount == 0 || caseTotal == 0) ? 0.00 :
Double.parseDouble(rateFormat.format((double) functionalCasePassCount / (double) caseTotal));
// FIXME: 后续替换成PASS_COUNT {保留该逻辑, 四舍五入导致的边界值数据展示偏差}
if (passRate == 0 && functionalCasePassCount > 0) {
passRate = 0.0001;
} else if (passRate == 100 && functionalCasePassCount < caseTotal) {
passRate = 0.9999;
}
planReport.setPassRate(passRate);
// 计划的(执行)结果状态: 通过率 >= 阈值 ? 成功 : 失败
planReport.setResultStatus(passRate >= planReport.getPassThreshold() ? ReportStatus.SUCCESS.name() : ReportStatus.ERROR.name());
return planReport;
}
/** /**
* 通过请求参数获取批量操作的ID集合 * 通过请求参数获取批量操作的ID集合
@ -114,7 +293,21 @@ public class TestPlanReportService {
} }
} }
/** /**
* 校验计划是否存在
* @param planId 计划ID
* @return 测试计划
*/
private TestPlan checkPlan(String planId) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId);
if (testPlan == null) {
throw new MSException(Translator.get("test_plan_not_exist"));
}
return testPlan;
}
/**
* 校验报告是否存在 * 校验报告是否存在
* *
* @param id 报告ID * @param id 报告ID

View File

@ -32,6 +32,7 @@ public class TestPlanReportControllerTests extends BaseTest {
private static final String RENAME_PLAN_REPORT = "/test-plan/report/rename"; private static final String RENAME_PLAN_REPORT = "/test-plan/report/rename";
private static final String DELETE_PLAN_REPORT = "/test-plan/report/delete"; 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 BATCH_DELETE_PLAN_REPORT = "/test-plan/report/batch-delete";
private static final String GEN_PLAN_REPORT = "/test-plan/report/gen";
private static final String GEN_AND_SHARE = "/test-plan/report/share/gen"; 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_INFO = "/test-plan/report/share/get";
private static final String GET_SHARE_TIME = "/test-plan/report/share/get-share-time"; private static final String GET_SHARE_TIME = "/test-plan/report/share/get-share-time";
@ -161,4 +162,25 @@ public class TestPlanReportControllerTests extends BaseTest {
request.setExcludeIds(null); request.setExcludeIds(null);
this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request); this.requestPostWithOk(BATCH_DELETE_PLAN_REPORT, request);
} }
@Test
@Order(10)
@Sql(scripts = {"/dml/init_test_plan_report_gen.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
void testGenReportError() throws Exception {
TestPlanReportGenRequest genRequest = new TestPlanReportGenRequest();
genRequest.setProjectId("100001100001");
genRequest.setTestPlanId("plan_id_for_gen_report-x");
this.requestPost(GEN_PLAN_REPORT, genRequest, status().is5xxServerError());
}
@Test
@Order(11)
void testGenReportSuccess() throws Exception {
TestPlanReportGenRequest genRequest = new TestPlanReportGenRequest();
genRequest.setProjectId("100001100001");
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);
}
} }

View File

@ -643,7 +643,7 @@ public class TestPlanTests extends BaseTest {
request.setGroupId(testPlanTestService.selectTestPlanByName("testPlan_60").getGroupId()); request.setGroupId(testPlanTestService.selectTestPlanByName("testPlan_60").getGroupId());
this.requestPost(URL_POST_TEST_PLAN_ADD, request); this.requestPost(URL_POST_TEST_PLAN_ADD, request);
request.setGroupId(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID); request.setGroupId(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID);
request.setPassThreshold(100.111); request.setPassThreshold(100.11);
this.requestPost(URL_POST_TEST_PLAN_ADD, request).andExpect(status().isBadRequest()); this.requestPost(URL_POST_TEST_PLAN_ADD, request).andExpect(status().isBadRequest());
request.setPassThreshold(-0.12); request.setPassThreshold(-0.12);
this.requestPost(URL_POST_TEST_PLAN_ADD, request).andExpect(status().isBadRequest()); this.requestPost(URL_POST_TEST_PLAN_ADD, request).andExpect(status().isBadRequest());
@ -889,7 +889,7 @@ public class TestPlanTests extends BaseTest {
updateRequest = testPlanTestService.generateUpdateRequest(testPlan.getId()); updateRequest = testPlanTestService.generateUpdateRequest(testPlan.getId());
updateRequest.setAutomaticStatusUpdate(true); updateRequest.setAutomaticStatusUpdate(true);
updateRequest.setRepeatCase(true); updateRequest.setRepeatCase(true);
updateRequest.setPassThreshold(43.123); updateRequest.setPassThreshold(43.12);
mvcResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_UPDATE, updateRequest); mvcResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_UPDATE, updateRequest);
returnStr = mvcResult.getResponse().getContentAsString(); returnStr = mvcResult.getResponse().getContentAsString();
holder = JSON.parseObject(returnStr, ResultHolder.class); holder = JSON.parseObject(returnStr, ResultHolder.class);
@ -900,7 +900,7 @@ public class TestPlanTests extends BaseTest {
updateRequest = testPlanTestService.generateUpdateRequest(testPlan.getId()); updateRequest = testPlanTestService.generateUpdateRequest(testPlan.getId());
updateRequest.setAutomaticStatusUpdate(false); updateRequest.setAutomaticStatusUpdate(false);
updateRequest.setRepeatCase(false); updateRequest.setRepeatCase(false);
updateRequest.setPassThreshold(56.478); updateRequest.setPassThreshold(56.47);
mvcResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_UPDATE, updateRequest); mvcResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_UPDATE, updateRequest);
returnStr = mvcResult.getResponse().getContentAsString(); returnStr = mvcResult.getResponse().getContentAsString();
holder = JSON.parseObject(returnStr, ResultHolder.class); holder = JSON.parseObject(returnStr, ResultHolder.class);

View File

@ -0,0 +1,19 @@
-- 计划的测试数据
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_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`, `test_planning`) VALUES
('plan_id_for_gen_report', b'0', b'0', 100.00, b'0'),
('plan_id_for_gen_report_1', b'0', b'0', 0.00, b'0');
-- 计划关联用例执行的测试数据
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);
-- 计划关联缺陷的测试数据
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);