fix(测试跟踪): 修复接口调用没有关联可执行用例测试计划执行时没有提示的缺陷 (#16502)

--bug=1015449 --user=王孝刚
[测试计划]github#16371测试计划里只包含功能用例,在页面无法执行,但是调用API可以执行,且可正常生成报告,报告里无任何信息
https://www.tapd.cn/55049933/s/1214889

Co-authored-by: wxg0103 <727495428@qq.com>
This commit is contained in:
MeterSphere Bot 2022-08-01 09:47:03 +08:00 committed by GitHub
parent dc17466990
commit 08519bc6e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 440 additions and 353 deletions

View File

@ -20,7 +20,7 @@ public interface ExtTestPlanApiCaseMapper {
List<String> getIdsByPlanId(String planId); List<String> getIdsByPlanId(String planId);
List<String> getNotRelevanceCaseIds(@Param("planId")String planId, @Param("relevanceProjectIds")List<String> relevanceProjectIds); List<String> getNotRelevanceCaseIds(@Param("planId") String planId, @Param("relevanceProjectIds") List<String> relevanceProjectIds);
List<String> getStatusByTestPlanId(String id); List<String> getStatusByTestPlanId(String id);
@ -36,14 +36,17 @@ public interface ExtTestPlanApiCaseMapper {
List<TestPlanFailureApiDTO> getFailureList(@Param("planId") String planId, @Param("status") String status); List<TestPlanFailureApiDTO> getFailureList(@Param("planId") String planId, @Param("status") String status);
List<TestPlanFailureApiDTO> getFailureListByIds(@Param("ids") Collection<String> caseIdList,@Param("status") String status); List<TestPlanFailureApiDTO> getFailureListByIds(@Param("ids") Collection<String> caseIdList, @Param("status") String status);
List<String> selectPlanIds(); List<String> selectPlanIds();
List<String> getIdsOrderByUpdateTime(@Param("planId") String planId); List<String> getIdsOrderByUpdateTime(@Param("planId") String planId);
Long getPreOrder(@Param("planId")String planId, @Param("baseOrder") Long baseOrder); Long getPreOrder(@Param("planId") String planId, @Param("baseOrder") Long baseOrder);
Long getLastOrder(@Param("planId") String planId, @Param("baseOrder") Long baseOrder);
List<TestPlanApiCase> selectByIdsAndStatusIsNotTrash(@Param("ids") List<String> ids);
Long getLastOrder(@Param("planId")String planId, @Param("baseOrder") Long baseOrder);
} }

View File

@ -3,368 +3,410 @@
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper"> <mapper namespace="io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper">
<insert id="insertIfNotExists" parameterType="io.metersphere.base.domain.TestPlanApiCase"> <insert id="insertIfNotExists" parameterType="io.metersphere.base.domain.TestPlanApiCase">
INSERT INTO test_plan_api_case(id, test_plan_id, api_case_id, environment_id, create_time, update_time, create_user, `order`) INSERT INTO test_plan_api_case(id, test_plan_id, api_case_id, environment_id, create_time, update_time,
SELECT #{request.id}, #{request.testPlanId}, #{request.apiCaseId}, #{request.environmentId}, #{request.createTime}, #{request.updateTime}, #{request.createUser}, #{request.order} create_user, `order`)
FROM DUAL SELECT #{request.id},
WHERE NOT EXISTS( #{request.testPlanId},
SELECT id FROM #{request.apiCaseId},
test_plan_api_case #{request.environmentId},
WHERE test_plan_id = #{request.testPlanId} and api_case_id = #{request.apiCaseId} #{request.createTime},
) #{request.updateTime},
</insert> #{request.createUser},
<select id="getApiTestCaseById" resultType="io.metersphere.base.domain.ApiTestCaseWithBLOBs"> #{request.order}
SELECT t.* FROM api_test_case t FROM DUAL
INNER JOIN test_plan_api_case tpac ON t.id = tpac.api_case_id WHERE NOT EXISTS(
WHERE tpac.id = #{0} SELECT id
</select> FROM test_plan_api_case
<select id="getApiTestCaseIdById" resultType="java.lang.String"> WHERE test_plan_id = #{request.testPlanId}
SELECT api_case_id FROM test_plan_api_case t WHERE id = #{0} and api_case_id = #{request.apiCaseId}
</select> )
<select id="selectLegalDataByTestPlanId" resultType="io.metersphere.base.domain.TestPlanApiCase"> </insert>
SELECT t.* FROM test_plan_api_case t WHERE t.test_plan_id = #{0} <select id="getApiTestCaseById" resultType="io.metersphere.base.domain.ApiTestCaseWithBLOBs">
AND t.api_case_id IN ( SELECT t.*
SELECT id FROM api_test_case WHERE status IS NULL OR status != 'Trash' FROM api_test_case t
) INNER JOIN test_plan_api_case tpac ON t.id = tpac.api_case_id
ORDER BY `order` DESC WHERE tpac.id = #{0}
</select> </select>
<select id="list" resultType="io.metersphere.api.dto.definition.TestPlanApiCaseDTO"> <select id="getApiTestCaseIdById" resultType="java.lang.String">
select SELECT api_case_id
t.id, FROM test_plan_api_case t
t.environment_id, WHERE id = #{0}
( </select>
SELECT <select id="selectLegalDataByTestPlanId" resultType="io.metersphere.base.domain.TestPlanApiCase">
NAME SELECT t.*
FROM FROM test_plan_api_case t
api_test_environment WHERE t.test_plan_id = #{0}
WHERE AND t.api_case_id IN (
id = t.environment_id SELECT id
) AS environment_name, FROM api_test_case
t.create_time, WHERE status IS NULL
t.update_time, OR status
c.id AS case_id, != 'Trash'
c.project_id, )
c.name, ORDER BY `order` DESC
c.api_definition_id, </select>
c.priority, <select id="list" resultType="io.metersphere.api.dto.definition.TestPlanApiCaseDTO">
c.description, select
c.create_user_id, t.id,
c.update_user_id, t.environment_id,
c.num, (
c.tags, SELECT
c.create_user_id as create_user, NAME
a.module_id, FROM
a.path, api_test_environment
a.protocol, WHERE
t.status execResult, id = t.environment_id
a.user_id, ) AS environment_name,
a.version_id versionId t.create_time,
from t.update_time,
test_plan_api_case t c.id AS case_id,
inner join c.project_id,
api_test_case c c.name,
on t.api_case_id = c.id c.api_definition_id,
<if test="request.planId != null and request.planId!=''"> c.priority,
and t.test_plan_id = #{request.planId} c.description,
</if> c.create_user_id,
inner join c.update_user_id,
api_definition a c.num,
on c.tags,
c.api_definition_id = a.id c.create_user_id as create_user,
where 1 a.module_id,
<if test="request.protocol != null and request.protocol!=''"> a.path,
and a.protocol = #{request.protocol} a.protocol,
</if> t.status execResult,
<choose> a.user_id,
<when test="request.status == 'Trash'"> a.version_id versionId
and c.status = 'Trash' from
</when> test_plan_api_case t
<when test="request.status == null"> inner join
and (c.status IS NULL or c.status != 'Trash') api_test_case c
</when> on t.api_case_id = c.id
<when test="request.status == ''"> <if test="request.planId != null and request.planId!=''">
and (c.status IS NULL or c.status != 'Trash') and t.test_plan_id = #{request.planId}
</when>
<when test="request.status == 'running'">
and t.status IS NULL
</when>
<otherwise>
and t.status = #{request.status}
</otherwise>
</choose>
<if test="request.ids != null and request.ids.size() > 0">
<if test="request.projectId != null and request.projectId!=''">
and a.projectId = #{request.projectId}
</if>
and t.id in
<foreach collection="request.ids" item="caseId" separator="," open="(" close=")">
#{caseId}
</foreach>
</if>
<if test="request.name != null and request.name!=''">
and (c.name like CONCAT('%', #{request.name},'%')
or c.tags like CONCAT('%', #{request.name},'%')
or c.num like CONCAT('%', #{request.name},'%')
)
</if>
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and a.module_id in
<foreach collection="request.moduleIds" item="nodeId" separator="," open="(" close=")">
#{nodeId}
</foreach>
</if>
<if test="request.filters != null and request.filters.size() > 0">
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key == 'priority'">
and c.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'user_id'">
and c.create_user_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'priority'">
and a.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'version_id'">
and a.version_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if> </if>
</foreach> inner join
</if> api_definition a
<include refid="queryVersionCondition"> on
<property name="versionTable" value="a"/> c.api_definition_id = a.id
</include> where 1
<if test="request.orders != null and request.orders.size() > 0"> <if test="request.protocol != null and request.protocol!=''">
order by and a.protocol = #{request.protocol}
<foreach collection="request.orders" separator="," item="order">
<choose>
<when test="order.name == 'update_time' or order.name == 'order'">
t.${order.name} ${order.type}
</when>
<when test="order.name == 'create_user'">
create_user_id ${order.type}
</when>
<otherwise>
${order.name} ${order.type}
</otherwise>
</choose>
</foreach>
</if>
</select>
<select id="selectIds" resultType="java.lang.String">
select
t.id
from
test_plan_api_case t
inner join
api_test_case c
on t.api_case_id = c.id
<if test="request.planId != null and request.planId!=''">
and t.test_plan_id = #{request.planId}
</if>
inner join
api_definition a
on
c.api_definition_id = a.id
<if test="request.protocol != null and request.protocol!=''">
and a.protocol = #{request.protocol}
</if>
<choose>
<when test="request.status == 'Trash'">
and a.status = 'Trash'
</when>
<when test="request.status == null">
and a.status != 'Trash'
</when>
<when test="request.status == ''">
and a.status != 'Trash'
</when>
<when test="request.status == 'running'">
and t.status IS NULL
</when>
<otherwise>
and t.status = #{request.status}
</otherwise>
</choose>
where 1
<if test="request.ids != null and request.ids.size() > 0">
<if test="request.projectId != null and request.projectId!=''">
and
</if>
t.id in
<foreach collection="request.ids" item="caseId" separator="," open="(" close=")">
#{caseId}
</foreach>
</if>
<if test="request.name != null and request.name!=''">
and (c.name like CONCAT('%', #{request.name},'%') or c.tags like CONCAT('%', #{request.name},'%'))
</if>
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and a.module_id in
<foreach collection="request.moduleIds" item="nodeId" separator="," open="(" close=")">
#{nodeId}
</foreach>
</if>
<if test="request.filters != null and request.filters.size() > 0">
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key == 'priority'">
and c.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'user_id'">
and c.create_user_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if> </if>
</foreach>
</if>
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
<choose> <choose>
<when test="order.name == 'update_time' or order.name == 'order'" > <when test="request.status == 'Trash'">
t.${order.name} ${order.type} and c.status = 'Trash'
</when> </when>
<when test="order.name == 'create_user'"> <when test="request.status == null">
create_user_id ${order.type} and (c.status IS NULL or c.status != 'Trash')
</when> </when>
<otherwise> <when test="request.status == ''">
c.${order.name} ${order.type} and (c.status IS NULL or c.status != 'Trash')
</otherwise> </when>
<when test="request.status == 'running'">
and t.status IS NULL
</when>
<otherwise>
and t.status = #{request.status}
</otherwise>
</choose> </choose>
</foreach> <if test="request.ids != null and request.ids.size() > 0">
</if> <if test="request.projectId != null and request.projectId!=''">
</select> and a.projectId = #{request.projectId}
<select id="getExecResultByPlanId" resultType="java.lang.String"> </if>
select status and t.id in
from <foreach collection="request.ids" item="caseId" separator="," open="(" close=")">
test_plan_api_case #{caseId}
where test_plan_id = #{planId} </foreach>
AND api_case_id in (SELECT id FROM api_test_case WHERE (`status` is null or `status` != 'Trash')) </if>
</select> <if test="request.name != null and request.name!=''">
and (c.name like CONCAT('%', #{request.name},'%')
or c.tags like CONCAT('%', #{request.name},'%')
or c.num like CONCAT('%', #{request.name},'%')
)
</if>
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and a.module_id in
<foreach collection="request.moduleIds" item="nodeId" separator="," open="(" close=")">
#{nodeId}
</foreach>
</if>
<if test="request.filters != null and request.filters.size() > 0">
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key == 'priority'">
and c.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'user_id'">
and c.create_user_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'priority'">
and a.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'version_id'">
and a.version_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if>
</foreach>
</if>
<include refid="queryVersionCondition">
<property name="versionTable" value="a"/>
</include>
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
<choose>
<when test="order.name == 'update_time' or order.name == 'order'">
t.${order.name} ${order.type}
</when>
<when test="order.name == 'create_user'">
create_user_id ${order.type}
</when>
<otherwise>
${order.name} ${order.type}
</otherwise>
</choose>
</foreach>
</if>
<select id="getIdsByPlanId" resultType="java.lang.String"> </select>
select id <select id="selectIds" resultType="java.lang.String">
from test_plan_api_case select
where id = #{planId} t.id
</select> from
test_plan_api_case t
inner join
api_test_case c
on t.api_case_id = c.id
<if test="request.planId != null and request.planId!=''">
and t.test_plan_id = #{request.planId}
</if>
inner join
api_definition a
on
c.api_definition_id = a.id
<if test="request.protocol != null and request.protocol!=''">
and a.protocol = #{request.protocol}
</if>
<choose>
<when test="request.status == 'Trash'">
and a.status = 'Trash'
</when>
<when test="request.status == null">
and a.status != 'Trash'
</when>
<when test="request.status == ''">
and a.status != 'Trash'
</when>
<when test="request.status == 'running'">
and t.status IS NULL
</when>
<otherwise>
and t.status = #{request.status}
</otherwise>
</choose>
where 1
<if test="request.ids != null and request.ids.size() > 0">
<if test="request.projectId != null and request.projectId!=''">
and
</if>
t.id in
<foreach collection="request.ids" item="caseId" separator="," open="(" close=")">
#{caseId}
</foreach>
</if>
<if test="request.name != null and request.name!=''">
and (c.name like CONCAT('%', #{request.name},'%') or c.tags like CONCAT('%', #{request.name},'%'))
</if>
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
and a.module_id in
<foreach collection="request.moduleIds" item="nodeId" separator="," open="(" close=")">
#{nodeId}
</foreach>
</if>
<if test="request.filters != null and request.filters.size() > 0">
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key == 'priority'">
and c.priority in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key == 'user_id'">
and c.create_user_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if>
</foreach>
</if>
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
<choose>
<when test="order.name == 'update_time' or order.name == 'order'">
t.${order.name} ${order.type}
</when>
<when test="order.name == 'create_user'">
create_user_id ${order.type}
</when>
<otherwise>
c.${order.name} ${order.type}
</otherwise>
</choose>
</foreach>
</if>
</select>
<select id="getExecResultByPlanId" resultType="java.lang.String">
select status
from test_plan_api_case
where test_plan_id = #{planId}
AND api_case_id in (SELECT id FROM api_test_case WHERE (`status` is null or `status` != 'Trash'))
</select>
<select id="getNotRelevanceCaseIds" resultType="java.lang.String"> <select id="getIdsByPlanId" resultType="java.lang.String">
select t.id select id
from test_plan_api_case t from test_plan_api_case
inner join api_test_case c where id = #{planId}
on c.id = t.api_case_id </select>
<if test="relevanceProjectIds != null and relevanceProjectIds.size() > 0">
and c.project_id not in <select id="getNotRelevanceCaseIds" resultType="java.lang.String">
<foreach collection="relevanceProjectIds" item="projectId" separator="," open="(" close=")"> select t.id
#{projectId} from test_plan_api_case t
</foreach> inner join api_test_case c
</if> on c.id = t.api_case_id
where t.test_plan_id = #{planId} <if test="relevanceProjectIds != null and relevanceProjectIds.size() > 0">
</select> and c.project_id not in
<select id="getStatusByTestPlanId" resultType="java.lang.String"> <foreach collection="relevanceProjectIds" item="projectId" separator="," open="(" close=")">
SELECT `status` FROM test_plan_api_case WHERE test_plan_id = #{0} #{projectId}
</select> </foreach>
</if>
where t.test_plan_id = #{planId}
</select>
<select id="getStatusByTestPlanId" resultType="java.lang.String">
SELECT `status`
FROM test_plan_api_case
WHERE test_plan_id = #{0}
</select>
<select id="selectForPlanReport" resultType="io.metersphere.track.dto.PlanReportCaseDTO"> <select id="selectForPlanReport" resultType="io.metersphere.track.dto.PlanReportCaseDTO">
select id,status from test_plan_api_case where test_plan_id = #{planId} and api_case_id IN ( select id, status
SELECT id FROM api_test_case where status is null or status != 'Trash' from test_plan_api_case
) where test_plan_id = #{planId}
and api_case_id IN (
SELECT id
FROM api_test_case
where status is null
or status
!= 'Trash'
)
</select> </select>
<select id="getFailureList" resultType="io.metersphere.api.dto.automation.TestPlanFailureApiDTO"> <select id="getFailureList" resultType="io.metersphere.api.dto.automation.TestPlanFailureApiDTO">
select select
t.id, t.id,
c.id as case_id, c.project_id, c.name, c.api_definition_id, c.priority, c.create_user_id, c.id as case_id, c.project_id, c.name, c.api_definition_id, c.priority, c.create_user_id,
c.num,c.create_user_id AS create_user, c.num,c.create_user_id AS create_user,
t.status execResult t.status execResult
from from
test_plan_api_case t test_plan_api_case t
inner join inner join
api_test_case c api_test_case c
on t.api_case_id = c.id on t.api_case_id = c.id
and t.test_plan_id = #{planId} and t.test_plan_id = #{planId}
<if test="status == 'unExecute'"> <if test="status == 'unExecute'">
and (t.status in ('Stop','unExecute') or t.status IS NULL) and (t.status in ('Stop','unExecute') or t.status IS NULL)
</if> </if>
<if test="status != null and status != 'unExecute'"> <if test="status != null and status != 'unExecute'">
and t.status = #{status} and t.status = #{status}
</if> </if>
and (c.status != 'Trash' or c.status is null) and (c.status != 'Trash' or c.status is null)
where t.test_plan_id = #{planId} ORDER BY t.order DESC where t.test_plan_id = #{planId} ORDER BY t.order DESC
</select> </select>
<select id="getFailureListByIds" resultType="io.metersphere.api.dto.automation.TestPlanFailureApiDTO"> <select id="getFailureListByIds" resultType="io.metersphere.api.dto.automation.TestPlanFailureApiDTO">
select select
t.id, t.id,
c.id as case_id, c.project_id, c.name, c.api_definition_id, c.priority, c.create_user_id, c.id as case_id, c.project_id, c.name, c.api_definition_id, c.priority, c.create_user_id,
c.num,t.create_user, c.num,t.create_user,
t.status execResult t.status execResult
from from
test_plan_api_case t test_plan_api_case t
inner join inner join
api_test_case c api_test_case c
on t.api_case_id = c.id on t.api_case_id = c.id
<if test="status != null"> <if test="status != null">
and t.status = 'error' and t.status = 'error'
</if> </if>
where t.id IN where t.id IN
<foreach collection="ids" item="id" separator="," open="(" close=")"> <foreach collection="ids" item="id" separator="," open="(" close=")">
#{id} #{id}
</foreach> </foreach>
ORDER BY t.order DESC ORDER BY t.order DESC
</select> </select>
<select id="selectPlanIds" resultType="java.lang.String"> <select id="selectPlanIds" resultType="java.lang.String">
select DISTINCT test_plan_id from test_plan_api_case; select DISTINCT test_plan_id
</select> from test_plan_api_case;
<select id="getIdsOrderByUpdateTime" resultType="java.lang.String"> </select>
select id from test_plan_api_case where test_plan_id = #{planId} order by update_time ASC; <select id="getIdsOrderByUpdateTime" resultType="java.lang.String">
</select> select id
from test_plan_api_case
where test_plan_id = #{planId}
order by update_time ASC;
</select>
<select id="getLastOrder" resultType="java.lang.Long"> <select id="getLastOrder" resultType="java.lang.Long">
select `order` from test_plan_api_case where test_plan_id = #{planId} select `order` from test_plan_api_case where test_plan_id = #{planId}
<if test="baseOrder != null"> <if test="baseOrder != null">
and `order` &gt; #{baseOrder} and `order` &gt; #{baseOrder}
</if> </if>
order by `order` desc limit 1; order by `order` desc limit 1;
</select> </select>
<select id="getPreOrder" resultType="java.lang.Long"> <select id="getPreOrder" resultType="java.lang.Long">
select `order` from test_plan_api_case where test_plan_id = #{planId} select `order` from test_plan_api_case where test_plan_id = #{planId}
<if test="baseOrder != null"> <if test="baseOrder != null">
and `order` &lt; #{baseOrder} and `order` &lt; #{baseOrder}
</if> </if>
order by `order` desc limit 1; order by `order` desc limit 1;
</select> </select>
<select id="selectByIdsAndStatusIsNotTrash" resultType="io.metersphere.base.domain.TestPlanApiCase">
SELECT
plan.*
FROM
test_plan_api_case plan
INNER JOIN api_test_case api ON plan.api_case_id = api.id
WHERE
(api.`status` is null OR api.`status` != 'Trash') AND plan.test_plan_id IN
<foreach collection="ids" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</select>
<sql id="queryVersionCondition"> <sql id="queryVersionCondition">
<if test="request.versionId != null"> <if test="request.versionId != null">
and ${versionTable}.version_id = #{request.versionId} and ${versionTable}.version_id = #{request.versionId}
</if> </if>
<if test="request.refId != null"> <if test="request.refId != null">
and ${versionTable}.ref_id = #{request.refId} and ${versionTable}.ref_id = #{request.refId}
</if> </if>
</sql> </sql>
</mapper> </mapper>

View File

@ -0,0 +1,12 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.base.domain.TestPlanApiScenario;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtTestPlanApiScenarioMapper {
List<TestPlanApiScenario> selectByIdsAndStatusIsNotTrash(@Param("ids") List<String> ids);
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.ext.ExtTestPlanApiScenarioMapper">
<select id="selectByIdsAndStatusIsNotTrash" resultType="io.metersphere.base.domain.TestPlanApiScenario">
SELECT
plan.*
FROM
test_plan_api_scenario plan
INNER JOIN api_scenario api ON plan.api_scenario_id = api.id
WHERE
(api.`status` is null OR api.`status` != 'Trash') AND plan.test_plan_id IN
<foreach collection="ids" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</select>
</mapper>

View File

@ -35,9 +35,9 @@ import io.metersphere.performance.service.MetricQueryService;
import io.metersphere.performance.service.PerformanceReportService; import io.metersphere.performance.service.PerformanceReportService;
import io.metersphere.performance.service.PerformanceTestService; import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.service.*; import io.metersphere.service.*;
import io.metersphere.track.factory.ReportComponentFactory;
import io.metersphere.track.domain.ReportComponent; import io.metersphere.track.domain.ReportComponent;
import io.metersphere.track.dto.*; import io.metersphere.track.dto.*;
import io.metersphere.track.factory.ReportComponentFactory;
import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest; import io.metersphere.track.request.testcase.PlanCaseRelevanceRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest; import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.AddTestPlanRequest; import io.metersphere.track.request.testplan.AddTestPlanRequest;
@ -184,6 +184,8 @@ public class TestPlanService {
private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper; private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper;
@Resource @Resource
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper; private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
@Resource
private ExtTestPlanApiScenarioMapper extTestPlanApiScenarioMapper;
public synchronized TestPlan addTestPlan(AddTestPlanRequest testPlan) { public synchronized TestPlan addTestPlan(AddTestPlanRequest testPlan) {
if (getTestPlanByName(testPlan.getName()).size() > 0) { if (getTestPlanByName(testPlan.getName()).size() > 0) {
@ -1924,6 +1926,10 @@ public class TestPlanService {
} }
public String runPlan(TestplanRunRequest testplanRunRequest) { public String runPlan(TestplanRunRequest testplanRunRequest) {
//检查是否有可以执行的用例
if (!haveExecCase(testplanRunRequest.getTestPlanId())) {
MSException.throwException(Translator.get("plan_warning"));
}
String envType = testplanRunRequest.getEnvironmentType(); String envType = testplanRunRequest.getEnvironmentType();
Map<String, String> envMap = testplanRunRequest.getEnvMap(); Map<String, String> envMap = testplanRunRequest.getEnvMap();
String environmentGroupId = testplanRunRequest.getEnvironmentGroupId(); String environmentGroupId = testplanRunRequest.getEnvironmentGroupId();
@ -1999,16 +2005,14 @@ public class TestPlanService {
if (StringUtils.isBlank(id)) { if (StringUtils.isBlank(id)) {
return false; return false;
} }
TestPlanApiCaseExample apiCaseExample = new TestPlanApiCaseExample(); List<String> ids = new ArrayList<>();
apiCaseExample.createCriteria().andTestPlanIdEqualTo(id); ids.add(id);
List<TestPlanApiCase> testPlanApiCases = testPlanApiCaseMapper.selectByExample(apiCaseExample); List<TestPlanApiCase> testPlanApiCases = extTestPlanApiCaseMapper.selectByIdsAndStatusIsNotTrash(ids);
if (!CollectionUtils.isEmpty(testPlanApiCases)) { if (!CollectionUtils.isEmpty(testPlanApiCases)) {
return true; return true;
} }
TestPlanApiScenarioExample apiScenarioExample = new TestPlanApiScenarioExample(); List<TestPlanApiScenario> testPlanApiScenarios = extTestPlanApiScenarioMapper.selectByIdsAndStatusIsNotTrash(ids);
apiScenarioExample.createCriteria().andTestPlanIdEqualTo(id);
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExample(apiScenarioExample);
if (!CollectionUtils.isEmpty(testPlanApiScenarios)) { if (!CollectionUtils.isEmpty(testPlanApiScenarios)) {
return true; return true;
} }
@ -2153,6 +2157,7 @@ public class TestPlanService {
Map<String, String> executeQueue = new LinkedHashMap<>(); Map<String, String> executeQueue = new LinkedHashMap<>();
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
StringBuilder haveExecCaseBuilder = new StringBuilder();
for (int i = 0; i < planList.size(); i++) { for (int i = 0; i < planList.size(); i++) {
if (StringUtils.isBlank(planList.get(i).getRunModeConfig())) { if (StringUtils.isBlank(planList.get(i).getRunModeConfig())) {
StringBuilder append = stringBuilder.append("请保存[").append(planList.get(i).getName()).append("]的运行配置"); StringBuilder append = stringBuilder.append("请保存[").append(planList.get(i).getName()).append("]的运行配置");
@ -2160,8 +2165,14 @@ public class TestPlanService {
append.append("/"); append.append("/");
} }
} }
if (!haveExecCase(planList.get(i).getId())) {
haveExecCaseBuilder.append(planList.get(i).getName()).append("; ");
}
} }
if (StringUtils.isNotEmpty(haveExecCaseBuilder)) {
MSException.throwException(Translator.get("track_test_plan") + ": " + haveExecCaseBuilder.toString() + " :" + Translator.get("plan_warning"));
}
if (StringUtils.isNotEmpty(stringBuilder)) { if (StringUtils.isNotEmpty(stringBuilder)) {
MSException.throwException(stringBuilder.toString()); MSException.throwException(stringBuilder.toString());
} }

@ -1 +1 @@
Subproject commit 7f405105bf50af4ae2f1a240059c742f3ac7c729 Subproject commit 830bad0961b3ec2eaff21e9eac382d16f0521639

View File

@ -217,8 +217,8 @@ import_xmind_not_found=Test case not found
license_valid_license_error=Authorization authentication failed license_valid_license_error=Authorization authentication failed
test_review_task_notice=Test review task notice test_review_task_notice=Test review task notice
swagger_url_scheduled_import_notification=SwaggerUrl Scheduled import notification swagger_url_scheduled_import_notification=SwaggerUrl Scheduled import notification
Swagger_parse_error =Swagger parsing failed, please confirm file format is correct! Swagger_parse_error=Swagger parsing failed, please confirm file format is correct!
Swagger_parse_error_with_auth =Swagger parsing failed. Please check whether authentication information is correct or file format is correct! Swagger_parse_error_with_auth=Swagger parsing failed. Please check whether authentication information is correct or file format is correct!
test_track.length_less_than=The title is too long, the length must be less than test_track.length_less_than=The title is too long, the length must be less than
# check owner # check owner
check_owner_project=The current user does not have permission to operate this project check_owner_project=The current user does not have permission to operate this project
@ -388,3 +388,4 @@ cmdExtractElement=element extraction
tcp_mock_not_unique=This tcp port is be used tcp_mock_not_unique=This tcp port is be used
no_tcp_mock_port=No idle tcp port, please contact administrators. no_tcp_mock_port=No idle tcp port, please contact administrators.
name_already_exists_in_module=Name already exists in same module name_already_exists_in_module=Name already exists in same module
plan_warning=There is no associated executable use case under the test plan

View File

@ -387,3 +387,4 @@ cmdExtractElement=提取元素信息
tcp_mock_not_unique=该TCP端口号已被使用 tcp_mock_not_unique=该TCP端口号已被使用
no_tcp_mock_port=无可用的TCP端口号请联系管理员 no_tcp_mock_port=无可用的TCP端口号请联系管理员
name_already_exists_in_module=同层级下已经存在 name_already_exists_in_module=同层级下已经存在
plan_warning=测试计划下没有关联可以执行的用例

View File

@ -386,3 +386,4 @@ cmdExtractElement=提取元素信息
tcp_mock_not_unique=該TCP端口號已被使用 tcp_mock_not_unique=該TCP端口號已被使用
no_tcp_mock_port=無可用的TCP端口號請聯繫管理員 no_tcp_mock_port=無可用的TCP端口號請聯繫管理員
name_already_exists_in_module=同層級下已存在 name_already_exists_in_module=同層級下已存在
plan_warning=測試計劃下沒有關聯可以執行的用例

@ -1 +1 @@
Subproject commit 20b5563776f552ecd1b84bed3bcf50e5cbcaa9b0 Subproject commit 12370ba86adfdf31b11a30d48a59c3715490b351