编辑测试用例详情

This commit is contained in:
chenjianxing 2020-04-06 23:38:25 +08:00
parent e018f744db
commit 04bb963c55
11 changed files with 302 additions and 48 deletions

View File

@ -39,13 +39,7 @@ public class TestCaseController {
return testCaseService.getTestCaseByNodeId(nodeIds);
}
@PostMapping("/plan/list/{goPage}/{pageSize}")
public Pager<List<TestPlanCaseDTO>> getTestPlanCases(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestCaseRequest request){
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, testCaseService.getTestPlanCases(request));
}
@PostMapping("/name/all")
@PostMapping("/name")
public List<TestCase> getTestCaseNames(@RequestBody QueryTestCaseRequest request){
return testCaseService.getTestCaseNames(request);
}

View File

@ -0,0 +1,42 @@
package io.metersphere.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.base.domain.TestCaseWithBLOBs;
import io.metersphere.base.domain.TestPlanTestCase;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.dto.TestPlanCaseDTO;
import io.metersphere.service.TestPlanTestCaseService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RequestMapping("/test/plan/case")
@RestController
public class TestPlanTestCaseController {
@Resource
TestPlanTestCaseService testPlanTestCaseService;
@PostMapping("/list/{goPage}/{pageSize}")
public Pager<List<TestPlanCaseDTO>> getTestPlanCases(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestCaseRequest request){
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, testPlanTestCaseService.getTestPlanCases(request));
}
@PostMapping("/edit")
public void editTestCase(@RequestBody TestPlanTestCase testPlanTestCase){
testPlanTestCaseService.editTestCase(testPlanTestCase);
}
@PostMapping("/delete/{id}")
public int deleteTestCase(@PathVariable Integer id){
return testPlanTestCaseService.deleteTestCase(id);
}
}

View File

@ -6,6 +6,8 @@ public class TestPlanCaseDTO extends TestCase {
private String executor;
private String status;
private String results;
private String remark;
public String getExecutor() {
return executor;
@ -22,4 +24,20 @@ public class TestPlanCaseDTO extends TestCase {
public void setStatus(String status) {
this.status = status;
}
public String getResults() {
return results;
}
public void setResults(String results) {
this.results = results;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}

View File

@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@Transactional(rollbackFor = Exception.class)
@ -30,10 +31,10 @@ public class TestCaseService {
ExtTestCaseMapper extTestCaseMapper;
@Resource
TestPlanTestCaseMapper testPlanTestCaseMapper;
TestPlanMapper testPlanMapper;
@Resource
TestPlanMapper testPlanMapper;
TestPlanTestCaseMapper testPlanTestCaseMapper;
public void addTestCase(TestCaseWithBLOBs testCase) {
testCase.setId(UUID.randomUUID().toString());
@ -78,17 +79,35 @@ public class TestCaseService {
return testCaseMapper.selectByExampleWithBLOBs(testCaseExample);
}
/**
* 获取测试用例
* 过滤已关联
* @param request
* @return
*/
public List<TestCase> getTestCaseNames(QueryTestCaseRequest request) {
if ( StringUtils.isNotBlank(request.getPlanId()) ) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getPlanId());
request.setProjectId(testPlan.getProjectId());
}
return extTestCaseMapper.getTestCaseNames(request);
List<TestCase> testCaseNames = extTestCaseMapper.getTestCaseNames(request);
if ( StringUtils.isNotBlank(request.getPlanId()) ) {
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(request.getPlanId());
List<String> relevanceIds = testPlanTestCaseMapper.selectByExample(testPlanTestCaseExample).stream()
.map(TestPlanTestCase::getCaseId)
.collect(Collectors.toList());
return testCaseNames.stream()
.filter(testcase -> !relevanceIds.contains(testcase.getId()))
.collect(Collectors.toList());
}
return testCaseNames;
}
public List<TestPlanCaseDTO> getTestPlanCases(QueryTestCaseRequest request) {
return extTestCaseMapper.getTestPlanTestCases(request);
}
}

View File

@ -0,0 +1,37 @@
package io.metersphere.service;
import io.metersphere.base.domain.TestPlanTestCase;
import io.metersphere.base.mapper.TestPlanTestCaseMapper;
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
import io.metersphere.dto.TestPlanCaseDTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanTestCaseService {
@Resource
TestPlanTestCaseMapper testPlanTestCaseMapper;
@Resource
ExtTestCaseMapper extTestCaseMapper;
public List<TestPlanCaseDTO> getTestPlanCases(QueryTestCaseRequest request) {
return extTestCaseMapper.getTestPlanTestCases(request);
}
public void editTestCase(TestPlanTestCase testPlanTestCase) {
testPlanTestCase.setUpdateTime(System.currentTimeMillis());
testPlanTestCaseMapper.updateByPrimaryKeySelective(testPlanTestCase);
}
public int deleteTestCase(Integer id) {
return testPlanTestCaseMapper.deleteByPrimaryKey(id);
}
}

View File

@ -63,7 +63,7 @@
<el-col :span="10" :offset="1">
<el-form-item :label="$t('test_track.type')" :label-width="formLabelWidth" prop="type">
<el-select v-model="form.type" :placeholder="$t('test_track.input_type')">
<el-option :label="$t('commons.functional')" value="functional"></el-option>
<el-option :label="$t('test_track.functional_test')" value="functional"></el-option>
<el-option :label="$t('commons.performance')" value="performance"></el-option>
<el-option :label="$t('commons.api')" value="api"></el-option>
</el-select>
@ -306,15 +306,12 @@
.tb-edit .el-input {
display: none;
color: black;
}
.tb-edit .current-row .el-input {
display: block;
}
.tb-edit .current-row .el-input+span {
display: none;
}
</style>

View File

@ -53,7 +53,7 @@
width="120"
show-overflow-tooltip>
<template v-slot:default="scope">
<span v-if="scope.row.type == 'functional'">{{$t('commons.functional')}}</span>
<span v-if="scope.row.type == 'functional'">{{$t('test_track.functional_test')}}</span>
<span v-if="scope.row.type == 'performance'">{{$t('commons.performance')}}</span>
<span v-if="scope.row.type == 'api'">{{$t('commons.api')}}</span>
</template>

View File

@ -24,8 +24,8 @@
ref="testCaseRelevance"></test-case-relevance>
<test-plan-test-case-edit
ref="testPlanTestCaseEdit">
ref="testPlanTestCaseEdit"
@refresh="getPlanCases">
</test-plan-test-case-edit>
@ -61,7 +61,7 @@
},
getPlanCases(nodeIds) {
this.$refs.testCasePlanList(nodeIds);
this.$refs.testCasePlanList.initTableData(nodeIds);
},
openTestCaseRelevanceDialog() {
this.$refs.testCaseRelevance.openTestCaseRelevanceDialog(this.planId);
@ -73,8 +73,12 @@
});
}
},
editTestPlanTestCase() {
this.$refs.testPlanTestCaseEdit.drawer = true;
editTestPlanTestCase(testCase) {
let item = {};
Object.assign(item, testCase);
item.results = JSON.parse(item.results);
this.$refs.testPlanTestCaseEdit.testCase = item;
this.$refs.testPlanTestCaseEdit.dialog = true;
}
}
}

View File

@ -53,7 +53,7 @@
width="120"
show-overflow-tooltip>
<template v-slot:default="scope">
<span v-if="scope.row.type == 'functional'">{{$t('commons.functional')}}</span>
<span v-if="scope.row.type == 'functional'">{{$t('test_track.functional_test')}}</span>
<span v-if="scope.row.type == 'performance'">{{$t('commons.performance')}}</span>
<span v-if="scope.row.type == 'api'">{{$t('commons.api')}}</span>
</template>
@ -129,7 +129,6 @@
</template>
<script>
import {CURRENT_PROJECT} from '../../../../../common/constants';
import PlanNodeTree from './PlanNodeTree';
export default {
@ -165,7 +164,7 @@
};
param.nodeIds = nodeIds;
param.planId = this.planId;
this.$post(this.buildPagePath('/test/case/plan/list'), param, response => {
this.$post(this.buildPagePath('/test/plan/case/list'), param, response => {
this.loadingRequire.testCase = false;
let data = response.data;
this.total = data.itemCount;
@ -205,7 +204,7 @@
},
_handleDelete(testCase) {
let testCaseId = testCase.id;
this.$post('/test/case/delete/' + testCaseId, {}, () => {
this.$post('/test/plan/case/delete/' + testCaseId, {}, () => {
this.initTableData();
this.$message({
message: this.$t('commons.delete_success'),

View File

@ -84,9 +84,7 @@
},
methods: {
openTestCaseRelevanceDialog(planId) {
console.log(planId);
this.getAllNodeTreeByPlanId(planId);
console.log(this.$refs);
this.getCaseNames(planId);
this.dialogFormVisible = true;
},
@ -95,7 +93,9 @@
param.planId = this.planId;
param.testCaseIds = [...this.selectIds];
this.$post('/test/plan/relevance' , param, () => {
this.dialogFormVisible = false;
this.$message.success("保存成功");
this.$emit('refresh');
});
},
getCaseNames(planId, nodeIds) {
@ -106,7 +106,7 @@
if (nodeIds && nodeIds.length > 0){
param.nodeIds = nodeIds;
}
this.$post('/test/case/name/all', param, response => {
this.$post('/test/case/name', param, response => {
this.testCases = response.data;
this.testCases.forEach(item => {
item.checked = false;
@ -117,12 +117,6 @@
this.dialogFormVisible = true;
this.getCaseNames(null, nodeIds);
},
checkAll() {
this.testCases.forEach(item => {
item.checked = this.isCheckAll;
});
this.dialogFormVisible = true;
},
handleSelectAll(selection) {
if(selection.length > 0){
this.testCases.forEach(item => {

View File

@ -1,14 +1,125 @@
<template>
<div>
<el-drawer
title="我是标题"
:visible.sync="drawer"
:direction="direction"
:before-close="handleClose">
<span>我来啦!</span>
</el-drawer>
</div>
<el-drawer
:title="testCase.name"
:before-close="handleClose"
:visible.sync="dialog"
direction="ttb"
size="100%"
ref="drawer">
<div>
<el-row >
<el-col :span="3" :offset="1">
<span class="cast_label">优先级</span>
<span class="cast_item">{{testCase.priority}}</span>
</el-col>
<el-col :span="3">
<span class="cast_label">用例类型</span>
<span class="cast_item" v-if="testCase.type == 'functional'">{{$t('test_track.functional_test')}}</span>
<span class="cast_item" v-if="testCase.type == 'performance'">{{$t('commons.performance')}}</span>
<span class="cast_item" v-if="testCase.type == 'api'">{{$t('commons.api')}}</span>
</el-col>
</el-row>
<el-row>
<el-col :span="3" :offset="1">
<span class="cast_label">测试方式</span>
<span v-if="testCase.method == 'manual'">{{$t('test_track.manual')}}</span>
<span v-if="testCase.method == 'auto'">{{$t('test_track.auto')}}</span>
</el-col>
<el-col :span="3">
<span class="cast_label">所属模块</span>
<span class="cast_item">{{testCase.nodePath}}</span>
</el-col>
</el-row>
<el-row>
<el-col :offset="1" :span="2">
<el-button type="success" round
:icon="testCase.status == 'Pass' ? 'el-icon-check' : ''"
@click="setTestCaseStatus('Pass')"> 成功</el-button>
</el-col>
<el-col :span="2">
<el-button type="danger" round
:icon="testCase.status == 'Failure' ? 'el-icon-check' : ''"
@click="setTestCaseStatus('Failure')"> 失败</el-button>
</el-col>
<el-col :span="2">
<el-button type="warning" round
:icon="testCase.status == 'Blocking' ? 'el-icon-check' : ''"
@click="setTestCaseStatus('Blocking')"> 阻塞</el-button>
</el-col>
<el-col :span="2">
<el-button type="info" round
:icon="testCase.status == 'Skip' ? 'el-icon-check' : ''"
@click="setTestCaseStatus('Skip')"> 跳过</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="20" :offset="1">
<el-table
:data="testCase.results"
class="tb-edit"
:default-sort = "{prop: 'num', order: 'ascending'}"
highlight-current-row>
<el-table-column :label="$t('test_track.number')" prop="num" min-width="8%"></el-table-column>
<el-table-column :label="$t('test_track.step_desc')" prop="desc" min-width="30%">
<template v-slot:default="scope">
<span>{{scope.row.desc}}</span>
</template>
</el-table-column>
<el-table-column :label="$t('test_track.expected_results')" prop="result" min-width="30%">
<template v-slot:default="scope">
<span>{{scope.row.result}}</span>
</template>
</el-table-column>
<el-table-column label="实际结果" min-width="30%">
<template v-slot:default="scope">
<el-input
size="small"
v-model="scope.row.actualResult"
:placeholder="$t('commons.input_content')"
clearable></el-input>
<span>{{scope.row.actualResult}}</span>
</template>
</el-table-column>
<el-table-column label="步骤执行结果" min-width="15%">
<template v-slot:default="scope">
<el-select v-model="scope.row.stepResult" placeholder="选择执行结果">
<el-option label="通过" value="Pass"></el-option>
<el-option label="失败" value="Failure"></el-option>
<el-option label="阻塞" value="Blocking"></el-option>
<el-option label="跳过" value="Skip"></el-option>
</el-select>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<el-row >
<el-col :span="40" :offset="1">
<span>备注</span>
<span>{{testCase.remark}}</span>
<span v-if="testCase.remark == null" style="color: gainsboro">未填写</span>
</el-col>
</el-row>
<el-row type="flex" justify="end">
<el-col :span="5">
<div>
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="saveCase">{{ ' ' }}</el-button>
</div>
</el-col>
</el-row>
</div>
</el-drawer>
</template>
@ -17,13 +128,52 @@
name: "TestPlanTestCaseEdit",
data() {
return {
drawer: false,
direction: 'rtl',
dialog: false,
testCase: {}
};
},
methods: {
handleClose(done) {
this.dialog = false;
},
cancel() {
this.dialog = false;
},
setTestCaseStatus(status) {
this.testCase.status = status;
},
saveCase() {
let param = {};
param.id = this.testCase.id;
param.status = this.testCase.status;
param.results = JSON.stringify(this.testCase.results);
this.$post('/test/plan/case/edit', param, () => {
this.$refs.drawer.closeDrawer();
this.$message.success("保存成功!");
this.$emit('refresh');
});
}
}
}
</script>
<style scoped>
.tb-edit .el-input {
display: none;
color: black;
}
.tb-edit .current-row .el-input {
display: block;
}
.tb-edit .current-row .el-input+span {
display: none;
}
.el-row {
margin-bottom: 3%;
}
</style>