feat: 接口用例列表添加批量执行

This commit is contained in:
chenjianxing 2021-07-27 11:37:01 +08:00 committed by jianxing
parent 85d0b78801
commit fa8affac2d
9 changed files with 182 additions and 70 deletions

View File

@ -162,6 +162,12 @@ public class ApiTestCaseController {
apiTestCaseService.relevanceByApiByReview(request);
}
@PostMapping(value = "/batch/run")
@MsAuditLog(module = "api_definition", type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.caseId)", msClass = ApiTestCaseService.class)
public void batchRun(@RequestBody ApiCaseBatchRequest request) {
apiTestCaseService.batchRun(request);
}
@PostMapping(value = "/jenkins/run")
@MsAuditLog(module = "api_definition", type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.caseId)", msClass = ApiTestCaseService.class)
public String jenkinsRun(@RequestBody RunCaseRequest request) {
@ -173,4 +179,4 @@ public class ApiTestCaseController {
return apiTestCaseService.getExecResult(id);
}
}
}

View File

@ -1,6 +1,7 @@
package io.metersphere.api.dto;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.controller.request.OrderRequest;
import lombok.Getter;
import lombok.Setter;
@ -13,4 +14,6 @@ public class ApiCaseBatchRequest extends ApiTestCaseWithBLOBs {
private List<String> ids;
private List<OrderRequest> orders;
private String projectId;
private String environmentId;
private BaseQueryRequest condition;
}

View File

@ -597,8 +597,20 @@ public class ApiTestCaseService {
return ids;
}
public void batchRun(ApiCaseBatchRequest request) {
ServiceUtils.getSelectAllIds(request, request.getCondition(),
(query) -> extApiTestCaseMapper.selectIdsByQuery(query));
request.getIds().forEach(id -> {
RunCaseRequest runCaseRequest = new RunCaseRequest();
runCaseRequest.setRunMode(ApiRunMode.DEFINITION.name());
runCaseRequest.setCaseId(id);
runCaseRequest.setEnvironmentId(request.getEnvironmentId());
run(runCaseRequest);
});
}
public String run(RunCaseRequest request) {
ApiTestCaseWithBLOBs testCaseWithBLOBs = new ApiTestCaseWithBLOBs();
ApiTestCaseWithBLOBs testCaseWithBLOBs = null;
if (StringUtils.equals(request.getRunMode(), ApiRunMode.JENKINS_API_PLAN.name())) {
testCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(request.getReportId());
request.setCaseId(request.getReportId());
@ -624,7 +636,7 @@ public class ApiTestCaseService {
jMeterService.runLocal(request.getCaseId(), jmeterHashTree, request.getReportId(), request.getRunMode());
} catch (Exception ex) {
LogUtil.error(ex.getMessage());
LogUtil.error(ex.getMessage(), ex);
}
}
return request.getReportId();

View File

@ -7,6 +7,7 @@ import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.ApiTestCaseResult;
import io.metersphere.base.domain.ApiDefinition;
import io.metersphere.base.domain.ApiTestCase;
import io.metersphere.controller.request.BaseQueryRequest;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -50,4 +51,6 @@ public interface ExtApiTestCaseMapper {
List<String> selectNameByIdIn(@Param("ids")List<String> ids);
String selectNameById(String id);
List<String> selectIdsByQuery(BaseQueryRequest query);
}

View File

@ -222,37 +222,7 @@
LEFT JOIN `user` u1 ON t1.update_user_id = u1.id
LEFT JOIN `user` u2 ON t1.create_user_id = u2.id
LEFT JOIN `user` u3 ON t2.user_id = u3.id
<where>
<if test="request.name != null and request.name!=''">
and t1.name like CONCAT('%', #{request.name},'%')
</if>
<if test="request.id != null and request.id!=''">
AND t1.id = #{request.id}
</if>
<if test="request.priority != null and request.priority!=''">
AND t1.priority = #{request.priority}
</if>
<if test="request.projectId != null and request.projectId!=''">
AND t1.project_id = #{request.projectId}
</if>
<if test="request.apiDefinitionId != null and request.apiDefinitionId!=''">
AND t1.api_definition_id = #{request.apiDefinitionId}
</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.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="name" value="request.name"/>
<property name="objectKey" value="request.combine.tags"/>
</include>
</if>
</where>
<include refid="queryWhereCondition"/>
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
@ -536,6 +506,47 @@
WHERE testCase.id = #{0}
</select>
<sql id="queryWhereCondition">
<where>
<if test="request.name != null and request.name!=''">
and t1.name like CONCAT('%', #{request.name},'%')
</if>
<if test="request.id != null and request.id!=''">
AND t1.id = #{request.id}
</if>
<if test="request.priority != null and request.priority!=''">
AND t1.priority = #{request.priority}
</if>
<if test="request.projectId != null and request.projectId!=''">
AND t1.project_id = #{request.projectId}
</if>
<if test="request.apiDefinitionId != null and request.apiDefinitionId!=''">
AND t1.api_definition_id = #{request.apiDefinitionId}
</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.combine != null">
<include refid="combine">
<property name="condition" value="request.combine"/>
<property name="name" value="request.name"/>
<property name="objectKey" value="request.combine.tags"/>
</include>
</if>
</where>
</sql>
<select id="selectIdsByQuery" resultType="java.lang.String">
SELECT t1.id
FROM api_test_case t1
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
inner join api_definition a on t1.api_definition_id = a.id
</if>
<include refid="queryWhereCondition"/>
</select>
<update id="deleteToGc" parameterType="io.metersphere.api.dto.definition.ApiTestCaseRequest">
update api_test_case
set original_status=status,

View File

@ -0,0 +1,46 @@
<template>
<ms-edit-dialog
width="20%"
:visible.sync="visible"
:title="$t('test_track.plan.load_case.batch_exec_cases')"
@confirm="save">
<ms-environment-select
:project-id="projectId"
@setEnvironment="setEnvironment" ref="environmentSelect"/>
</ms-edit-dialog>
</template>
<script>
import MsEditDialog from "@/business/components/common/components/MsEditDialog";
import MsEnvironmentSelect from "@/business/components/api/definition/components/case/MsEnvironmentSelect";
export default {
name: "ApiCaseBatchRun",
components: {MsEnvironmentSelect, MsEditDialog},
props: ['projectId'],
data() {
return {
visible: false,
environment: {}
}
},
methods: {
setEnvironment(environment) {
this.environment = environment;
},
open() {
this.visible = true;
},
close() {
this.visible = false;
},
save() {
this.$emit('batchRun', this.environment);
}
}
}
</script>
<style scoped>
</style>

View File

@ -141,6 +141,8 @@
<!--高级搜索-->
<ms-table-adv-search-bar :condition.sync="condition" :showLink="false" ref="searchBar" @search="initTable"/>
<api-case-batch-run :project-id="projectId" @batchRun="runBatch" ref="batchRun"/>
</div>
</template>
@ -180,10 +182,13 @@ import {
} from "@/common/js/tableUtils";
import {API_CASE_LIST} from "@/common/js/constants";
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
import {apiCaseBatchRun} from "@/network/api";
import ApiCaseBatchRun from "@/business/components/api/definition/components/list/ApiCaseBatchRun";
export default {
name: "ApiCaseSimpleList",
components: {
ApiCaseBatchRun,
HeaderLabelOperate,
MsTableHeaderSelectPopover,
MsSetEnvironment,
@ -221,7 +226,8 @@ export default {
buttons: [],
simpleButtons: [
{name: this.$t('api_test.definition.request.batch_delete'), handleClick: this.handleDeleteToGcBatch},
{name: this.$t('api_test.definition.request.batch_edit'), handleClick: this.handleEditBatch}
{name: this.$t('api_test.definition.request.batch_edit'), handleClick: this.handleEditBatch},
{name: this.$t('api_test.automation.batch_execute'), handleClick: this.handleRunBatch},
],
trashButtons: [
{name: this.$t('commons.reduction'), handleClick: this.handleBatchRestore},
@ -248,7 +254,7 @@ export default {
icon: "el-icon-delete",
type: "danger",
permissions: ['PROJECT_API_DEFINITION:READ+DELETE_CASE']
},
}
],
trashOperators: [
{tip: this.$t('commons.reduction'), icon: "el-icon-refresh-left", exec: this.reduction},
@ -376,6 +382,17 @@ export default {
}
},
methods: {
handleRunBatch() {
this.$refs.batchRun.open();
},
runBatch(environment) {
this.condition.environmentId = environment.id;
this.condition.ids = this.$refs.caseTable.selectIds;
apiCaseBatchRun(this.condition);
this.condition.ids = [];
this.$refs.batchRun.close();
this.search();
},
customHeader() {
this.$refs.caseTable.openCustomHeader();
},

View File

@ -1,5 +1,41 @@
import {Message} from 'element-ui';
export function success(message) {
Message.success({
message: message,
type: "success",
showClose: true,
duration: 1500
});
}
export function info(message, duration) {
Message.info({
message: message,
type: "info",
showClose: true,
duration: duration || 3000
});
}
export function warning(message) {
Message.warning({
message: message,
type: "warning",
showClose: true,
duration: 5000
});
}
export function error(message, duration) {
Message.error({
message: message,
type: "error",
showClose: true,
duration: duration || 10000
});
}
export default {
install(Vue) {
if (!Message) {
@ -7,42 +43,12 @@ export default {
return
}
Vue.prototype.$success = function (message) {
Message.success({
message: message,
type: "success",
showClose: true,
duration: 1500
})
};
Vue.prototype.$success = success;
Vue.prototype.$info = function (message, duration) {
Message.info({
message: message,
type: "info",
showClose: true,
duration: duration || 3000
})
};
Vue.prototype.$warning = function (message) {
Message.warning({
message: message,
type: "warning",
showClose: true,
duration: 5000
})
};
Vue.prototype.$error = function (message, duration) {
Message.error({
message: message,
type: "error",
showClose: true,
duration: duration || 10000
})
};
Vue.prototype.$info = info;
Vue.prototype.$warning = warning;
Vue.prototype.$error = error;
}
}

View File

@ -0,0 +1,8 @@
import {post} from "@/common/js/ajax";
import {success} from "@/common/js/message";
export function apiCaseBatchRun(condition) {
return post('/api/testcase/batch/run', condition, () => {
success("执行成功,请稍后刷新查看");
});
}