测试平台目录
测试平台自建源码
后台核心代码
def add_api(kwags):
"""插入api数据"""
try:
join_info = CaseApi(name=kwags.get("name"), httpType=kwags.get("httpType"),
headers=kwags.get("headers") if kwags.get("headers") else '{}',
requestType=kwags.get("requestType"), apiAddress=kwags.get("apiAddress"),
requestParameterType=kwags.get("requestParameterType"),
project_id=filter_project(project_name=kwags.get("project"))[0].get("id"),
params=kwags.get("body") if kwags.get("body") else '{}',
create_time=kwags.get("create_time"), responseData='{}',
create_user=kwags.get("create_user"), update_time=kwags.get("update_time"),
update_user=kwags.get("update_user"))
session.add(join_info)
session.commit()
return {"msg": "新增接口成功"}
except Exception as e:
logger.error(f"新增接口时失败:{e}")
return {"msg": f"新增接口失败:{e}"}
def filter_api(kwags):
"""查询api列表数据"""
try:
logger.info("开始查询api列表")
result = []
# 获取页数
page = kwags.get('page') if kwags.get('page') else 1
# 获取条数
limit = kwags.get('limit') if kwags.get('limit') else 20
# 排序
name = kwags.get('name')
data_header = "session.query(CaseApi).filter_by"
data_filter = '(name=name)' if name else '()'
data_sort = f".order_by(CaseApi.id.asc()).all()" if kwags.get(
'sort') == '+id' else f".order_by(CaseApi.id.desc()).all()"
data = data_header + data_filter + data_sort
data = eval(data)[(page - 1) * limit:limit]
for i in data:
case_item = i.to_json()
case_item["project"] = filter_project(i.to_json()["project"])[0].get("project_name")
result.append(case_item)
return result
except Exception as e:
logger.error(f"查询api列表失败:{e}")
部分前端代码样例
<template>
<div class="app-container">
<div class="filter-container">
<el-row class="filter-row">
<div class="filter-col">
<el-col span="5">
<label class="radio-label" style="font-style: normal;font-weight: normal">测试用例名称 </label>
<el-input v-model="listQuery.name" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
</el-col>
<el-col span="2">
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
Search
</el-button>
</el-col>
<el-col span="2">
<el-button v-waves class="filter-item" type="primary" icon="el-icon-circle-plus-outline" @click="add_case">
新增用例
</el-button>
</el-col>
</div>
</el-row>
</div>
<el-table
:key="tableKey"
:data="list"
:header-cell-style="getRowClass"
border
fit
highlight-current-row
style="width: 100%;margin-top:30px"
@sort-change="sortChange"
>
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="table-expand">
<el-form-item label="请求类型:">
<span>{{ props.row.httpType }}</span>
</el-form-item>
<el-form-item label="接口地址:">
<span>{{ props.row.apiAddress }}</span>
</el-form-item>
<el-form-item label="传参类型:">
<span>{{ props.row.requestParameterType }}</span>
</el-form-item>
<el-form-item label="请求header:">
<span>{{ props.row.headers }}</span>
</el-form-item>
<el-form-item label="参数:">
<span>{{ props.row.body }}</span>
</el-form-item>
<el-form-item label="响应code:">
<span>{{ props.row.httpCode }}</span>
</el-form-item>
<el-form-item label="响应data:">
<span>{{ props.row.responseData }}</span>
</el-form-item>
</el-form></template></el-table-column>
<el-table-column label="ID" prop="id" sortable="custom" align="center" width="100" :class-name="getSortClass('id')">
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column label="测试用例名称" width="300px" align="center">
<template slot-scope="{row}">
<span>{{ row.name }}</span>
<i class="el-icon-document-copy" style="margin-left:10%" @click="copyValue(row.name)" />
</template>
</el-table-column>
<el-table-column label="请求方式" width="110px" align="center">
<template slot-scope="{row}">
<span>{{ row.requestType }}</span>
</template>
</el-table-column>
<el-table-column label="所属项目" width="300px" align="center">
<template slot-scope="{row}">
<span>{{ row.project }}</span>
</template>
</el-table-column>
<el-table-column label="创建人" width="280px" align="center">
<template slot-scope="{row}">
<span>{{ row.create_user }}</span>
</template>
</el-table-column>
<el-table-column label="响应" width="280px" align="center">
<template slot-scope="{row}">
<el-popover
placement="top-start"
width="300"
trigger="hover"
:disabled="row.responseData.length <= 80"
>
<span>{{ row.responseData }}</span>
<span v-if="row.responseData.length <= 80" slot="reference">{{ row.responseData }}</span>
<span v-if="row.responseData.length > 80" slot="reference">{{ row.responseData.substr(0, 80) + "..." }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column label="操作" width="280px" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="success" size="small" icon="el-icon-video-play" :loading="loadingstatus" @click="runCase(scope.$index, scope.row)">运行</el-button>
<el-button type="primary" size="small" @click="formEditDialog(scope.$index, scope.row)">编辑</el-button>
<el-dialog :visible.sync="dialogFormVisible" :modal-append-to-body="false">
<span slot="title" :model="editForm" style="font-weight:bold;">编辑用例:{{ editForm.id }}_{{ editForm.name }}</span>
<el-form class="form" label-width="auto" :model="editForm" :rules="rules">
<el-form-item label="用例名称:" prop="name" :rules="rules.name">
<el-input v-model="editForm.name" />
</el-form-item>
<el-row>
<el-col span="6">
<el-form-item label="http类型:">
<el-select v-model="editForm.httpType" placeholder="请选择http类型">
<el-option label="http" value="http" />
<el-option label="https" value="https" />
</el-select>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="请求方法:">
<el-select v-model="editForm.requestType" placeholder="请选择请求方法">
<el-option label="get" value="get" />
<el-option label="post" value="post" />
<el-option label="put" value="put" />
<el-option label="delete" value="delete" />
</el-select>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="参数类型:">
<el-select v-model="editForm.requestParameterType" placeholder="请选择参数类型">
<el-option label="data" value="data" />
<el-option label="json" value="json" />
</el-select>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="项目名:">
<el-select v-model="editForm.project" placeholder="项目名">
<el-option
v-for="item in options"
:key="item.id"
:label="item.project_name"
:value="item.id"
/></el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="接口地址:" prop="apiAddress" :rules="rules.apiAddress">
<el-input v-model="editForm.apiAddress" />
</el-form-item>
<el-form-item label="请求header:">
<el-input v-model="editForm.headers" type="textarea" :rows="5" autocomplete="off" />
</el-form-item>
<el-form-item label="参数:">
<el-input v-model="editForm.body" type="textarea" :rows="5" autocomplete="off" />
</el-form-item></el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="formEditOn">确 定</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="dialogFormVisibleAdd" :modal-append-to-body="false">
<span slot="title" :model="addForm" style="font-weight:bold;">新增用例:</span>
<el-form class="form" label-width="auto" :label-position="left" :model="addForm" :rules="rules">
<el-form-item label="用例名称:" prop="name" :rules="rules.name">
<el-input v-model="addForm.name" />
</el-form-item>
<el-row>
<el-col span="6">
<el-form-item label="http类型:">
<el-select v-model="addForm.httpType" placeholder="请选择http类型">
<el-option label="http" value="http" />
<el-option label="https" value="https" />
</el-select>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="请求方法:">
<el-select v-model="addForm.requestType" placeholder="请选择请求方法">
<el-option label="get" value="get" />
<el-option label="post" value="post" />
<el-option label="put" value="put" />
<el-option label="delete" value="delete" />
</el-select>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="参数类型:">
<el-select v-model="addForm.requestParameterType" placeholder="请选择参数类型">
<el-option label="data" value="data" />
<el-option label="json" value="json" />
</el-select>
</el-form-item>
</el-col>
<el-col span="6">
<el-form-item label="项目名:">
<el-select v-model="editForm.project" placeholder="项目名">
<el-option
v-for="item in options"
:key="item.id"
:label="item.project_name"
:value="item.id"
/></el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="接口地址:" prop="apiAddress" :rules="rules.apiAddress">
<el-input v-model="addForm.apiAddress" />
</el-form-item>
<el-form-item label="请求header:" label-width="auto">
<el-input v-model="editForm.headers" type="textarea" :rows="5" autocomplete="off" />
</el-form-item>
<el-form-item label="参数:">
<el-input v-model="addForm.body" type="textarea" :rows="5" autocomplete="off" />
</el-form-item></el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisibleAdd = false">取 消</el-button>
<el-button type="primary" @click="formAdd">确 定</el-button>
</div>
</el-dialog>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import axios from 'axios'
import { platformBaseUrl } from '@/api/baseHost'
export default {
components: { Pagination },
data() {
return {
// formInline: {
// caseName: ''
// },
dialogFormVisible: false,
dialogFormVisibleAdd: false,
// formLabelWidth: '120px',
tableKey: 0,
list: [],
total: 0,
loadingstatus: false,
listLoading: true,
id: '',
params: {},
options: [{ 'id': 1, 'project_name': 'WGP-SRVbak' }, { 'id': 2, 'project_name': 'WGP-ADMINbak' }],
rules: {
name: [{ required: true, message: '用例名称不能为空', tigger: 'change' }],
apiAddress: [{ required: true, message: '接口地址不能为空', tigger: 'change' }]
},
addForm: {
name: '',
httpType: 'http',
requestType: 'get',
requestParameterType: 'data',
project: 'WGP-SRV',
apiAddress: '',
body: '',
headers: ''
},
editForm: {
id: undefined,
name: '',
httpType: '',
requestType: '',
requestParameterType: '',
project: '',
apiAddress: '',
body: '',
headers: ''
},
listQuery: {
page: 1,
limit: 10,
name: '',
sort: '+id'
},
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }]
}
},
created() {
console.log('created')
this.getProject()
this.getList()
},
methods: {
getList() {
this.listLoading = true
axios.post(platformBaseUrl + '/filter_Api/', this.listQuery)
.then(response => {
console.log(response.data)
this.list = response.data.result.items
this.total = response.data.result.total
})
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
},
getProject() {
axios.post(platformBaseUrl + '/filter_Project/', {})
.then(response => {
console.log(response.data)
this.options = response.data.result
})
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
},
copyValue(value) {
console.log('cope 121212')
const oInput = document.createElement('input') // 创建一个input标签
oInput.setAttribute('value', value) // 设置改input的value值
document.body.appendChild(oInput) // 将input添加到body
oInput.select() // 获取input的文本内容
document.execCommand('copy') // 执行copy指令
document.body.removeChild(oInput) // 删除input标签
this.$message({ message: '复制成功', type: 'success' })
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
formEditDialog(index, row) {
this.dialogFormVisible = true
this.id = index
this.editForm = Object.assign({}, row)
console.log(this.editForm)
},
runCase(index, row) {
this.params = Object.assign({}, row)['id']
// this.params = Object.assign({}, row)
if ((this.params !== '')) {
axios.post(platformBaseUrl + '/run_case/', this.params)
.then(response => {
console.log(response.data)
this.dialogFormVisible = false
// eslint-disable-next-line eqeqeq
if (response.data.result.msg == '更新成功') {
this.$message({ message: response.data.result.msg, type: 'success' })
this.getList()
} else {
this.$message({ message: response.data.result.msg, type: 'error' })
}
})
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
}
},
formEditOn() {
if ((this.editForm.name !== '' && this.editForm.apiAddress !== '')) {
axios.post(platformBaseUrl + '/edit_Api/', this.editForm)
.then(response => {
console.log(response.data)
this.dialogFormVisible = false
// eslint-disable-next-line eqeqeq
if (response.data.result.msg == '更新成功') {
this.$message({ message: response.data.result.msg, type: 'success' })
this.getList()
} else {
this.$message({ message: response.data.result.msg, type: 'error' })
}
})
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
}
},
add_case() {
this.dialogFormVisibleAdd = true
},
formAdd() {
if ((this.addForm.name !== '' && this.addForm.apiAddress !== '')) {
this.dialogFormVisibleAdd = false
axios.post(platformBaseUrl + '/add_Api/', this.addForm)
.then(response => {
console.log(response.data)
if (response.data.result.msg === '新增接口成功') {
this.$message({ message: response.data.result.msg, type: 'success' })
this.getList()
} else {
this.$message({ message: response.data.result.msg, type: 'error' })
}
})
setTimeout(() => {
this.listLoading = false
}, 1.5 * 1000)
}
},
sortChange(data) {
const { prop, order } = data
if (prop === 'id') {
this.sortByID(order)
}
},
getRowClass({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0) {
return 'background:#C0C0C0;color:#666666;text-align:center;font-size:14px;font-weight:500;width: 100%'
} else {
return 'white-space: pre-line'
}
},
sortByID(order) {
if (order === 'ascending') {
this.listQuery.sort = '+id'
} else {
this.listQuery.sort = '-id'
}
this.handleFilter()
},
getSortClass: function(key) {
const sort = this.listQuery.sort
return sort === `+${key}` ? 'ascending' : 'descending'
}
}
}
</script>
<style scoped>
.app-container{
background: #f3f0f0;
/* position: fixed; */
width: 100%;
height: 100%;
}
.filter-container{
background: #fdfdfd;
width: 100%;
height: 100px;
}
.filter-col{
margin:30px 50px 10px 50px;
}
.table-expand {
font-size: 0;
border: 2px solid #078359;
}
.table-expand label {
width: 90px;
color: #99a9bf;
}
.table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
width: 50%;
}
.form{
margin:0px 0px 10px 0px;
width: 100%;
border: 2px solid #078359;
margin-bottom: 0;
}
</style>