测试计划关联用例及执行

This commit is contained in:
liangdaliang
2025-04-27 23:36:48 +08:00
parent b680339e6a
commit 18434d1f88
19 changed files with 1153 additions and 10 deletions

View File

@@ -0,0 +1,51 @@
import request from '@/utils/request'
const api = {
planCaseList: 'test/planCase/list',
relateCaseList: '/test/case/planRelateList',
saveRelate: 'test/planCase/saveRelate',
delRelate: 'test/planCase/delRelate/',
}
export function getPlanCaseList(data) {
return request({
url: api.planCaseList,
method: 'get',
params: data
})
}
// 查询可关联的用例列表
export function getRelateCaseList(data) {
return request({
url: api.relateCaseList,
method: 'get',
params: data
})
}
export function saveRelate(data) {
return request({
url: api.saveRelate,
method: 'post',
data
})
}
export function delRelate(id) {
return request({
url: api.delRelate + id,
method: 'post',
data: {id}
})
}
// 执行用例
export function runTestPlanCase(data) {
return request({
url: '/test/case/runTestPlanCase',
method: 'post',
data
})
}

View File

@@ -130,6 +130,20 @@ export const constantRoutes = [
}
]
},
{
path: '/testplan/execute',
component: Layout,
hidden: true,
children: [
{
path: '',
component: () => import('@/views/test/testplan/execute/index'),
name: 'PlanExecute',
noCache: true,
meta: { title: '计划执行', activeMenu: '/testplan' }
}
]
},
{
path: '/task/detail',
component: Layout,

View File

@@ -14,7 +14,7 @@
<el-table-column label="创建时间" align="center" prop="createTime"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-delete" @click.native.stop="handleRun(scope.row.id)">执行</el-button>
<el-button size="mini" type="text" icon="el-icon-caret-right" @click.native.stop="handleRun(scope.row.id)">执行</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click.native.stop="handleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>

View File

@@ -0,0 +1,267 @@
<template>
<div class="app-container">
<!-- 顶部导航 -->
<el-row :gutter="10">
<el-col :span="24">
<el-header class="header">
<div class="head1">
<span style="font-size: 18px; font-weight: bold; margin-right: 20px;">[{{ title }}]关联用例列表</span>
</div>
<div class="head2">
<el-input :placeholder="'请输入用例名称'" v-model="queryParams.caseName" class="input-with-select" clearable>
<el-button slot="append" icon="el-icon-search" @click="handleQuery"></el-button>
</el-input>
<el-button icon="el-icon-plus" type="primary" size="medium" style="margin-left: 10px;" @click="relateCaseVue">
关联用例
</el-button>
<el-button type="primary" plain icon="el-icon-caret-right" size="medium" :disabled="isExecuteVisible" @click="handleRunAll">执行全部用例</el-button>
<el-button
type="danger"
plain
icon="el-icon-delete"
size="medium"
:disabled="multiple"
@click="handleDelete"
>批量删除</el-button>
</div>
</el-header>
</el-col>
</el-row>
<!-- 标签页 -->
<el-tabs v-model="activeTab" @tab-click="handleTabClick" style="margin-top: 10px;">
<el-tab-pane :label="'冒烟测试'" name="0"></el-tab-pane>
<el-tab-pane :label="'功能测试'" name="1"></el-tab-pane>
<el-tab-pane :label="'回归测试'" name="2"></el-tab-pane>
<el-tab-pane :label="'准生产验证'" name="3"></el-tab-pane>
<el-tab-pane :label="'生产验证'" name="4"></el-tab-pane>
<el-Table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
<el-table-column type="selection"/>
<el-table-column prop="caseName" label="测试用例名称" align="center"/>
<el-table-column prop="executeResult" label="执行结果" align="center"/>
<el-table-column prop="createBy" label="创建人" align="center"/>
<el-table-column prop="executeBy" label="最近执行人" align="center"/>
<el-table-column prop="executeTime" label="最近执行时间" align="center"/>
<el-table-column prop="createTime" label="关联时间" align="center"/>
<el-table-column label="操作" align="left" fixed="right">
<template slot-scope="scope">
<!-- <el-button size="mini" type="text" icon="el-icon-caret-right" @click.native.stop="handleRun(scope.row.id)">执行</el-button>-->
<el-button size="mini" type="text" icon="el-icon-delete" @click.native.stop="handleDelete(scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-Table>
</el-tabs>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<el-dialog title="关联测试用例" :visible.sync="open" width="1100px" v-loading="submitLoading" append-to-body>
<RelateCase ref="relateCase" :form="queryParams" @refresh="getList"></RelateCase>
<span slot="footer" class="dialog-footer">
<el-button @click="open = false"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {getPlanCaseList, saveRelate, delRelate} from "@/api/test/planCase";
import SimpleOptions from "@/components/FormItem/option/SimpleOptions.vue";
import RelateCase from "@/views/test/testplan/execute/relateCase.vue";
import page1 from "../../case/detail/page1.vue";
import {runTestPlanCase} from "../../../../api/test/planCase";
export default {
name: 'project',
components: {page1, SimpleOptions, RelateCase},
dicts: ['priority_level', 'project_source', 'project_type', 'status'],
data() {
return {
activeTab: '0',
total: 0,
list: [],
title: '',
// 选中数组
ids: [],
isExecuteVisible: true,
// 非多个禁用
multiple: true,
// 遮罩层
loading: false,
submitLoading: false,
//弹窗
open: false,
selectedRows: [],
selectedData: [],
managerList: [],
queryParams: {
caseName: '',
planId: '',
type: 0,
pageNum: 1,
pageSize: 10,
},
activeNames: [], // 控制 collapse 的展开状态
};
},
created() {
this.queryParams.planId = this.$route.query.id;
this.title = this.$route.query.name;
this.getList();
},
methods: {
handleSelectionChange(selection) {
this.selectedRows = selection;
this.ids = selection.map(item => item.id)
this.multiple = !selection.length
},
handleTabClick(tab) {
this.ids = [];
this.multiple = false;
this.activeTab = tab.name;
this.queryParams.type = parseInt(this.activeTab, 10);
this.getList();
},
// 搜索
handleQuery() {
this.getList();
},
relateCaseVue() {
this.open = true;
this.reset();
this.$refs.relateCase.getList()
},
/** 查询列表 */
getList() {
this.loading = true;
const queryParams = {
...this.queryParams
}
getPlanCaseList(queryParams).then(list => {
this.list = list.rows;
this.total = list.total;
if (this.total > 0) {
this.isExecuteVisible = false;
} else {
this.isExecuteVisible = true;
}
this.loading = false
})
},
handleRunAll() {
this.loading = true;
const queryParams = {
planId: this.queryParams.planId,
type: this.queryParams.type
}
this.$modal.confirm('是否确认执行全部接口用例?').then(function () {
return runTestPlanCase(queryParams);
}).then((res) => {
this.$modal.msgSuccess("提交执行成功");
this.open = true;
this.loading = false;
});
},
// 表单重置
reset() {
this.selectedRows = [];
this.ids = [];
this.multiple = false;
},
submitForm() {
const form = {
...this.queryParams,
testCaseIdList: this.$refs.relateCase.getSelectedCaseIds()
}
this.submitLoading = true
saveRelate(form)
.then(() => {
this.$message.success('关联成功')
this.open = false
})
.catch(() => {
this.$message.error('关联失败')
})
.finally(() => {
this.submitLoading = false
this.open = false
this.getList()
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除关联用例?').then(function () {
return delRelate(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
});
}
}
};
</script>
<style lang="scss" scoped>
.input-with-select {
background-color: #ffffff;
width: 300px;
}
.collapse-search {
::v-deep .el-collapse-item__header {
display: none;
}
}
.high-search {
display: flex;
justify-content: space-between;
padding-top: 40px;
background-color: rgb(248, 248, 249);
}
.header {
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.head1 {
display: flex;
align-items: center;
}
.head2 {
display: flex;
align-items: center;
flex: 1;
justify-content: flex-end;
column-gap: 10px;
}
.el-dialog .el-form {
width: 100%;
}
.el-dialog .el-form-item {
margin-bottom: 20px;
}
.el-dialog .el-textarea {
width: 100%;
}
.basic-information {
background-color: rgb(248, 248, 249) !important;
}
</style>

View File

@@ -0,0 +1,80 @@
<template>
<folder-page type="case" @click="folderHandleSelected" :style="{ height: '600px' }">
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection"/>
<el-table-column label="用例名称" align="center" prop="name"/>
<el-table-column label="创建人" align="center" prop="createBy"/>
<el-table-column label="用例状态" align="center" prop="status" :formatter="row => ['','草稿', '通过', '不通过'][row.status]"/>
<el-table-column label="创建时间" align="center" prop="createTime"/>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList"/>
</folder-page>
</template>
<script>
import FolderPage from "@/components/FolderPage/index.vue";
import {runCaseSync} from "@/api/test/case";
import {getRelateCaseList} from "@/api/test/planCase";
export default {
name: "relateCase",
components: {FolderPage},
props: {
form: {
type: Object
}
},
data() {
return {
loading: false,
open: false,
showSearch: true,
total: 0,
dataList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
groupId: null,
planId: '',
type: 0,
},
selectedRows: [], // 存储选中的行
caseSID: null,
}
},
methods: {
getSelectedCaseIds() {
// 返回选中的行的用例 id 数组
return this.selectedRows.map(row => row.id);
},
handleSelectionChange(selection) {
this.selectedRows = selection; // 更新选中的行
},
folderHandleSelected(id) {
if (id) {
this.queryParams.groupId = id;
this.getList();
} else {
this.dataList = [];
}
},
getList() {
this.loading = true;
this.queryParams.type = this.form.type;
this.queryParams.planId = this.form.planId;
getRelateCaseList(this.queryParams).then(response => {
this.dataList = response.rows;
this.total = response.total;
this.loading = false;
});
}
}
}
</script>
<style scoped lang="scss">
::v-deep .el-table__row {
cursor: pointer;
}
</style>

View File

@@ -255,6 +255,8 @@
<el-table-column prop="defectNum" label="缺陷数" align="left"/>
<el-table-column label="操作" align="left" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-view" @click.native.stop="handlePlanRun(scope.row)">计划执行
</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click.native.stop="handleDelete(scope.row.id)">删除
</el-button>
</template>
@@ -478,6 +480,9 @@ export default {
this.$modal.msgSuccess("删除成功");
});
},
handlePlanRun(row) {
this.$tab.openPage(`计划执行[${row.name}]`, "/testplan/execute", {id: row.id, name: row.name});
},
editSubmitForm() {
const form = {
...this.editForm,