fix(接口测试): 修复接口测试首页场景面板的接口覆盖率统计不对的问题

修复接口测试首页场景面板的接口覆盖率统计不对的问题
This commit is contained in:
song-tianyang 2022-04-12 14:02:08 +08:00 committed by 刘瑞斌
parent 3a094212de
commit c8fa84042e
13 changed files with 59 additions and 151 deletions

View File

@ -294,11 +294,10 @@ public class APITestController {
* 接口覆盖率
* 复制的接口定义/复制或引用的单接口用例/ 添加的自定义请求 url 路径与现有的接口定义一致的请求
*/
List<ApiScenarioWithBLOBs> allScenarioInfoList = apiAutomationService.selectIdAndUseUrlByProjectId(projectId);
List<String> allScenarioIdList = apiAutomationService.selectIdsByProjectId(projectId);
List<ApiDefinition> allEffectiveApiIdList = apiDefinitionService.selectEffectiveIdByProjectId(projectId);
// List<ApiTestCase> allEffectiveApiCaseList = apiTestCaseService.selectEffectiveTestCaseByProjectId(projectId);
try {
float intetfaceCoverageRageNumber = apiAutomationService.countInterfaceCoverage(allScenarioInfoList, allEffectiveApiIdList);
float intetfaceCoverageRageNumber = apiAutomationService.countInterfaceCoverage(allScenarioIdList, allEffectiveApiIdList);
DecimalFormat df = new DecimalFormat("0.0");
returnStr = df.format(intetfaceCoverageRageNumber) + "%";
}catch (Exception e){

View File

@ -247,8 +247,6 @@ public class ApiAutomationService {
scenario.setCreateTime(System.currentTimeMillis());
scenario.setNum(nextNum);
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenario);
scenario.setUseUrl(JSONArray.toJSONString(useUrl));
scenario.setOrder(ServiceUtils.getNextOrder(scenario.getProjectId(), extApiScenarioMapper::getLastOrder));
scenario.setRefId(request.getId());
scenario.setLatest(true);
@ -359,8 +357,6 @@ public class ApiAutomationService {
}
deleteUpdateBodyFile(scenario, beforeScenario);
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenario);
scenario.setUseUrl(JSONArray.toJSONString(useUrl));
scenario.setCreateUser(null); // 更新时不更新创建人
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andIdEqualTo(scenario.getId()).andVersionIdEqualTo(request.getVersionId());
@ -922,8 +918,8 @@ public class ApiAutomationService {
return extApiScenarioMapper.countByProjectID(projectId);
}
public List<ApiScenarioWithBLOBs> selectIdAndUseUrlByProjectId(String projectId) {
return extApiScenarioMapper.selectIdAndUseUrlByProjectId(projectId);
public List<String> selectIdsByProjectId(String projectId) {
return extApiScenarioMapper.selectIdsByProjectId(projectId);
}
public long countScenarioByProjectIDAndCreatInThisWeek(String projectId) {
@ -1082,10 +1078,6 @@ public class ApiAutomationService {
ApiScenarioWithBLOBs apiScenarioWithBLOBs = new ApiScenarioWithBLOBs();
BeanUtils.copyBean(apiScenarioWithBLOBs, request);
apiScenarioWithBLOBs.setUpdateTime(System.currentTimeMillis());
if (apiScenarioWithBLOBs.getScenarioDefinition() != null) {
List<ApiMethodUrlDTO> useUrl = this.parseUrl(apiScenarioWithBLOBs);
apiScenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
}
apiScenarioMapper.updateByExampleSelective(
apiScenarioWithBLOBs,
apiScenarioExample);
@ -1127,8 +1119,6 @@ public class ApiAutomationService {
ApiScenarioWithBLOBs scenarioWithBLOBs, ApiTestImportRequest apiTestImportRequest, ApiTestCaseMapper apiTestCaseMapper, ApiDefinitionMapper apiDefinitionMapper) {
if (CollectionUtils.isEmpty(sameRequest)) {
scenarioWithBLOBs.setId(UUID.randomUUID().toString());
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs);
scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
scenarioWithBLOBs.setOrder(getImportNextOrder(apiTestImportRequest.getProjectId()));
// 导入时设置版本
scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId());
@ -1165,8 +1155,6 @@ public class ApiAutomationService {
scenarioWithBLOBs.setVersionId(apiTestImportRequest.getUpdateVersionId());
scenarioWithBLOBs.setOrder(existScenario.getOrder());
scenarioWithBLOBs.setNum(existScenario.getNum());
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs);
scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
batchMapper.updateByPrimaryKeyWithBLOBs(scenarioWithBLOBs);
}
checkReferenceCase(scenarioWithBLOBs, apiTestCaseMapper, apiDefinitionMapper);
@ -1229,8 +1217,6 @@ public class ApiAutomationService {
_importCreate(sameRequest, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest, apiTestCaseMapper, apiDefinitionMapper);
} else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
if (CollectionUtils.isEmpty(sameRequest)) {
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenarioWithBLOBs);
scenarioWithBLOBs.setUseUrl(JSONArray.toJSONString(useUrl));
scenarioWithBLOBs.setOrder(getImportNextOrder(request.getProjectId()));
scenarioWithBLOBs.setId(UUID.randomUUID().toString());
scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId());
@ -1555,86 +1541,27 @@ public class ApiAutomationService {
* <p>
* 匹配场景中用到的路径
*
* @param allScenarioInfoList 场景集合id / scenario大字段 必须有数据
* @param scenarioIdList 场景集合id / scenario大字段 必须有数据
* @param allEffectiveApiList 接口集合id / path 必须有数据
* @return
*/
public float countInterfaceCoverage(List<ApiScenarioWithBLOBs> allScenarioInfoList, List<ApiDefinition> allEffectiveApiList) {
if (allEffectiveApiList == null || allEffectiveApiList.isEmpty()) {
public float countInterfaceCoverage(List<String> scenarioIdList, List<ApiDefinition> allEffectiveApiList) {
if (CollectionUtils.isEmpty(scenarioIdList) || CollectionUtils.isEmpty(allEffectiveApiList)) {
return 0;
}
List<String> refIdList = apiScenarioReferenceIdService.findByScenarioIds(scenarioIdList);
Map<ApiMethodUrlDTO, List<String>> urlMap = new HashMap<>();
int containsCount = 0;
for (ApiDefinition model : allEffectiveApiList) {
String url = model.getPath();
String method = model.getMethod();
String id = model.getId();
ApiMethodUrlDTO dto = new ApiMethodUrlDTO(url, method);
if (urlMap.containsKey(dto)) {
urlMap.get(dto).add(id);
} else {
List<String> list = new ArrayList<>();
list.add(id);
urlMap.put(dto, list);
if(refIdList.contains(model.getId())){
containsCount ++;
}
}
if (urlMap.isEmpty()) {
return 100;
}
List<ApiMethodUrlDTO> urlList = new ArrayList<>();
for (ApiScenarioWithBLOBs model : allScenarioInfoList) {
List<ApiMethodUrlDTO> useUrl = this.getScenarioUseUrl(model);
if (CollectionUtils.isNotEmpty(useUrl)) {
for (ApiMethodUrlDTO dto : useUrl) {
if (!urlList.contains(dto)) {
urlList.add(dto);
}
}
}
}
List<String> containsApiIdList = new ArrayList<>();
for (ApiMethodUrlDTO urlDTO : urlList) {
List<String> apiIdList = urlMap.get(urlDTO);
if (apiIdList != null) {
for (String api : apiIdList) {
if (!containsApiIdList.contains(api)) {
containsApiIdList.add(api);
}
}
}
}
int allApiIdCount = 0;
for (List<String> allApiIdList : urlMap.values()) {
if (CollectionUtils.isNotEmpty(allApiIdList)) {
allApiIdCount += allApiIdList.size();
}
}
float coverageRageNumber = (float) containsApiIdList.size() * 100 / allApiIdCount;
float coverageRageNumber = (float) containsCount * 100 / allEffectiveApiList.size();
return coverageRageNumber;
}
private List<ApiMethodUrlDTO> getScenarioUseUrl(ApiScenarioWithBLOBs model) {
List<ApiMethodUrlDTO> useUrlList = new ArrayList<>();
try {
useUrlList = JSONArray.parseArray(model.getUseUrl(), ApiMethodUrlDTO.class);
} catch (Exception e) {
}
return useUrlList;
}
public List<ApiMethodUrlDTO> parseUrl(ApiScenarioWithBLOBs scenario) {
List<ApiMethodUrlDTO> urlList = new ArrayList<>();
// 去除未生效且影响性能的方法
return urlList;
}
public ScenarioEnv getApiScenarioProjectId(String id) {
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(id);
ScenarioEnv scenarioEnv = new ScenarioEnv();
@ -1734,23 +1661,6 @@ public class ApiAutomationService {
return null;
}
public void checkApiScenarioUseUrl() {
List<String> noUrlScenarioIdList = extApiScenarioMapper.selectIdsByUseUrlIsNull();
for (String id : noUrlScenarioIdList) {
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(id);
if (scenario.getUseUrl() == null) {
List<ApiMethodUrlDTO> useUrl = this.parseUrl(scenario);
if (useUrl != null) {
ApiScenarioWithBLOBs updateModel = new ApiScenarioWithBLOBs();
updateModel.setId(scenario.getId());
updateModel.setUseUrl(JSONArray.toJSONString(useUrl));
apiScenarioMapper.updateByPrimaryKeySelective(updateModel);
apiScenarioReferenceIdService.saveApiAndScenarioRelation(updateModel);
}
}
}
}
public void checkApiScenarioReferenceId() {
List<ApiScenarioWithBLOBs> scenarioNoRefs = extApiScenarioMapper.selectByNoReferenceId();
for (ApiScenarioWithBLOBs model : scenarioNoRefs) {

View File

@ -7,6 +7,7 @@ import io.metersphere.base.domain.ApiScenarioReferenceId;
import io.metersphere.base.domain.ApiScenarioReferenceIdExample;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.mapper.ApiScenarioReferenceIdMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioReferenceIdMapper;
import io.metersphere.commons.utils.SessionUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
@ -31,6 +32,8 @@ public class ApiScenarioReferenceIdService {
@Resource
private ApiScenarioReferenceIdMapper apiScenarioReferenceIdMapper;
@Resource
private ExtApiScenarioReferenceIdMapper extApiScenarioReferenceIdMapper;
@Resource
private SqlSessionFactory sqlSessionFactory;
public List<ApiScenarioReferenceId> findByReferenceIds(List<String> deleteIds) {
@ -134,4 +137,12 @@ public class ApiScenarioReferenceIdService {
return apiScenarioReferenceIdMapper.selectByExample(example);
}
}
public List<String> findByScenarioIds(List<String> scenarioIdList) {
if(CollectionUtils.isEmpty(scenarioIdList)){
return new ArrayList<>();
}else {
return extApiScenarioReferenceIdMapper.selectRefIdsFromScenarioIds(scenarioIdList);
}
}
}

View File

@ -368,8 +368,6 @@ public class HistoricalDataUpgradeService {
scenario.setUpdateTime(System.currentTimeMillis());
scenario.setStatus(ScenarioStatus.Underway.name());
scenario.setUserId(SessionUtils.getUserId());
List<ApiMethodUrlDTO> useUrl = apiAutomationService.parseUrl(scenario);
scenario.setUseUrl(JSONArray.toJSONString(useUrl));
mapper.updateByPrimaryKeySelective(scenario);
apiScenarioReferenceIdService.saveApiAndScenarioRelation(scenario);
} else {
@ -389,8 +387,6 @@ public class HistoricalDataUpgradeService {
scenario.setStatus(ScenarioStatus.Underway.name());
scenario.setUserId(SessionUtils.getUserId());
scenario.setNum(num);
List<ApiMethodUrlDTO> useUrl = apiAutomationService.parseUrl(scenario);
scenario.setUseUrl(JSONArray.toJSONString(useUrl));
mapper.insert(scenario);
apiScenarioReferenceIdService.saveApiAndScenarioRelation(scenario);
}

View File

@ -1,8 +1,7 @@
package io.metersphere.base.domain;
import lombok.Data;
import java.io.Serializable;
import lombok.Data;
@Data
public class ApiScenario implements Serializable {

View File

@ -13,8 +13,6 @@ public class ApiScenarioWithBLOBs extends ApiScenario implements Serializable {
private String description;
private String useUrl;
private String environmentJson;
private static final long serialVersionUID = 1L;

View File

@ -37,7 +37,6 @@
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiScenarioWithBLOBs">
<result column="scenario_definition" jdbcType="LONGVARCHAR" property="scenarioDefinition" />
<result column="description" jdbcType="LONGVARCHAR" property="description" />
<result column="use_url" jdbcType="LONGVARCHAR" property="useUrl" />
<result column="environment_json" jdbcType="LONGVARCHAR" property="environmentJson" />
</resultMap>
<sql id="Example_Where_Clause">
@ -106,7 +105,7 @@
latest
</sql>
<sql id="Blob_Column_List">
scenario_definition, description, use_url, environment_json
scenario_definition, description, environment_json
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.ApiScenarioExample" resultMap="ResultMapWithBLOBs">
select
@ -157,7 +156,7 @@
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
INSERT INTO api_scenario (id, project_id, tags,
insert into api_scenario (id, project_id, tags,
user_id, api_scenario_module_id, module_path,
`name`, `level`, `status`,
principal, step_total, schedule,
@ -168,8 +167,8 @@
execute_times, `order`, environment_type,
environment_group_id, version_id, ref_id,
latest, scenario_definition, description,
use_url, environment_json)
VALUES (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{tags,jdbcType=VARCHAR},
environment_json)
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{tags,jdbcType=VARCHAR},
#{userId,jdbcType=VARCHAR}, #{apiScenarioModuleId,jdbcType=VARCHAR}, #{modulePath,jdbcType=VARCHAR},
#{name,jdbcType=VARCHAR}, #{level,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
#{principal,jdbcType=VARCHAR}, #{stepTotal,jdbcType=INTEGER}, #{schedule,jdbcType=VARCHAR},
@ -180,7 +179,7 @@
#{executeTimes,jdbcType=INTEGER}, #{order,jdbcType=BIGINT}, #{environmentType,jdbcType=VARCHAR},
#{environmentGroupId,jdbcType=VARCHAR}, #{versionId,jdbcType=VARCHAR}, #{refId,jdbcType=VARCHAR},
#{latest,jdbcType=BIT}, #{scenarioDefinition,jdbcType=LONGVARCHAR}, #{description,jdbcType=LONGVARCHAR},
#{useUrl,jdbcType=LONGVARCHAR}, #{environmentJson,jdbcType=LONGVARCHAR})
#{environmentJson,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
insert into api_scenario
@ -284,9 +283,6 @@
<if test="description != null">
description,
</if>
<if test="useUrl != null">
use_url,
</if>
<if test="environmentJson != null">
environment_json,
</if>
@ -391,9 +387,6 @@
<if test="description != null">
#{description,jdbcType=LONGVARCHAR},
</if>
<if test="useUrl != null">
#{useUrl,jdbcType=LONGVARCHAR},
</if>
<if test="environmentJson != null">
#{environmentJson,jdbcType=LONGVARCHAR},
</if>
@ -507,9 +500,6 @@
<if test="record.description != null">
description = #{record.description,jdbcType=LONGVARCHAR},
</if>
<if test="record.useUrl != null">
use_url = #{record.useUrl,jdbcType=LONGVARCHAR},
</if>
<if test="record.environmentJson != null">
environment_json = #{record.environmentJson,jdbcType=LONGVARCHAR},
</if>
@ -553,7 +543,6 @@
latest = #{record.latest,jdbcType=BIT},
scenario_definition = #{record.scenarioDefinition,jdbcType=LONGVARCHAR},
description = #{record.description,jdbcType=LONGVARCHAR},
use_url = #{record.useUrl,jdbcType=LONGVARCHAR},
environment_json = #{record.environmentJson,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -695,9 +684,6 @@
<if test="description != null">
description = #{description,jdbcType=LONGVARCHAR},
</if>
<if test="useUrl != null">
use_url = #{useUrl,jdbcType=LONGVARCHAR},
</if>
<if test="environmentJson != null">
environment_json = #{environmentJson,jdbcType=LONGVARCHAR},
</if>
@ -738,7 +724,6 @@
latest = #{latest,jdbcType=BIT},
scenario_definition = #{scenarioDefinition,jdbcType=LONGVARCHAR},
description = #{description,jdbcType=LONGVARCHAR},
use_url = #{useUrl,jdbcType=LONGVARCHAR},
environment_json = #{environmentJson,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>

View File

@ -31,20 +31,12 @@ public interface ExtApiScenarioMapper {
List<ApiScenario> selectReference(@Param("request") ApiScenarioRequest request);
// int removeToGc(@Param("ids") List<String> ids);
// int removeToGc(ApiScenarioRequest request);
int removeToGcByExample(ApiScenarioExampleWithOperation example);
int reduction(@Param("ids") List<String> ids);
long countByProjectID(String projectId);
List<ApiScenarioWithBLOBs> selectIdAndScenarioByProjectId(String projectId);
List<ApiScenarioWithBLOBs> selectIdAndUseUrlByProjectId(String projectId);
long countByProjectIDAndCreatInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
List<ApiDataCountResult> countRunResultByProjectID(String projectId);
@ -55,14 +47,14 @@ public interface ExtApiScenarioMapper {
List<String> selectIdsByQuery(@Param("request") BaseQueryRequest request);
List<String> selectIdsByProjectId(String projectId);
void updateCustomNumByProjectId(@Param("projectId") String projectId);
List<ApiScenarioWithBLOBs> listWithIds(@Param("ids") List<String> ids);
List<Map<String, Object>> listModuleByCollection(@Param("request") ApiScenarioRequest request);
List<String> selectIdsByUseUrlIsNull();
String selectNameById(String id);
List<String> selectNameByIdIn(@Param("ids") List<String> id);

View File

@ -424,9 +424,6 @@
<select id="selectIdAndScenarioByProjectId" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
SELECT id,scenario_definition FROM api_scenario WHERE project_id = #{0} AND status != 'Trash'
</select>
<select id="selectIdAndUseUrlByProjectId" resultType="io.metersphere.base.domain.ApiScenarioWithBLOBs">
SELECT id,use_url FROM api_scenario WHERE project_id = #{0} AND status != 'Trash' AND latest = 1
</select>
<select id="countByProjectIDAndCreatInThisWeek" resultType="java.lang.Long">
SELECT count(id) AS countNumber FROM api_scenario
WHERE project_id = #{projectId} AND status != 'Trash' and latest = 1
@ -458,6 +455,10 @@
left join project on api_scenario.project_id = project.id
<include refid="queryWhereCondition"/>
</select>
<select id="selectIdsByProjectId" resultType="java.lang.String">
select id from api_scenario WHERE project_id = #{0} AND status != 'Trash'
</select>
<select id="listReview" resultMap="BaseResultMap">
select api_scenario.id, api_scenario.project_id, api_scenario.tags, api_scenario.user_id, api_scenario.num,
api_scenario.api_scenario_module_id,api_scenario.module_path, api_scenario.name, api_scenario.level,
@ -472,11 +473,6 @@
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select>
<select id="selectIdsByUseUrlIsNull" resultType="java.lang.String">
select id
from api_scenario
WHERE use_url IS NULL
</select>
<select id="selectTrash" resultType="java.lang.Integer">
select count(DISTINCT ref_id)
from api_scenario

View File

@ -0,0 +1,9 @@
package io.metersphere.base.mapper.ext;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtApiScenarioReferenceIdMapper {
List<String> selectRefIdsFromScenarioIds(@Param("ids") List<String> scenarioIds);
}

View File

@ -0,0 +1,11 @@
<?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.ExtApiScenarioReferenceIdMapper">
<select id="selectRefIdsFromScenarioIds" resultType="java.lang.String">
select reference_id from api_scenario_reference_id
where api_scenario_id IN
<foreach collection="ids" item="v" separator="," open="(" close=")">
#{v}
</foreach>
</select>
</mapper>

View File

@ -137,7 +137,6 @@ public class AppStartListener implements ApplicationListener<ApplicationReadyEve
}
private void initOnceOperate() {
initOnceOperate(apiAutomationService::checkApiScenarioUseUrl, "init.scenario.url");
initOnceOperate(apiAutomationService::checkApiScenarioReferenceId, "init.scenario.referenceId");
initOnceOperate(apiAutomationService::initExecuteTimes, "init.scenario.executeTimes");
initOnceOperate(issuesService::syncThirdPartyIssues, "init.issue");

View File

@ -211,4 +211,7 @@ INSERT INTO user_group_permission (id, group_id, permission_id, module_id)
VALUES (UUID(), 'ws_admin', 'WORKSPACE_QUOTA:READ', 'WORKSPACE_QUOTA') ;
INSERT INTO user_group_permission (id, group_id, permission_id, module_id)
VALUES (UUID(), 'ws_admin', 'WORKSPACE_QUOTA:READ+EDIT', 'WORKSPACE_QUOTA');
VALUES (UUID(), 'ws_admin', 'WORKSPACE_QUOTA:READ+EDIT', 'WORKSPACE_QUOTA');
-- 删除场景冗余字段
ALTER TABLE api_scenario DROP COLUMN use_url;