refactor(接口测试): 用例列表加载接口优化

--bug=1011348 --user=赵勇 【接口测试】-接口定义-case列表查询和执行单接口case变慢了 https://www.tapd.cn/55049933/s/1123873
This commit is contained in:
fit2-zhao 2022-03-22 19:13:42 +08:00 committed by fit2-zhao
parent b7845ffa82
commit 85aa8ab18c
5 changed files with 128 additions and 46 deletions

View File

@ -0,0 +1,9 @@
package io.metersphere.api.dto.definition;
import lombok.Data;
@Data
public class ParamsDTO {
private String id;
private String value;
}

View File

@ -133,10 +133,7 @@ public class ApiTestCaseService {
if (CollectionUtils.isEmpty(apiTestCases)) { if (CollectionUtils.isEmpty(apiTestCases)) {
return apiTestCases; return apiTestCases;
} }
if (BooleanUtils.isTrue(request.isSelectEnvironment())) { buildUserInfo(apiTestCases, request.isSelectEnvironment());
setCaseEnvironment(apiTestCases);
}
buildUserInfo(apiTestCases);
return apiTestCases; return apiTestCases;
} }
@ -202,17 +199,31 @@ public class ApiTestCaseService {
return request; return request;
} }
public void buildUserInfo(List<? extends ApiTestCaseDTO> apiTestCases) { public void buildUserInfo(List<? extends ApiTestCaseDTO> apiTestCases, boolean isSelectEnvironment) {
List<String> userIds = new ArrayList(); List<String> userIds = new ArrayList();
userIds.addAll(apiTestCases.stream().map(ApiTestCaseDTO::getCreateUserId).collect(Collectors.toList())); userIds.addAll(apiTestCases.stream().map(ApiTestCaseDTO::getCreateUserId).collect(Collectors.toList()));
userIds.addAll(apiTestCases.stream().map(ApiTestCaseDTO::getUpdateUserId).collect(Collectors.toList())); userIds.addAll(apiTestCases.stream().map(ApiTestCaseDTO::getUpdateUserId).collect(Collectors.toList()));
List<String> ids = apiTestCases.stream().map(ApiTestCaseDTO::getId).collect(Collectors.toList());
List<ParamsDTO> passRateList = extApiTestCaseMapper.findPassRateByIds(ids);
Map<String, String> passRates = passRateList.stream()
.collect(Collectors.toMap(ParamsDTO::getId, ParamsDTO::getValue));
Map<String, String> envMap = null;
if (BooleanUtils.isTrue(isSelectEnvironment)) {
envMap = this.getApiCaseEnvironments(ids);
}
if (!CollectionUtils.isEmpty(userIds)) { if (!CollectionUtils.isEmpty(userIds)) {
Map<String, User> userMap = userService.queryNameByIds(userIds); Map<String, User> userMap = userService.queryNameByIds(userIds);
Map<String, String> finalEnvMap = envMap;
apiTestCases.forEach(caseResult -> { apiTestCases.forEach(caseResult -> {
caseResult.setPassRate(passRates.get(caseResult.getId()));
User createUser = userMap.get(caseResult.getCreateUserId()); User createUser = userMap.get(caseResult.getCreateUserId());
if (createUser != null) { if (createUser != null) {
caseResult.setCreateUser(createUser.getName()); caseResult.setCreateUser(createUser.getName());
} }
if (finalEnvMap != null && finalEnvMap.containsKey(caseResult.getId())) {
caseResult.setEnvironment(finalEnvMap.get(caseResult.getId()));
}
User updateUser = userMap.get(caseResult.getUpdateUserId()); User updateUser = userMap.get(caseResult.getUpdateUserId());
if (updateUser != null) { if (updateUser != null) {
caseResult.setUpdateUser(updateUser.getName()); caseResult.setUpdateUser(updateUser.getName());
@ -222,7 +233,6 @@ public class ApiTestCaseService {
} }
public ApiTestCaseInfo get(String id) { public ApiTestCaseInfo get(String id) {
// ApiTestCaseWithBLOBs returnBlobs = apiTestCaseMapper.selectByPrimaryKey(id);
ApiTestCaseInfo model = extApiTestCaseMapper.selectApiCaseInfoByPrimaryKey(id); ApiTestCaseInfo model = extApiTestCaseMapper.selectApiCaseInfoByPrimaryKey(id);
if (model != null) { if (model != null) {
if (StringUtils.equalsIgnoreCase(model.getApiMethod(), "esb")) { if (StringUtils.equalsIgnoreCase(model.getApiMethod(), "esb")) {
@ -1051,6 +1061,35 @@ public class ApiTestCaseService {
return null; return null;
} }
public Map<String, String> getApiCaseEnvironments(List<String> caseIds) {
List<ParamsDTO> environments = extApiTestCaseMapper.getApiCaseEnvironments(caseIds);
if (CollectionUtils.isEmpty(environments)) {
return null;
}
try {
List<String> envIds = environments.stream().map(ParamsDTO::getValue).collect(Collectors.toList());
ApiTestEnvironmentExample example = new ApiTestEnvironmentExample();
example.createCriteria().andIdIn(envIds);
List<ApiTestEnvironment> environmentList = apiTestEnvironmentMapper.selectByExample(example);
if (CollectionUtils.isEmpty(environmentList)) {
return null;
}
Map<String, String> envMap = environmentList.stream()
.collect(Collectors.toMap(ApiTestEnvironment::getId, ApiTestEnvironment::getName));
Map<String, String> caseEnvMap = environments.stream().collect(HashMap::new, (m, v) -> m.put(v.getId(), v.getValue()), HashMap::putAll);
caseEnvMap.forEach((k, v) -> {
if (envMap.containsKey(v)) {
caseEnvMap.put(k, envMap.get(v));
}
});
return caseEnvMap;
} catch (Exception e) {
LogUtil.error("api case environmentId incorrect parsing", e);
}
return null;
}
public List<String> getFollows(String testId) { public List<String> getFollows(String testId) {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
if (StringUtils.isBlank(testId)) { if (StringUtils.isBlank(testId)) {

View File

@ -4,7 +4,6 @@ import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.api.dto.definition.*; import io.metersphere.api.dto.definition.*;
import io.metersphere.base.domain.ApiDefinition; import io.metersphere.base.domain.ApiDefinition;
import io.metersphere.base.domain.ApiTestCase; import io.metersphere.base.domain.ApiTestCase;
import io.metersphere.controller.request.BaseQueryRequest;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -16,6 +15,7 @@ public interface ExtApiTestCaseMapper {
List<ApiTestCaseDTO> listSimple(@Param("request") ApiTestCaseRequest request); List<ApiTestCaseDTO> listSimple(@Param("request") ApiTestCaseRequest request);
List<String> selectIdsNotExistsInPlan(@Param("projectId") String projectId, @Param("planId") String planId); List<String> selectIdsNotExistsInPlan(@Param("projectId") String projectId, @Param("planId") String planId);
List<String> selectIdsNotExistsInReview(@Param("projectId") String projectId, @Param("reviewId") String reviewId); List<String> selectIdsNotExistsInReview(@Param("projectId") String projectId, @Param("reviewId") String reviewId);
@ -43,9 +43,10 @@ public interface ExtApiTestCaseMapper {
List<ApiTestCaseDTO> getCannotReductionApiCaseList(@Param("ids") List<String> ids); List<ApiTestCaseDTO> getCannotReductionApiCaseList(@Param("ids") List<String> ids);
List<String> selectCaseIdsByApiIds(@Param("ids")List<String> apiIds); List<String> selectCaseIdsByApiIds(@Param("ids") List<String> apiIds);
List<String> selectNameByIdIn(@Param("ids") List<String> ids);
List<String> selectNameByIdIn(@Param("ids")List<String> ids);
String selectNameById(String id); String selectNameById(String id);
List<String> selectIdsByQuery(@Param("request") ApiTestCaseRequest request); List<String> selectIdsByQuery(@Param("request") ApiTestCaseRequest request);
@ -54,16 +55,21 @@ public interface ExtApiTestCaseMapper {
List<String> getIdsOrderByUpdateTime(@Param("projectId") String projectId); List<String> getIdsOrderByUpdateTime(@Param("projectId") String projectId);
Long getPreOrder(@Param("projectId")String projectId, @Param("baseOrder") Long baseOrder); Long getPreOrder(@Param("projectId") String projectId, @Param("baseOrder") Long baseOrder);
Long getLastOrder(@Param("projectId")String projectId, @Param("baseOrder") Long baseOrder); Long getLastOrder(@Param("projectId") String projectId, @Param("baseOrder") Long baseOrder);
/** /**
* 获取接口用例的环境 * 获取接口用例的环境
*
* @param caseId 用例ID * @param caseId 用例ID
* @return ApiEnvironment * @return ApiEnvironment
*/ */
String getApiCaseEnvironment(@Param("caseId") String caseId); String getApiCaseEnvironment(@Param("caseId") String caseId);
int moduleCount(@Param("request")ApiTestCaseRequest request); int moduleCount(@Param("request") ApiTestCaseRequest request);
List<ParamsDTO> findPassRateByIds(@Param("ids") List<String> ids);
List<ParamsDTO> getApiCaseEnvironments(@Param("caseIds") List<String> caseIds);
} }

View File

@ -312,22 +312,62 @@
</select> </select>
<select id="findPassRateByIds" resultType="io.metersphere.api.dto.definition.ParamsDTO">
SELECT
t2.resource_id as id,
CONCAT(
FORMAT(
SUM(
IF
( t2.`status` = 'success', 1, 0 ))/ COUNT( t2.id )* 100,
2
),
'%'
) value
FROM
api_definition_exec_result t2
WHERE
t2.resource_id IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
GROUP BY
t2.resource_id
</select>
<select id="listSimple" resultType="io.metersphere.api.dto.definition.ApiTestCaseDTO"> <select id="listSimple" resultType="io.metersphere.api.dto.definition.ApiTestCaseDTO">
select SELECT
t1.id, t1.project_id, t1.name,t1.case_status, t1.api_definition_id, t1.priority, t1.description, t1.id,
t1.create_user_id, t1.update_user_id, t1.create_time, t1.update_time, t1.num, t1.project_id,
a.module_id, a.path, a.protocol, t1.tags,t1.status,t3.STATUS AS execResult, t1.last_result_id AS lastResultId , t1.NAME,
project.name as project_name, t1.case_status,
t1.delete_time, deleteUser.name AS deleteUser,CONCAT(FORMAT(SUM(IF t1.api_definition_id,
(t2.`status`='success',1,0))/COUNT(t2.id)*100,2),'%') passRate, project_version.name as version_name t1.priority,
from t1.description,
t1.create_user_id,
t1.update_user_id,
t1.create_time,
t1.update_time,
t1.num,
a.module_id,
a.path,
a.protocol,
t1.tags,
t1.STATUS,
t3.STATUS AS execResult,
t1.last_result_id AS lastResultId,
project.NAME AS project_name,
t1.delete_time,
deleteUser.NAME AS deleteUser,
project_version.NAME AS version_name
FROM
api_test_case t1 api_test_case t1
LEFT JOIN api_definition_exec_result t2 ON t1.id = t2.resource_id
LEFT JOIN api_definition_exec_result t3 ON t1.last_result_id = t3.id LEFT JOIN api_definition_exec_result t3 ON t1.last_result_id = t3.id
LEFT JOIN user deleteUser ON t1.delete_user_id = deleteUser.id LEFT JOIN USER deleteUser ON t1.delete_user_id = deleteUser.id
LEFT JOIN api_definition a on t1.api_definition_id = a.id LEFT JOIN api_definition a ON t1.api_definition_id = a.id
LEFT JOIN project ON t1.project_id = project.id LEFT JOIN project ON t1.project_id = project.id
LEFT JOIN project_version on project.id = project_version.project_id AND project_version.id = t1.version_id LEFT JOIN project_version ON project.id = project_version.project_id
AND project_version.id = t1.version_id
WHERE 1=1 WHERE 1=1
<if test="request.protocol != null and request.protocol!=''"> <if test="request.protocol != null and request.protocol!=''">
and a.protocol = #{request.protocol} and a.protocol = #{request.protocol}
@ -421,29 +461,11 @@
and (t1.status is null or t1.status != 'Trash') and (t1.status is null or t1.status != 'Trash')
</if> </if>
<if test="request.toUpdate !=null and request.toUpdate == true"> <if test="request.toUpdate !=null and request.toUpdate == true">
and (t1.update_time >= #{request.updateTime} or t2.status = 'error') and (t1.update_time >= #{request.updateTime} or t3.status = 'error')
</if> </if>
<include refid="queryVersionCondition"> <include refid="queryVersionCondition">
<property name="versionTable" value="t1"/> <property name="versionTable" value="t1"/>
</include> </include>
GROUP BY t1.id,
t1.project_id,
t1.name,
t1.api_definition_id,
t1.priority,
t1.description,
t1.create_user_id,
t1.update_user_id,
t1.create_time,
t1.update_time,
t1.num,
a.module_id,
a.path,
a.protocol,
t1.tags,
t1.status,
t1.`order`
having 1=1
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/> <include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select> </select>
<select id="idSimple" resultType="java.lang.String"> <select id="idSimple" resultType="java.lang.String">
@ -643,7 +665,7 @@
WHERE testCase.id = #{0} WHERE testCase.id = #{0}
</select> </select>
<sql id="queryWhereCondition"> <sql id="queryWhereCondition">
<where> <where>
<if test="request.name != null and request.name!=''"> <if test="request.name != null and request.name!=''">
and t1.name like CONCAT('%', #{request.name},'%') and t1.name like CONCAT('%', #{request.name},'%')
@ -751,6 +773,12 @@
</if> </if>
order by `order` desc limit 1; order by `order` desc limit 1;
</select> </select>
<select id="getApiCaseEnvironments" resultType="io.metersphere.api.dto.definition.ParamsDTO">
select id,JSON_UNQUOTE(JSON_EXTRACT(request, '$.useEnvironment')) as value from api_test_case where id in
<foreach collection="caseIds" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
<select id="getApiCaseEnvironment" resultType="java.lang.String"> <select id="getApiCaseEnvironment" resultType="java.lang.String">
select JSON_UNQUOTE(JSON_EXTRACT(request, '$.useEnvironment')) from api_test_case where id = #{caseId} select JSON_UNQUOTE(JSON_EXTRACT(request, '$.useEnvironment')) from api_test_case where id = #{caseId}
</select> </select>

View File

@ -42,7 +42,7 @@ public class TestCaseReviewApiCaseService {
if (CollectionUtils.isEmpty(apiTestCases)) { if (CollectionUtils.isEmpty(apiTestCases)) {
return apiTestCases; return apiTestCases;
} }
apiTestCaseService.buildUserInfo(apiTestCases); apiTestCaseService.buildUserInfo(apiTestCases, request.isSelectEnvironment());
return apiTestCases; return apiTestCases;
} }
public List<String> getExecResultByReviewId(String reviewId) { public List<String> getExecResultByReviewId(String reviewId) {