测试计划关联测试用例
This commit is contained in:
parent
d421965476
commit
83fe299506
|
@ -4,6 +4,7 @@ import io.metersphere.base.domain.TestCase;
|
||||||
import io.metersphere.controller.request.ReportRequest;
|
import io.metersphere.controller.request.ReportRequest;
|
||||||
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||||
import io.metersphere.dto.ReportDTO;
|
import io.metersphere.dto.ReportDTO;
|
||||||
|
import io.metersphere.dto.TestPlanCaseDTO;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -11,4 +12,6 @@ import java.util.List;
|
||||||
public interface ExtTestCaseMapper {
|
public interface ExtTestCaseMapper {
|
||||||
|
|
||||||
List<TestCase> getTestCaseNames(@Param("request") QueryTestCaseRequest request);
|
List<TestCase> getTestCaseNames(@Param("request") QueryTestCaseRequest request);
|
||||||
|
|
||||||
|
List<TestPlanCaseDTO> getTestPlanTestCases(@Param("request") QueryTestCaseRequest request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,4 +20,22 @@
|
||||||
ORDER BY test_case.update_time DESC
|
ORDER BY test_case.update_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="getTestPlanTestCases" resultType="io.metersphere.dto.TestPlanCaseDTO">
|
||||||
|
select t1.id as id, t1.plan_id as planId, t1.executor as executor, t1.status as status, t1.results as results, t1.remark remard, t1.create_time as createTime, t1.update_time updateTime,
|
||||||
|
t2.id as caseId, t2.node_id as nodeId, t2.node_path as nodePath, t2.project_id as projectId, t2.name as name,
|
||||||
|
t2.type as type, t2.maintainer as maintainer, t2.priority as priority, t2.method as method, t2.prerequisite as prerequisite
|
||||||
|
from test_plan_test_case as t1
|
||||||
|
inner join test_case as t2 on
|
||||||
|
t1.plan_id = #{request.planId}
|
||||||
|
<if test="request.nodeIds != null and request.nodeIds.size() > 0">
|
||||||
|
and t2.node_id in
|
||||||
|
<foreach collection="request.nodeIds" open="(" close=")" separator="," item="nodeId">
|
||||||
|
#{nodeId}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
and t1.case_id = t2.id
|
||||||
|
<if test="request.name != null">
|
||||||
|
and t2.name like CONCAT('%', #{request.name},'%')
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
public enum TestPlanTestCaseStatus {
|
||||||
|
Prepare, Pass, Failure, Blocking, Skip
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||||
import io.metersphere.controller.request.testplan.QueryTestPlanRequest;
|
import io.metersphere.controller.request.testplan.QueryTestPlanRequest;
|
||||||
import io.metersphere.dto.LoadTestDTO;
|
import io.metersphere.dto.LoadTestDTO;
|
||||||
import io.metersphere.dto.TestCaseNodeDTO;
|
import io.metersphere.dto.TestCaseNodeDTO;
|
||||||
|
import io.metersphere.dto.TestPlanCaseDTO;
|
||||||
import io.metersphere.service.TestCaseNodeService;
|
import io.metersphere.service.TestCaseNodeService;
|
||||||
import io.metersphere.service.TestCaseService;
|
import io.metersphere.service.TestCaseService;
|
||||||
import io.metersphere.user.SessionUtils;
|
import io.metersphere.user.SessionUtils;
|
||||||
|
@ -38,6 +39,12 @@ public class TestCaseController {
|
||||||
return testCaseService.getTestCaseByNodeId(nodeIds);
|
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/all")
|
||||||
public List<TestCase> getTestCaseNames(@RequestBody QueryTestCaseRequest request){
|
public List<TestCase> getTestCaseNames(@RequestBody QueryTestCaseRequest request){
|
||||||
return testCaseService.getTestCaseNames(request);
|
return testCaseService.getTestCaseNames(request);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||||
import io.metersphere.base.domain.TestPlan;
|
import io.metersphere.base.domain.TestPlan;
|
||||||
import io.metersphere.commons.utils.PageUtils;
|
import io.metersphere.commons.utils.PageUtils;
|
||||||
import io.metersphere.commons.utils.Pager;
|
import io.metersphere.commons.utils.Pager;
|
||||||
|
import io.metersphere.controller.request.testcase.PlanCaseRelevanceRequest;
|
||||||
import io.metersphere.controller.request.testcase.QueryTestPlanRequest;
|
import io.metersphere.controller.request.testcase.QueryTestPlanRequest;
|
||||||
import io.metersphere.dto.TestPlanDTO;
|
import io.metersphere.dto.TestPlanDTO;
|
||||||
import io.metersphere.service.TestCaseService;
|
import io.metersphere.service.TestCaseService;
|
||||||
|
@ -49,5 +50,10 @@ public class TestPlanController {
|
||||||
return testPlanService.deleteTestPlan(testPlanId);
|
return testPlanService.deleteTestPlan(testPlanId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/relevance")
|
||||||
|
public void testPlanRelevance(@RequestBody PlanCaseRelevanceRequest request){
|
||||||
|
testPlanService.testPlanRelevance(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package io.metersphere.controller.request.testcase;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlanCaseRelevanceRequest {
|
||||||
|
|
||||||
|
private String planId;
|
||||||
|
private List<String> testCaseIds = new ArrayList<>();
|
||||||
|
|
||||||
|
public String getPlanId() {
|
||||||
|
return planId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlanId(String planId) {
|
||||||
|
this.planId = planId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTestCaseIds() {
|
||||||
|
return testCaseIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTestCaseIds(List<String> testCaseIds) {
|
||||||
|
this.testCaseIds = testCaseIds;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ import java.util.List;
|
||||||
|
|
||||||
public class QueryTestPlanRequest extends TestPlan {
|
public class QueryTestPlanRequest extends TestPlan {
|
||||||
|
|
||||||
private String workspaceId;
|
|
||||||
private boolean recent = false;
|
private boolean recent = false;
|
||||||
|
|
||||||
public boolean isRecent() {
|
public boolean isRecent() {
|
||||||
|
@ -17,12 +16,4 @@ public class QueryTestPlanRequest extends TestPlan {
|
||||||
public void setRecent(boolean recent) {
|
public void setRecent(boolean recent) {
|
||||||
this.recent = recent;
|
this.recent = recent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWorkspaceId() {
|
|
||||||
return workspaceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWorkspaceId(String workspaceId) {
|
|
||||||
this.workspaceId = workspaceId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package io.metersphere.dto;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.TestCase;
|
||||||
|
|
||||||
|
public class TestPlanCaseDTO extends TestCase {
|
||||||
|
|
||||||
|
private String executor;
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
public String getExecutor() {
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExecutor(String executor) {
|
||||||
|
this.executor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
|
@ -135,9 +135,10 @@ public class TestCaseNodeService {
|
||||||
.map(TestPlanTestCase::getCaseId)
|
.map(TestPlanTestCase::getCaseId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
List<Integer> nodeIds = nodes.stream()
|
TestCaseExample testCaseExample = new TestCaseExample();
|
||||||
.filter(node -> caseIds.contains(node.getId()))
|
testCaseExample.createCriteria().andIdIn(caseIds);
|
||||||
.map(TestCaseNode::getId)
|
List<Integer> dataNodeIds = testCaseMapper.selectByExample(testCaseExample).stream()
|
||||||
|
.map(TestCase::getNodeId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
List<TestCaseNodeDTO> nodeTrees = getNodeTrees(nodes);
|
List<TestCaseNodeDTO> nodeTrees = getNodeTrees(nodes);
|
||||||
|
@ -145,7 +146,7 @@ public class TestCaseNodeService {
|
||||||
Iterator<TestCaseNodeDTO> iterator = nodeTrees.iterator();
|
Iterator<TestCaseNodeDTO> iterator = nodeTrees.iterator();
|
||||||
while(iterator.hasNext()){
|
while(iterator.hasNext()){
|
||||||
TestCaseNodeDTO rootNode = iterator.next();
|
TestCaseNodeDTO rootNode = iterator.next();
|
||||||
if(pruningTree(rootNode, nodeIds)){
|
if(pruningTree(rootNode, dataNodeIds)){
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,6 +164,13 @@ public class TestCaseNodeService {
|
||||||
|
|
||||||
List<TestCaseNodeDTO> children = rootNode.getChildren();
|
List<TestCaseNodeDTO> children = rootNode.getChildren();
|
||||||
|
|
||||||
|
if(children == null || children.isEmpty()){
|
||||||
|
//叶子节点,并且该节点无数据
|
||||||
|
if(!nodeIds.contains(rootNode.getId())){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(children != null) {
|
if(children != null) {
|
||||||
Iterator<TestCaseNodeDTO> iterator = children.iterator();
|
Iterator<TestCaseNodeDTO> iterator = children.iterator();
|
||||||
while(iterator.hasNext()){
|
while(iterator.hasNext()){
|
||||||
|
@ -171,11 +179,8 @@ public class TestCaseNodeService {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(children == null || children.isEmpty()){
|
if (children.isEmpty() && !nodeIds.contains(rootNode.getId())) {
|
||||||
//叶子节点,并且该节点无数据
|
|
||||||
if(!nodeIds.contains(rootNode.getId())){
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
package io.metersphere.service;
|
package io.metersphere.service;
|
||||||
|
|
||||||
|
|
||||||
import io.metersphere.base.domain.TestCase;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.domain.TestCaseExample;
|
|
||||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
|
||||||
import io.metersphere.base.domain.TestPlan;
|
|
||||||
import io.metersphere.base.mapper.TestCaseMapper;
|
import io.metersphere.base.mapper.TestCaseMapper;
|
||||||
import io.metersphere.base.mapper.TestPlanMapper;
|
import io.metersphere.base.mapper.TestPlanMapper;
|
||||||
|
import io.metersphere.base.mapper.TestPlanTestCaseMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
||||||
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||||
|
import io.metersphere.dto.TestPlanCaseDTO;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -27,6 +29,9 @@ public class TestCaseService {
|
||||||
@Resource
|
@Resource
|
||||||
ExtTestCaseMapper extTestCaseMapper;
|
ExtTestCaseMapper extTestCaseMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
TestPlanTestCaseMapper testPlanTestCaseMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
TestPlanMapper testPlanMapper;
|
TestPlanMapper testPlanMapper;
|
||||||
|
|
||||||
|
@ -61,13 +66,13 @@ public class TestCaseService {
|
||||||
public List<TestCaseWithBLOBs> listTestCase(QueryTestCaseRequest request) {
|
public List<TestCaseWithBLOBs> listTestCase(QueryTestCaseRequest request) {
|
||||||
TestCaseExample testCaseExample = new TestCaseExample();
|
TestCaseExample testCaseExample = new TestCaseExample();
|
||||||
TestCaseExample.Criteria criteria = testCaseExample.createCriteria();
|
TestCaseExample.Criteria criteria = testCaseExample.createCriteria();
|
||||||
if( StringUtils.isNotBlank(request.getName()) ){
|
if ( StringUtils.isNotBlank(request.getName()) ) {
|
||||||
criteria.andNameLike("%" + request.getName() + "%");
|
criteria.andNameLike("%" + request.getName() + "%");
|
||||||
}
|
}
|
||||||
if( StringUtils.isNotBlank(request.getProjectId()) ){
|
if ( StringUtils.isNotBlank(request.getProjectId()) ) {
|
||||||
criteria.andProjectIdEqualTo(request.getProjectId());
|
criteria.andProjectIdEqualTo(request.getProjectId());
|
||||||
}
|
}
|
||||||
if( request.getNodeIds() != null && request.getNodeIds().size() > 0){
|
if ( request.getNodeIds() != null && request.getNodeIds().size() > 0) {
|
||||||
criteria.andNodeIdIn(request.getNodeIds());
|
criteria.andNodeIdIn(request.getNodeIds());
|
||||||
}
|
}
|
||||||
return testCaseMapper.selectByExampleWithBLOBs(testCaseExample);
|
return testCaseMapper.selectByExampleWithBLOBs(testCaseExample);
|
||||||
|
@ -75,10 +80,15 @@ public class TestCaseService {
|
||||||
|
|
||||||
public List<TestCase> getTestCaseNames(QueryTestCaseRequest request) {
|
public List<TestCase> getTestCaseNames(QueryTestCaseRequest request) {
|
||||||
|
|
||||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getPlanId());
|
if ( StringUtils.isNotBlank(request.getPlanId()) ) {
|
||||||
|
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getPlanId());
|
||||||
request.setProjectId(testPlan.getProjectId());
|
request.setProjectId(testPlan.getProjectId());
|
||||||
|
}
|
||||||
|
|
||||||
return extTestCaseMapper.getTestCaseNames(request);
|
return extTestCaseMapper.getTestCaseNames(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TestPlanCaseDTO> getTestPlanCases(QueryTestCaseRequest request) {
|
||||||
|
return extTestCaseMapper.getTestPlanTestCases(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,24 @@ package io.metersphere.service;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.TestCaseMapper;
|
import io.metersphere.base.mapper.TestCaseMapper;
|
||||||
import io.metersphere.base.mapper.TestPlanMapper;
|
import io.metersphere.base.mapper.TestPlanMapper;
|
||||||
|
import io.metersphere.base.mapper.TestPlanTestCaseMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
|
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
|
||||||
import io.metersphere.commons.constants.TestPlanStatus;
|
import io.metersphere.commons.constants.TestPlanStatus;
|
||||||
|
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
||||||
|
import io.metersphere.controller.request.testcase.PlanCaseRelevanceRequest;
|
||||||
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||||
import io.metersphere.controller.request.testcase.QueryTestPlanRequest;
|
import io.metersphere.controller.request.testcase.QueryTestPlanRequest;
|
||||||
import io.metersphere.dto.TestPlanDTO;
|
import io.metersphere.dto.TestPlanDTO;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
|
import org.apache.ibatis.session.SqlSession;
|
||||||
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.UUID;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -27,6 +33,15 @@ public class TestPlanService {
|
||||||
@Resource
|
@Resource
|
||||||
ExtTestPlanMapper extTestPlanMapper;
|
ExtTestPlanMapper extTestPlanMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
TestCaseMapper testCaseMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
TestPlanTestCaseMapper testPlanTestCaseMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
SqlSessionFactory sqlSessionFactory;
|
||||||
|
|
||||||
public void addTestPlan(TestPlan testPlan) {
|
public void addTestPlan(TestPlan testPlan) {
|
||||||
testPlan.setId(UUID.randomUUID().toString());
|
testPlan.setId(UUID.randomUUID().toString());
|
||||||
testPlan.setStatus(TestPlanStatus.Prepare.name());
|
testPlan.setStatus(TestPlanStatus.Prepare.name());
|
||||||
|
@ -54,4 +69,36 @@ public class TestPlanService {
|
||||||
public List<TestPlanDTO> listTestPlan(QueryTestPlanRequest request) {
|
public List<TestPlanDTO> listTestPlan(QueryTestPlanRequest request) {
|
||||||
return extTestPlanMapper.list(request);
|
return extTestPlanMapper.list(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPlanRelevance(PlanCaseRelevanceRequest request) {
|
||||||
|
|
||||||
|
List<String> testCaseIds = request.getTestCaseIds();
|
||||||
|
TestCaseExample testCaseExample = new TestCaseExample();
|
||||||
|
testCaseExample.createCriteria().andIdIn(testCaseIds);
|
||||||
|
|
||||||
|
Map<String, TestCaseWithBLOBs> testCaseMap =
|
||||||
|
testCaseMapper.selectByExampleWithBLOBs(testCaseExample)
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(TestCase::getId, testcase -> testcase));
|
||||||
|
|
||||||
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
TestPlanTestCaseMapper batchMapper = sqlSession.getMapper(TestPlanTestCaseMapper.class);
|
||||||
|
|
||||||
|
if (!testCaseIds.isEmpty()) {
|
||||||
|
testCaseIds.forEach(caseId -> {
|
||||||
|
TestCaseWithBLOBs testCase = testCaseMap.get(caseId);
|
||||||
|
TestPlanTestCase testPlanTestCase = new TestPlanTestCase();
|
||||||
|
testPlanTestCase.setExecutor(testCase.getMaintainer());
|
||||||
|
testPlanTestCase.setCaseId(caseId);
|
||||||
|
testPlanTestCase.setCreateTime(System.currentTimeMillis());
|
||||||
|
testPlanTestCase.setUpdateTime(System.currentTimeMillis());
|
||||||
|
testPlanTestCase.setPlanId(request.getPlanId());
|
||||||
|
testPlanTestCase.setStatus(TestPlanTestCaseStatus.Prepare.name());
|
||||||
|
testPlanTestCase.setResults(testCase.getSteps());
|
||||||
|
batchMapper.insert(testPlanTestCase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlSession.flushStatements();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@
|
||||||
option.id = node.id;
|
option.id = node.id;
|
||||||
option.path = option.path + '/' + node.name;
|
option.path = option.path + '/' + node.name;
|
||||||
moduleOptions.push(option);
|
moduleOptions.push(option);
|
||||||
if(node.children){
|
if (node.children) {
|
||||||
for (let i = 0; i < node.children.length; i++){
|
for (let i = 0; i < node.children.length; i++){
|
||||||
this.buildNodePath(node.children[i], { path: option.path }, moduleOptions);
|
this.buildNodePath(node.children[i], { path: option.path }, moduleOptions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
@node-drag-end="handleDragEnd"
|
@node-drag-end="handleDragEnd"
|
||||||
:filter-node-method="filterNode"
|
:filter-node-method="filterNode"
|
||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
|
highlight-current
|
||||||
draggable
|
draggable
|
||||||
ref="tree">
|
ref="tree">
|
||||||
|
|
||||||
|
@ -230,7 +231,7 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
width: 100px;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-tree {
|
.node-tree {
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
<el-select v-model="form.type" :placeholder="$t('test_track.input_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('commons.functional')" value="functional"></el-option>
|
||||||
<el-option :label="$t('commons.performance')" value="performance"></el-option>
|
<el-option :label="$t('commons.performance')" value="performance"></el-option>
|
||||||
<el-option :label="$t('commons.interface')" value="interface"></el-option>
|
<el-option :label="$t('commons.api')" value="api"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span v-if="scope.row.type == 'functional'">{{$t('commons.functional')}}</span>
|
<span v-if="scope.row.type == 'functional'">{{$t('commons.functional')}}</span>
|
||||||
<span v-if="scope.row.type == 'performance'">{{$t('commons.performance')}}</span>
|
<span v-if="scope.row.type == 'performance'">{{$t('commons.performance')}}</span>
|
||||||
<span v-if="scope.row.type == 'interface'">{{$t('commons.interface')}}</span>
|
<span v-if="scope.row.type == 'api'">{{$t('commons.api')}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
|
@ -2,25 +2,33 @@
|
||||||
|
|
||||||
<div class="plan_container">
|
<div class="plan_container">
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-aside width="250px">
|
<el-aside class="node-tree" width="250px">
|
||||||
<plan-node-tree
|
<plan-node-tree
|
||||||
:plan-id="planId"
|
:tree-nodes="treeNodes"
|
||||||
class="node_tree"
|
@nodeSelectEvent="getPlanCases"
|
||||||
@nodeSelectEvent="get"
|
ref="tree"></plan-node-tree>
|
||||||
ref="nodeTree"></plan-node-tree>
|
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
|
||||||
<el-main>
|
<el-main>
|
||||||
<test-case-plan-list
|
<test-case-plan-list
|
||||||
@openTestCaseRelevanceDialog="openTestCaseRelevanceDialog"
|
@openTestCaseRelevanceDialog="openTestCaseRelevanceDialog"
|
||||||
|
@editTestPlanTestCase="editTestPlanTestCase"
|
||||||
|
:plan-id="planId"
|
||||||
ref="testCasePlanList"></test-case-plan-list>
|
ref="testCasePlanList"></test-case-plan-list>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
|
||||||
<test-case-relevance
|
<test-case-relevance
|
||||||
@refresh="getCaseByNodeIds"
|
@refresh="getPlanCases"
|
||||||
|
:plan-id="planId"
|
||||||
ref="testCaseRelevance"></test-case-relevance>
|
ref="testCaseRelevance"></test-case-relevance>
|
||||||
|
|
||||||
|
<test-plan-test-case-edit
|
||||||
|
ref="testPlanTestCaseEdit">
|
||||||
|
|
||||||
|
</test-plan-test-case-edit>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -30,15 +38,19 @@
|
||||||
import PlanNodeTree from "./components/PlanNodeTree";
|
import PlanNodeTree from "./components/PlanNodeTree";
|
||||||
import TestCasePlanList from "./components/TestCasePlanList";
|
import TestCasePlanList from "./components/TestCasePlanList";
|
||||||
import TestCaseRelevance from "./components/TestCaseRelevance";
|
import TestCaseRelevance from "./components/TestCaseRelevance";
|
||||||
|
import TestPlanTestCaseEdit from "./components/TestPlanTestCaseEdit";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TestPlanView",
|
name: "TestPlanView",
|
||||||
components: {PlanNodeTree, TestCasePlanList, TestCaseRelevance},
|
components: {PlanNodeTree, TestCasePlanList, TestCaseRelevance, TestPlanTestCaseEdit},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentProject: {}
|
treeNodes: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.getNodeTreeByPlanId();
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
planId: function () {
|
planId: function () {
|
||||||
return this.$route.params.planId;
|
return this.$route.params.planId;
|
||||||
|
@ -48,14 +60,21 @@
|
||||||
refresh() {
|
refresh() {
|
||||||
|
|
||||||
},
|
},
|
||||||
get() {
|
getPlanCases(nodeIds) {
|
||||||
|
this.$refs.testCasePlanList(nodeIds);
|
||||||
},
|
},
|
||||||
openTestCaseRelevanceDialog() {
|
openTestCaseRelevanceDialog() {
|
||||||
this.$refs.testCaseRelevance.openTestCaseRelevanceDialog(this.planId);
|
this.$refs.testCaseRelevance.openTestCaseRelevanceDialog(this.planId);
|
||||||
},
|
},
|
||||||
getCaseByNodeIds() {
|
getNodeTreeByPlanId() {
|
||||||
|
if(this.planId){
|
||||||
|
this.$get("/case/node/list/plan/" + this.planId, response => {
|
||||||
|
this.treeNodes = response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editTestPlanTestCase() {
|
||||||
|
this.$refs.testPlanTestCaseEdit.drawer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,5 +87,9 @@
|
||||||
height: 600px;
|
height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.node-tree {
|
||||||
|
margin-top: 2%;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -10,10 +10,13 @@
|
||||||
@node-drag-end="handleDragEnd"
|
@node-drag-end="handleDragEnd"
|
||||||
:filter-node-method="filterNode"
|
:filter-node-method="filterNode"
|
||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
|
highlight-current
|
||||||
draggable
|
draggable
|
||||||
ref="tree">
|
ref="tree">
|
||||||
<template @click="selectNode(node)" v-slot:default="{node}">
|
<template v-slot:default="{node}">
|
||||||
{{node.label}}
|
<span class="custom-tree-node" @click="selectNode(node)">
|
||||||
|
{{node.label}}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,6 +45,11 @@
|
||||||
Array
|
Array
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
filterText(val) {
|
||||||
|
this.$refs.tree.filter(val);
|
||||||
|
}
|
||||||
|
},
|
||||||
selectNode(node) {
|
selectNode(node) {
|
||||||
let nodeIds = [];
|
let nodeIds = [];
|
||||||
this.getChildNodeId(node, nodeIds);
|
this.getChildNodeId(node, nodeIds);
|
||||||
|
@ -119,7 +127,7 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
width: 100px;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node-tree {
|
.node-tree {
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span v-if="scope.row.type == 'functional'">{{$t('commons.functional')}}</span>
|
<span v-if="scope.row.type == 'functional'">{{$t('commons.functional')}}</span>
|
||||||
<span v-if="scope.row.type == 'performance'">{{$t('commons.performance')}}</span>
|
<span v-if="scope.row.type == 'performance'">{{$t('commons.performance')}}</span>
|
||||||
<span v-if="scope.row.type == 'interface'">{{$t('commons.interface')}}</span>
|
<span v-if="scope.row.type == 'api'">{{$t('commons.api')}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
@ -68,19 +68,27 @@
|
||||||
<span v-if="scope.row.method == 'auto'">{{$t('test_track.auto')}}</span>
|
<span v-if="scope.row.method == 'auto'">{{$t('test_track.auto')}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="nodePath"
|
width="160"
|
||||||
:label="$t('test_track.module')"
|
prop="executor"
|
||||||
|
label="执行人">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
label="执行结果"
|
||||||
width="160"
|
width="160"
|
||||||
show-overflow-tooltip>
|
show-overflow-tooltip>
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
width="160"
|
|
||||||
:label="$t('commons.create_time')">
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
<span v-if="scope.row.status == 'Prepare'">未开始</span>
|
||||||
|
<span v-if="scope.row.status == 'Pass'">通过</span>
|
||||||
|
<span v-if="scope.row.status == 'Failure'">失败</span>
|
||||||
|
<span v-if="scope.row.status == 'Blocking'">阻塞</span>
|
||||||
|
<span v-if="scope.row.status == 'Skip'">跳过</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
width="160"
|
width="160"
|
||||||
:label="$t('commons.update_time')">
|
:label="$t('commons.update_time')">
|
||||||
|
@ -141,26 +149,29 @@
|
||||||
testId: null
|
testId: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
props:{
|
||||||
|
planId: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.initTableData();
|
this.initTableData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initTableData(nodeIds) {
|
initTableData(nodeIds) {
|
||||||
let param = {
|
if (this.planId) {
|
||||||
name: this.condition,
|
let param = {
|
||||||
};
|
name: this.condition,
|
||||||
param.nodeIds = nodeIds;
|
};
|
||||||
|
param.nodeIds = nodeIds;
|
||||||
if(localStorage.getItem(CURRENT_PROJECT)) {
|
param.planId = this.planId;
|
||||||
param.projectId = JSON.parse(localStorage.getItem(CURRENT_PROJECT)).id;
|
this.$post(this.buildPagePath('/test/case/plan/list'), param, response => {
|
||||||
|
this.loadingRequire.testCase = false;
|
||||||
|
let data = response.data;
|
||||||
|
this.total = data.itemCount;
|
||||||
|
this.tableData = data.listObject;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$post(this.buildPagePath('/test/case/list'), param, response => {
|
|
||||||
this.loadingRequire.testCase = false;
|
|
||||||
let data = response.data;
|
|
||||||
this.total = data.itemCount;
|
|
||||||
this.tableData = data.listObject;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
search() {
|
search() {
|
||||||
this.initTableData();
|
this.initTableData();
|
||||||
|
@ -180,7 +191,7 @@
|
||||||
this.multipleSelection = val;
|
this.multipleSelection = val;
|
||||||
},
|
},
|
||||||
handleEdit(testCase) {
|
handleEdit(testCase) {
|
||||||
this.$emit('testCaseRelevance', testCase);
|
this.$emit('editTestPlanTestCase', testCase);
|
||||||
},
|
},
|
||||||
handleDelete(testCase) {
|
handleDelete(testCase) {
|
||||||
this.$alert(this.$t('load_test.delete_confirm') + testCase.name + "?", '', {
|
this.$alert(this.$t('load_test.delete_confirm') + testCase.name + "?", '', {
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
|
|
||||||
<el-dialog title="关联测试用例"
|
<el-dialog title="关联测试用例"
|
||||||
:visible.sync="dialogFormVisible"
|
:visible.sync="dialogFormVisible"
|
||||||
width="65%">
|
width="50%">
|
||||||
|
|
||||||
<el-container class="main-content">
|
<el-container class="main-content">
|
||||||
<el-aside class="node-tree" width="250px">
|
<el-aside class="node-tree" width="250px">
|
||||||
<plan-node-tree
|
<plan-node-tree
|
||||||
:tree-nodes="treeNodes" ref="tree"></plan-node-tree>
|
:tree-nodes="treeNodes"
|
||||||
|
@nodeSelectEvent="getCaseNameByNodeIds"
|
||||||
|
ref="tree"></plan-node-tree>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
|
||||||
<el-container>
|
<el-container>
|
||||||
|
@ -23,16 +25,12 @@
|
||||||
ref="table">
|
ref="table">
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
type="selection"
|
type="selection"></el-table-column>
|
||||||
:reserve-selection="true"></el-table-column>
|
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="name"
|
prop="name"
|
||||||
label="用例名称"
|
label="用例名称"
|
||||||
style="width: 100%">
|
style="width: 100%">
|
||||||
<template v-slot:header>
|
|
||||||
用例名称
|
|
||||||
</template>
|
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
{{scope.row.name}}
|
{{scope.row.name}}
|
||||||
</template>
|
</template>
|
||||||
|
@ -79,28 +77,45 @@
|
||||||
treeNodes: []
|
treeNodes: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
planId: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openTestCaseRelevanceDialog(planId) {
|
openTestCaseRelevanceDialog(planId) {
|
||||||
console.log(planId);
|
console.log(planId);
|
||||||
this.getNodeTreeByPlanId(planId);
|
this.getAllNodeTreeByPlanId(planId);
|
||||||
console.log(this.$refs);
|
console.log(this.$refs);
|
||||||
this.getCaseNames(planId);
|
this.getCaseNames(planId);
|
||||||
this.dialogFormVisible = true;
|
this.dialogFormVisible = true;
|
||||||
},
|
},
|
||||||
saveCaseRelevance(){
|
saveCaseRelevance(){
|
||||||
|
let param = {};
|
||||||
|
param.planId = this.planId;
|
||||||
|
param.testCaseIds = [...this.selectIds];
|
||||||
|
this.$post('/test/plan/relevance' , param, () => {
|
||||||
|
this.$message.success("保存成功");
|
||||||
|
});
|
||||||
},
|
},
|
||||||
getCaseNames(planId) {
|
getCaseNames(planId, nodeIds) {
|
||||||
if(planId){
|
let param = {};
|
||||||
let param = {};
|
if (planId) {
|
||||||
param.planId = planId;
|
param.planId = planId;
|
||||||
this.$post('/test/case/name/all', param, response => {
|
|
||||||
this.testCases = response.data;
|
|
||||||
this.testCases.forEach(item => {
|
|
||||||
item.checked = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
if (nodeIds && nodeIds.length > 0){
|
||||||
|
param.nodeIds = nodeIds;
|
||||||
|
}
|
||||||
|
this.$post('/test/case/name/all', param, response => {
|
||||||
|
this.testCases = response.data;
|
||||||
|
this.testCases.forEach(item => {
|
||||||
|
item.checked = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getCaseNameByNodeIds(nodeIds) {
|
||||||
|
this.dialogFormVisible = true;
|
||||||
|
this.getCaseNames(null, nodeIds);
|
||||||
},
|
},
|
||||||
checkAll() {
|
checkAll() {
|
||||||
this.testCases.forEach(item => {
|
this.testCases.forEach(item => {
|
||||||
|
@ -124,14 +139,13 @@
|
||||||
this.selectIds.add(row.id);
|
this.selectIds.add(row.id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getNodeTreeByPlanId(planId) {
|
getAllNodeTreeByPlanId(planId) {
|
||||||
if(planId){
|
if (planId) {
|
||||||
this.$get("/case/node/list/all/plan/" + planId, response => {
|
this.$get("/case/node/list/all/plan/" + planId, response => {
|
||||||
this.treeNodes = response.data;
|
this.treeNodes = response.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -155,7 +169,7 @@
|
||||||
/*border-radius: 1px;*/
|
/*border-radius: 1px;*/
|
||||||
/*padding-top: 5px ;*/
|
/*padding-top: 5px ;*/
|
||||||
/*height: 100%;*/
|
/*height: 100%;*/
|
||||||
margin-right: 5px;
|
margin-right: 10px;
|
||||||
/*box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);*/
|
/*box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +177,6 @@
|
||||||
background-color: darkgrey;
|
background-color: darkgrey;
|
||||||
color: #333;
|
color: #333;
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
height: 1%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-aside {
|
.el-aside {
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
testId: null,
|
testId: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created() {
|
||||||
this.projectId = this.$route.params.projectId;
|
this.projectId = this.$route.params.projectId;
|
||||||
this.initTableData();
|
this.initTableData();
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<el-drawer
|
||||||
|
title="我是标题"
|
||||||
|
:visible.sync="drawer"
|
||||||
|
:direction="direction"
|
||||||
|
:before-close="handleClose">
|
||||||
|
<span>我来啦!</span>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TestPlanTestCaseEdit",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
drawer: false,
|
||||||
|
direction: 'rtl',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -40,7 +40,6 @@ export default {
|
||||||
'system_setting': 'Settings',
|
'system_setting': 'Settings',
|
||||||
'api': 'Api',
|
'api': 'Api',
|
||||||
'performance': 'Performance',
|
'performance': 'Performance',
|
||||||
'interface': 'Interface test',
|
|
||||||
'input_content': 'Please enter content',
|
'input_content': 'Please enter content',
|
||||||
'create': 'create',
|
'create': 'create',
|
||||||
'refresh': 'refresh',
|
'refresh': 'refresh',
|
||||||
|
|
|
@ -40,7 +40,6 @@ export default {
|
||||||
'system_setting': '系统设置',
|
'system_setting': '系统设置',
|
||||||
'api': '接口测试',
|
'api': '接口测试',
|
||||||
'performance': '性能测试',
|
'performance': '性能测试',
|
||||||
'interface': '接口测试',
|
|
||||||
'input_content': '请输入内容',
|
'input_content': '请输入内容',
|
||||||
'create': '新建',
|
'create': '新建',
|
||||||
'refresh': '刷新',
|
'refresh': '刷新',
|
||||||
|
|
Loading…
Reference in New Issue