feat(接口测试): 接口测试首页执行统计增加按照版本筛选的功能

接口测试首页执行统计增加按照版本筛选的功能(暂时保留,因为还有一些使用细节需要确认)
This commit is contained in:
song-tianyang 2022-11-15 15:35:51 +08:00 committed by 建国
parent d1709c8a5a
commit abafe7ee38
19 changed files with 131 additions and 98 deletions

View File

@ -1,11 +1,11 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.dto.PlanReportCaseDTO;
import io.metersphere.api.dto.QueryAPIReportRequest;
import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.base.domain.ApiDefinitionExecResultExpand;
import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs;
import io.metersphere.dto.PlanReportCaseDTO;
import io.metersphere.task.dto.TaskCenterRequest;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
@ -24,7 +24,7 @@ public interface ExtApiDefinitionExecResultMapper {
ApiDefinitionExecResultWithBLOBs selectMaxResultByResourceIdAndType(String resourceId, String type);
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("version") String version, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
long countByTestCaseIDInProject(String projectId);

View File

@ -31,6 +31,9 @@
FROM api_test_case testCase
WHERE testCase.project_id = #{projectId}
)
<if test="version != null">
AND version = #{version}
</if>
AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
</select>

View File

@ -1,11 +1,11 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.dto.PlanReportCaseDTO;
import io.metersphere.api.dto.QueryAPIReportRequest;
import io.metersphere.api.dto.automation.ApiScenarioReportResult;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.base.domain.ApiScenarioReport;
import io.metersphere.dto.ApiReportCountDTO;
import io.metersphere.dto.PlanReportCaseDTO;
import io.metersphere.task.dto.TaskCenterRequest;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
@ -20,11 +20,11 @@ public interface ExtApiScenarioReportMapper {
long countByProjectID(String projectId);
long countByProjectIdAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
long countByProjectIdAndCreateInThisWeek(@Param("projectId") String projectId, @Param("version") String version, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
long countByProjectIdAndCreateAndByScheduleInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
long countByProjectIdAndCreateAndByScheduleInThisWeek(@Param("projectId") String projectId, @Param("version") String version, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(String projectId);
List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(@Param("projectId") String projectId, @Param("version") String version);
List<ApiScenarioReport> selectLastReportByIds(@Param("scenarioIdList") List<String> ids);

View File

@ -358,41 +358,37 @@
SELECT count(id) AS countNumber
FROM scenario_execution_info
WHERE create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
AND (
source_id in (
SELECT id
FROM api_scenario
WHERE project_id = #{projectId}
) or
source_id in (
select id
FROM test_plan_api_scenario
WHERE api_scenario_id in (SELECT id
FROM api_scenario
WHERE project_id = #{projectId})
)
)
AND project_id = #{projectId}
<if test="version != null">
AND version = #{version}
</if>
</select>
<select id="countByProjectIdAndCreateAndByScheduleInThisWeek" resultType="java.lang.Long">
SELECT count(ar.id) AS countNumber
FROM scenario_execution_info ar
SELECT count(id) AS countNumber
FROM scenario_execution_info
WHERE trigger_mode = 'SCHEDULE'
AND source_id IN (SELECT id
FROM api_scenario
WHERE project_id = #{projectId}
AND latest = 1)
<if test="version != null">
AND version = #{version}
</if>
AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
</select>
<select id="countByProjectIdGroupByExecuteResult" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
SELECT count(id) AS countNumber, result AS groupField
FROM scenario_execution_info ar
FROM scenario_execution_info
WHERE trigger_mode = 'SCHEDULE'
AND source_id IN (SELECT id
FROM api_scenario
WHERE project_id = #{projectId}
AND latest = 1)
<if test="version != null">
AND version = #{version}
</if>
GROUP BY groupField;
</select>
<select id="selectLastReportByIds" resultType="io.metersphere.base.domain.ApiScenarioReport">

View File

@ -48,6 +48,7 @@ public class ApiHomeController {
@GetMapping("/api/count/{projectId}")
public ApiDataCountDTO apiCount(@PathVariable String projectId) {
ApiDataCountDTO apiCountResult = new ApiDataCountDTO();
List<ApiDataCountResult> countResultByProtocolList = apiDefinitionService.countProtocolByProjectID(projectId);
apiCountResult.countProtocol(countResultByProtocolList);
@ -96,9 +97,9 @@ public class ApiHomeController {
//本周创建本周执行总执行
long dateCountByCreateInThisWeek = apiTestCaseService.countByProjectIDAndCreateInThisWeek(projectId);
apiCountResult.setCreatedInWeek(dateCountByCreateInThisWeek);
long executedInThisWeekCountNumber = apiDefinitionExecResultService.countByTestCaseIDInProjectAndExecutedInThisWeek(projectId);
long executedInThisWeekCountNumber = apiDefinitionExecResultService.countByTestCaseIDInProjectAndExecutedInThisWeek(projectId, null);
apiCountResult.setExecutedTimesInWeek(executedInThisWeekCountNumber);
long executedCount = apiTestCaseService.countExecutedTimesByProjectId(projectId, ExecutionExecuteTypeEnum.BASIC.name());
long executedCount = apiTestCaseService.countExecutedTimesByProjectId(projectId, ExecutionExecuteTypeEnum.BASIC.name(), null);
apiCountResult.setExecutedTimes(executedCount);
//未覆盖 已覆盖 统计当前接口下是否含有案例
List<ApiDataCountResult> countResultByApiCoverageList = apiDefinitionService.countApiCoverageByProjectID(projectId);
@ -136,10 +137,10 @@ public class ApiHomeController {
//统计覆盖率
long dateCountByCreateInThisWeek = apiAutomationService.countScenarioByProjectIDAndCreatInThisWeek(projectId);
apiCountResult.setCreatedInWeek(dateCountByCreateInThisWeek);
long executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIdAndCreateInThisWeek(projectId);
long executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIdAndCreateInThisWeek(projectId, null);
apiCountResult.setExecutedTimesInWeek(executedInThisWeekCountNumber);
//所有执行次数
long executedTimes = apiAutomationService.countExecuteTimesByProjectID(projectId, null);
long executedTimes = apiAutomationService.countExecuteTimesByProjectID(projectId, null, null);
apiCountResult.setExecutedTimes(executedTimes);
//未执行未通过已通过
List<ApiDataCountResult> countResultByRunResult = apiAutomationService.countRunResultByProjectID(projectId);
@ -172,6 +173,7 @@ public class ApiHomeController {
@GetMapping("/schedule/task/count/{projectId}")
public ApiDataCountDTO scheduleTaskCount(@PathVariable String projectId) {
List<Schedule> allScenarioScheduleList = baseScheduleService.selectScenarioTaskByProjectId(projectId);
ApiDataCountDTO apiCountResult = new ApiDataCountDTO();
@ -179,12 +181,12 @@ public class ApiHomeController {
apiCountResult.setTotal(allTaskCount);
long taskCountInThisWeek = baseScheduleService.countTaskByProjectIdInThisWeek(projectId);
apiCountResult.setCreatedInWeek(taskCountInThisWeek);
long executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIdAndCreateAndByScheduleInThisWeek(projectId);
long executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIdAndCreateAndByScheduleInThisWeek(projectId, null);
apiCountResult.setExecutedTimesInWeek(executedInThisWeekCountNumber);
long executedTimes = apiAutomationService.countExecuteTimesByProjectID(projectId, ReportTriggerMode.SCHEDULE.name());
long executedTimes = apiAutomationService.countExecuteTimesByProjectID(projectId, ReportTriggerMode.SCHEDULE.name(), null);
apiCountResult.setExecutedTimes(executedTimes);
//统计 失败 成功 以及总数
List<ApiDataCountResult> allExecuteResult = apiScenarioReportService.countByProjectIdGroupByExecuteResult(projectId);
List<ApiDataCountResult> allExecuteResult = apiScenarioReportService.countByProjectIdGroupByExecuteResult(projectId, null);
apiCountResult.countScheduleExecute(allExecuteResult);
if (executedTimes != 0) {
float passRateNumber = (float) apiCountResult.getPassCount() * 100 / executedTimes;

View File

@ -46,9 +46,13 @@ public class ApiCaseExecutionInfoService {
}
}
public long countExecutedTimesByProjectId(String projectId, String executeType) {
public long countExecutedTimesByProjectIdAndVersion(String projectId, String executeType, String version) {
ApiCaseExecutionInfoExample example = new ApiCaseExecutionInfoExample();
example.createCriteria().andProjectIdEqualTo(projectId).andExecuteTypeEqualTo(executeType);
ApiCaseExecutionInfoExample.Criteria criteria = example.createCriteria();
criteria.andProjectIdEqualTo(projectId).andExecuteTypeEqualTo(executeType);
if (StringUtils.isNotEmpty(version)) {
criteria.andVersionEqualTo(version);
}
return apiCaseExecutionInfoMapper.countByExample(example);
}

View File

@ -343,13 +343,13 @@ public class ApiDefinitionExecResultService {
apiDefinitionExecResultMapper.deleteByExample(example);
}
public long countByTestCaseIDInProjectAndExecutedInThisWeek(String projectId) {
public long countByTestCaseIDInProjectAndExecutedInThisWeek(String projectId, String version) {
Date firstTime = DateUtils.getWeedFirstTimeAndLastTime(new Date()).get("firstTime");
Date lastTime = DateUtils.getWeedFirstTimeAndLastTime(new Date()).get("lastTime");
if (firstTime == null || lastTime == null) {
return 0;
} else {
return extApiDefinitionExecResultMapper.countByProjectIDAndCreateInThisWeek(projectId, firstTime.getTime(), lastTime.getTime());
return extApiDefinitionExecResultMapper.countByProjectIDAndCreateInThisWeek(projectId, version, firstTime.getTime(), lastTime.getTime());
}
}

View File

@ -1240,8 +1240,8 @@ public class ApiTestCaseService {
return extApiTestCaseMapper.getCaseCountById(id);
}
public long countExecutedTimesByProjectId(String projectId, String executeType) {
return apiCaseExecutionInfoService.countExecutedTimesByProjectId(projectId, executeType);
public long countExecutedTimesByProjectId(String projectId, String executeType, String version) {
return apiCaseExecutionInfoService.countExecutedTimesByProjectIdAndVersion(projectId, executeType, version);
}
@Async

View File

@ -91,13 +91,16 @@ public class ApiScenarioExecutionInfoService {
scenarioExecutionInfoMapper.deleteByExample(example);
}
public long countExecuteTimesByProjectID(String projectId, String triggerMode) {
public long countExecuteTimesByProjectID(String projectId, String triggerMode, String version) {
ScenarioExecutionInfoExample example = new ScenarioExecutionInfoExample();
ScenarioExecutionInfoExample.Criteria criteria = example.createCriteria();
criteria.andProjectIdEqualTo(projectId);
if (StringUtils.isNotEmpty(triggerMode)) {
criteria.andTriggerModeEqualTo(triggerMode);
}
if (StringUtils.isNotEmpty(version)) {
criteria.andVersionEqualTo(version);
}
return scenarioExecutionInfoMapper.countByExample(example);
}

View File

@ -718,7 +718,7 @@ public class ApiScenarioReportService {
return ids;
}
public long countByProjectIdAndCreateAndByScheduleInThisWeek(String projectId) {
public long countByProjectIdAndCreateAndByScheduleInThisWeek(String projectId, String version) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
@ -727,11 +727,11 @@ public class ApiScenarioReportService {
if (firstTime == null || lastTime == null) {
return 0;
} else {
return extApiScenarioReportMapper.countByProjectIdAndCreateAndByScheduleInThisWeek(projectId, firstTime.getTime(), lastTime.getTime());
return extApiScenarioReportMapper.countByProjectIdAndCreateAndByScheduleInThisWeek(projectId, version, firstTime.getTime(), lastTime.getTime());
}
}
public long countByProjectIdAndCreateInThisWeek(String projectId) {
public long countByProjectIdAndCreateInThisWeek(String projectId, String version) {
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
Date firstTime = startAndEndDateInWeek.get("firstTime");
@ -740,12 +740,12 @@ public class ApiScenarioReportService {
if (firstTime == null || lastTime == null) {
return 0;
} else {
return extApiScenarioReportMapper.countByProjectIdAndCreateInThisWeek(projectId, firstTime.getTime(), lastTime.getTime());
return extApiScenarioReportMapper.countByProjectIdAndCreateInThisWeek(projectId, version, firstTime.getTime(), lastTime.getTime());
}
}
public List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(String projectId) {
return extApiScenarioReportMapper.countByProjectIdGroupByExecuteResult(projectId);
public List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(String projectId, String version) {
return extApiScenarioReportMapper.countByProjectIdGroupByExecuteResult(projectId, version);
}
public List<ApiScenarioReport> selectLastReportByIds(List<String> ids) {

View File

@ -2011,8 +2011,8 @@ public class ApiScenarioService {
return result;
}
public long countExecuteTimesByProjectID(String projectId, String triggerMode) {
return scenarioExecutionInfoService.countExecuteTimesByProjectID(projectId, triggerMode);
public long countExecuteTimesByProjectID(String projectId, String triggerMode, String version) {
return scenarioExecutionInfoService.countExecuteTimesByProjectID(projectId, triggerMode, version);
}
/**

View File

@ -186,4 +186,8 @@ export default {
color: #1F2329;
line-height: 22px;
}
.api-home-layout :deep(.el-card) {
border: 0;
}
</style>

View File

@ -23,9 +23,7 @@
<span class="main-info-card-title">{{ $t("home.dashboard.public.this_week") }}</span>
<div class="common-amount">
<el-button class="common-amount-button" @click="redirect('createdInWeek')">
<span type="num" class="addition-num">
+{{ countData.createdInWeek }}
</span>
+{{ countData.createdInWeek }}
<img class="main-info-card-right" src="/assets/figma/icon_right_outlined.svg" alt="">
</el-button>
</div>
@ -34,9 +32,7 @@
<span class="main-info-card-title">{{ $t("home.dashboard.public.fake_error") }}</span>
<div class="common-amount">
<el-button class="common-amount-button" @click="redirect('fakeError')">
<span class="addition-num">
{{ countData.fakeErrorCount }}
</span>
<img class="main-info-card-right" src="/assets/figma/icon_right_outlined.svg" alt="">
</el-button>
</div>
@ -91,12 +87,13 @@ export default {
.common-amount-button {
padding: 0 4px 0 4px;
border: 0;
margin: 0 -4px 0 -8px;
margin: 0 -4px 0 -4px;
font-size: 20px;
font-weight: 500;
line-height: 28px;
color: #1F2329;
}
.common-amount-button :deep(.addition-num) {
margin: 0 -4px 0 4px;
}
.main-info-card-right {
height: 12px;
@ -113,4 +110,12 @@ export default {
filter: drop-shadow(#783887 0px 999999px);
}
.common-amount-button:focus {
color: #783887;
}
.common-amount-button:hover {
color: #783887;
}
</style>

View File

@ -1,46 +1,12 @@
<template>
<div v-if="reloadOver">
<el-row type="flex" justify="left" align="left">
<div style="height: 184px;width: 184px;margin-left: 30px;margin-right: 30px;">
<div style="height: 184px;width: 100%;margin-left: 30px;margin-right: 30px;">
<ms-chart :options="options"
:height="184"
:width="184"
width="100%"
:autoresize="true"/>
</div>
<!-- 总数统计 -->
<div style="margin: auto;width: 260px;padding-right: 30px">
<div class="count-row">
<div>
<span class="ms-point-http"/>
<span class="count-title">HTTP</span>
<span class="count-value">
{{ formatAmount(apiData.httpCount) }}
</span>
</div>
</div>
<div class="count-row">
<span class="ms-point-rpc"/>
<span class="count-title">RPC</span>
<span class="count-value">
{{ formatAmount(apiData.rpcCount) }}
</span>
</div>
<div class="count-row">
<span class="ms-point-tcp"/>
<span class="count-title">TCP</span>
<span class="count-value">
{{ formatAmount(apiData.tcpCount) }}
</span>
</div>
<div class="count-row">
<span class="ms-point-sql"/>
<span class="count-title">SQL</span>
<span class="count-value">
{{ formatAmount(apiData.sqlCount) }}
</span>
</div>
</div>
</el-row>
</div>
</template>
@ -70,6 +36,7 @@ export default {
}
},
created() {
this.reload();
},
methods: {
reload() {
@ -132,16 +99,64 @@ export default {
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
icon: "rect",
itemGap: 16,
left: '45%',
y: 'center',
itemHeight: 8,
itemWidth: 8, //icon
itemStyle: {
borderWidth: 0.1
},
textStyle: {
align: 'right',
rich: {
protocol: {
fontSize: 14,
color: '#646A73',
fontWeight: 400,
align: 'center',
lineHeight: 22,
padding: [0, 0, 0, 4]
},
num: {
fontSize: 14,
align: 'left',
lineHeight: 22,
color: '#646A73',
fontWeight: 500,
padding: [0, 0, 0, 140]
}
}
},
data: protocolData,
formatter: function (name) {
//name
let singleData = protocolData.filter(function (item) {
return item.name === name
});
let value = singleData[0].value;
if (name !== 'HTTP') {
name += " ";
}
name += " \t";
return [`{protocol|${name}}`, `{num|${value}}`].join("");
}
},
title: {
text: "{mainTitle|" + this.$t("home.dashboard.api.api_total") + "}\n\n{number|" + this.getAmount() + "}\n\n",
subtext: this.$t("home.dashboard.public.this_week") + "+" + formatNumber(this.apiData.createdInWeek) + " >",
top: "center",
left: "center",
left: "86px",
textAlign: 'center',
textStyle: {
rich: {
mainTitle: {
color: '#646A73',
fontSize: 12,
align: 'center'
},
number: {
fontSize: this.pieChartStyle.amountFontSize,
@ -166,6 +181,7 @@ export default {
{
type: 'pie',
radius: ['70%', '96%'],
center: ['92px', '50%'],
avoidLabelOverlap: false,
hoverAnimation: true,
label: {

View File

@ -8,7 +8,7 @@
<div v-show="loadError"
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
<img style="height: 100px;width: 100px;"
src="/assets/figma/icon_load.svg"/>
src="/assets/figma/icon_load_error.svg"/>
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
</div>
<div v-show="!loadError">

View File

@ -8,7 +8,7 @@
<div v-show="loadError"
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
<img style="height: 100px;width: 100px;"
src="/assets/figma/icon_load.svg"/>
src="/assets/figma/icon_load_error.svg"/>
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
</div>
<div v-show="!loadError">

View File

@ -8,7 +8,7 @@
<div v-show="loadError"
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
<img style="height: 100px;width: 100px;"
src="/assets/figma/icon_load.svg"/>
src="/assets/figma/icon_load_error.svg"/>
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
</div>
<div v-show="!loadError">

View File

@ -8,7 +8,7 @@
<div v-show="loadError"
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
<img style="height: 100px;width: 100px;"
src="/assets/figma/icon_load.svg"/>
src="/assets/figma/icon_load_error.svg"/>
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
</div>
<div v-show="!loadError">

View File

@ -7,7 +7,7 @@
<div v-show="loadError"
style="width: 100%; height: 300px; display: flex; flex-direction: column; justify-content: center;align-items: center">
<img style="height: 100px;width: 100px;"
src="/assets/figma/icon_load.svg"/>
src="/assets/figma/icon_load_error.svg"/>
<span class="addition-info-title" style="color: #646A73">{{ $t("home.dashboard.public.load_error") }}</span>
</div>
<div v-show="!loadError">
@ -51,7 +51,7 @@
</template>
</el-table-column>
<el-table-column prop="caseTotal" :label="$t('home.new_case.relation_case')"
width="100">
width="120">
<template v-slot:default="{row}">
<el-link style="color: #783887;width: 100%;" type="info" :underline="false"
@click="redirectPage( 'api', 'apiTestCase', 'singleList:' + row.id)">
@ -61,7 +61,7 @@
</el-table-column>
<el-table-column prop="scenarioTotal"
:label="$t('home.new_case.relation_scenario')"
width="100">
width="140">
<template v-slot:default="{row}">
<el-link style="color: #783887;width: 100%;" type="info"
@click="redirectPage('scenario', 'scenario','list:' +row.scenarioIds)">