测试计划关联用例及执行
This commit is contained in:
@@ -8,6 +8,7 @@ import com.test.common.enums.BusinessType;
|
||||
import com.test.common.utils.DateUtils;
|
||||
import com.test.common.utils.uuid.IdUtils;
|
||||
import com.test.test.domain.TestCase;
|
||||
import com.test.test.domain.TestPlanCase;
|
||||
import com.test.test.domain.qo.IDQO;
|
||||
import com.test.test.domain.qo.TestCaseListQO;
|
||||
import com.test.test.service.ITestCaseService;
|
||||
@@ -44,6 +45,16 @@ public class TestCaseController extends BaseController {
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询测试计划可关联的用例列表
|
||||
*/
|
||||
@GetMapping("/planRelateList")
|
||||
public TableDataInfo planRelateList(TestCaseListQO qo) {
|
||||
startPage();
|
||||
List<TestCase> list = testCaseService.selectValidTestPlanCaseList(qo);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用例详细信息
|
||||
*/
|
||||
@@ -108,4 +119,18 @@ public class TestCaseController extends BaseController {
|
||||
testCaseService.executeTestCaseById(qo.getId(), jmeterHomePath, caseSid);
|
||||
return AjaxResult.success("执行成功", caseSid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行测试计划用例
|
||||
*/
|
||||
@Log(title = "用例", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/runTestPlanCase")
|
||||
public AjaxResult runTestPlanCase(@RequestBody TestPlanCase testPlanCase) {
|
||||
String caseSid = IdUtils.simpleUUID();
|
||||
// 异步执行任务
|
||||
CompletableFuture.runAsync(() -> {
|
||||
testCaseService.executeTestCaseByPlanCase(testPlanCase, jmeterHomePath, caseSid);
|
||||
});
|
||||
return toAjax(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.test.test.controller;
|
||||
|
||||
import com.test.common.annotation.Log;
|
||||
import com.test.common.core.controller.BaseController;
|
||||
import com.test.common.core.domain.AjaxResult;
|
||||
import com.test.common.core.page.TableDataInfo;
|
||||
import com.test.common.enums.BusinessType;
|
||||
import com.test.test.domain.TestPlanCase;
|
||||
import com.test.test.domain.qo.TestPlanCaseQO;
|
||||
import com.test.test.service.ITestPlanCaseService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试计划用例关联Controller
|
||||
*
|
||||
* @author test
|
||||
* @date 2025-04-25
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/test/planCase")
|
||||
public class TestPlanCaseController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ITestPlanCaseService testPlanCaseService;
|
||||
|
||||
/**
|
||||
* 查询测试计划用例关联列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(TestPlanCase testPlanCase)
|
||||
{
|
||||
startPage();
|
||||
List<TestPlanCase> list = testPlanCaseService.selectTestPlanCaseList(testPlanCase);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出测试计划用例关联列表
|
||||
*/
|
||||
// @Log(title = "测试计划用例关联", businessType = BusinessType.EXPORT)
|
||||
// @PostMapping("/export")
|
||||
// public void export(HttpServletResponse response, TestPlanCase testPlanCase)
|
||||
// {
|
||||
// List<TestPlanCase> list = testPlanCaseService.selectTestPlanCaseList(testPlanCase);
|
||||
// ExcelUtil<TestPlanCase> util = new ExcelUtil<TestPlanCase>(TestPlanCase.class);
|
||||
// util.exportExcel(response, list, "测试计划用例关联数据");
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取测试计划用例关联详细信息
|
||||
*/
|
||||
// @GetMapping(value = "/{id}")
|
||||
// public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||
// {
|
||||
// return success(testPlanCaseService.selectTestPlanCaseById(id));
|
||||
// }
|
||||
|
||||
/**
|
||||
* 新增测试计划用例关联
|
||||
*/
|
||||
@Log(title = "测试计划用例关联", businessType = BusinessType.INSERT)
|
||||
@PostMapping(value = "/saveRelate")
|
||||
public AjaxResult saveRelate(@RequestBody TestPlanCaseQO qo)
|
||||
{
|
||||
testPlanCaseService.saveRelate(qo);
|
||||
return success(qo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改测试计划用例关联
|
||||
*/
|
||||
// @Log(title = "测试计划用例关联", businessType = BusinessType.UPDATE)
|
||||
// @PutMapping
|
||||
// public AjaxResult edit(@RequestBody TestPlanCase testPlanCase)
|
||||
// {
|
||||
// return toAjax(testPlanCaseService.updateTestPlanCase(testPlanCase));
|
||||
// }
|
||||
|
||||
/**
|
||||
* 删除测试计划用例关联
|
||||
*/
|
||||
@Log(title = "测试计划用例关联", businessType = BusinessType.DELETE)
|
||||
@PostMapping("/delRelate/{ids}")
|
||||
public AjaxResult remove(@PathVariable("ids") Long[] ids)
|
||||
{
|
||||
return toAjax(testPlanCaseService.deleteTestPlanCaseByIds(ids));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.test.test.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.test.common.annotation.Excel;
|
||||
import com.test.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 测试计划用例关联对象 test_plan_case
|
||||
*
|
||||
* @author test
|
||||
* @date 2025-04-25
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class TestPlanCase extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键 */
|
||||
private Long id;
|
||||
|
||||
/** 测试计划主键ID */
|
||||
@Excel(name = "测试计划主键ID")
|
||||
private Long planId;
|
||||
|
||||
/** 用例主键ID */
|
||||
@Excel(name = "用例主键ID")
|
||||
private Long caseId;
|
||||
|
||||
/** 测试用例类型(0,冒烟测试,1,功能测试,2,回归测试,3,准生产测试,4,生产验证) */
|
||||
@Excel(name = "测试用例类型(0,冒烟测试,1,功能测试,2,回归测试,3,准生产测试,4,生产验证)")
|
||||
private Integer type;
|
||||
|
||||
/** 未执行、成功或失败 */
|
||||
@Excel(name = "未执行、成功或失败")
|
||||
private String executeResult;
|
||||
|
||||
/** 执行时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "执行时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date executeTime;
|
||||
|
||||
/** 执行人 */
|
||||
@Excel(name = "执行人")
|
||||
private String executeBy;
|
||||
|
||||
/** 版本 */
|
||||
@Excel(name = "版本")
|
||||
private String version;
|
||||
|
||||
/** 0,正常,1,删除 */
|
||||
private String delFlag;
|
||||
|
||||
/** 未执行、成功或失败 */
|
||||
@Excel(name = "用例名称")
|
||||
private String caseName;
|
||||
}
|
||||
@@ -3,8 +3,18 @@ package com.test.test.domain.qo;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class TestCaseListQO {
|
||||
public class TestCaseListQO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4636502018355979101L;
|
||||
@NotNull(message = "父节点id不能为空")
|
||||
private Long groupId;
|
||||
/** 测试计划主键ID */
|
||||
private Long planId;
|
||||
/**
|
||||
* 测试用例类型(0,冒烟测试,1,功能测试,2,回归测试,3,准生产测试,4,生产验证)
|
||||
*/
|
||||
private Integer type;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.test.test.domain.qo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author liangdaliang
|
||||
* @Description:测试计划关联用例
|
||||
* @date 2025-04-27 13:16
|
||||
*/
|
||||
@Data
|
||||
public class TestPlanCaseQO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4636202018365979101L;
|
||||
private Long planId;
|
||||
private Integer type;
|
||||
private List<Long> testCaseIdList;
|
||||
}
|
||||
@@ -20,6 +20,11 @@ public interface TestCaseMapper
|
||||
*/
|
||||
List<TestCase> selectTestCaseList(TestCaseListQO qo);
|
||||
|
||||
/**
|
||||
* 查询测试计划可关联的用例列表
|
||||
*/
|
||||
List<TestCase> selectValidTestPlanCaseList(TestCaseListQO qo);
|
||||
|
||||
/**
|
||||
* 查询用例列表
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.test.test.mapper;
|
||||
|
||||
import com.test.test.domain.TestPlanCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试计划用例关联Mapper接口
|
||||
*
|
||||
* @author test
|
||||
* @date 2025-04-25
|
||||
*/
|
||||
public interface TestPlanCaseMapper
|
||||
{
|
||||
/**
|
||||
* 查询测试计划用例关联
|
||||
*
|
||||
* @param id 测试计划用例关联主键
|
||||
* @return 测试计划用例关联
|
||||
*/
|
||||
public TestPlanCase selectTestPlanCaseById(Long id);
|
||||
|
||||
/**
|
||||
* 查询测试计划用例关联列表
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 测试计划用例关联集合
|
||||
*/
|
||||
public List<TestPlanCase> selectTestPlanCaseList(TestPlanCase testPlanCase);
|
||||
|
||||
/**
|
||||
* 新增测试计划用例关联
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertTestPlanCase(TestPlanCase testPlanCase);
|
||||
|
||||
/**
|
||||
* 修改测试计划用例关联
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateTestPlanCase(TestPlanCase testPlanCase);
|
||||
|
||||
/**
|
||||
* 删除测试计划用例关联
|
||||
*
|
||||
* @param id 测试计划用例关联主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestPlanCaseById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除测试计划用例关联
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestPlanCaseByIds(Long[] ids);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.test.test.service;
|
||||
|
||||
import com.test.test.domain.TestCase;
|
||||
import com.test.test.domain.TestPlanCase;
|
||||
import com.test.test.domain.qo.TestCaseListQO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -29,6 +30,13 @@ public interface ITestCaseService
|
||||
*/
|
||||
public List<TestCase> selectTestCaseList(TestCaseListQO qo);
|
||||
|
||||
/**
|
||||
* 查询测试计划可关联的用例列表
|
||||
* @param qo 用例
|
||||
* @return 用例集合
|
||||
*/
|
||||
public List<TestCase> selectValidTestPlanCaseList(TestCaseListQO qo);
|
||||
|
||||
/**
|
||||
* 查询用例列表
|
||||
* @param testCase
|
||||
@@ -77,4 +85,14 @@ public interface ITestCaseService
|
||||
* @return 是否成功
|
||||
*/
|
||||
public String executeTestCaseById(Long id, String jmeterHomePath, String caseSid);
|
||||
|
||||
/**
|
||||
* 执行测试计划关联的用例
|
||||
*
|
||||
* @param testPlanCase 测试计划关联用例查询条件
|
||||
* @param jmeterHomePath jmeter安装路径
|
||||
* @param caseSid 用例执行uuid
|
||||
* @return 是否成功
|
||||
*/
|
||||
public void executeTestCaseByPlanCase(TestPlanCase testPlanCase, String jmeterHomePath, String caseSid);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.test.test.service;
|
||||
|
||||
import com.test.test.domain.TestPlanCase;
|
||||
import com.test.test.domain.qo.TestPlanCaseQO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试计划用例关联Service接口
|
||||
*
|
||||
* @author test
|
||||
* @date 2025-04-25
|
||||
*/
|
||||
public interface ITestPlanCaseService
|
||||
{
|
||||
/**
|
||||
* 查询测试计划用例关联
|
||||
*
|
||||
* @param id 测试计划用例关联主键
|
||||
* @return 测试计划用例关联
|
||||
*/
|
||||
public TestPlanCase selectTestPlanCaseById(Long id);
|
||||
|
||||
/**
|
||||
* 查询测试计划用例关联列表
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 测试计划用例关联集合
|
||||
*/
|
||||
public List<TestPlanCase> selectTestPlanCaseList(TestPlanCase testPlanCase);
|
||||
|
||||
/**
|
||||
* 保存测试计划用例关联列表
|
||||
*
|
||||
* @param testPlanCaseQO 测试计划用例关联
|
||||
* @return
|
||||
*/
|
||||
public void saveRelate(TestPlanCaseQO testPlanCaseQO);
|
||||
|
||||
/**
|
||||
* 新增测试计划用例关联
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertTestPlanCase(TestPlanCase testPlanCase);
|
||||
|
||||
/**
|
||||
* 修改测试计划用例关联
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateTestPlanCase(TestPlanCase testPlanCase);
|
||||
|
||||
/**
|
||||
* 批量删除测试计划用例关联
|
||||
*
|
||||
* @param ids 需要删除的测试计划用例关联主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestPlanCaseByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除测试计划用例关联信息
|
||||
*
|
||||
* @param id 测试计划用例关联主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestPlanCaseById(Long id);
|
||||
}
|
||||
@@ -4,17 +4,11 @@ import com.fatboyindustrial.gsonjavatime.LocalDateTimeConverter;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.test.common.utils.DateUtils;
|
||||
import com.test.common.utils.JMeterUtil;
|
||||
import com.test.common.utils.MySQLExecutor;
|
||||
import com.test.common.utils.StringUtils;
|
||||
import com.test.common.utils.*;
|
||||
import com.test.common.utils.sql.TinyIntTypeAdapter;
|
||||
import com.test.test.domain.*;
|
||||
import com.test.test.domain.qo.*;
|
||||
import com.test.test.mapper.TestCaseLogMapper;
|
||||
import com.test.test.mapper.TestCaseMapper;
|
||||
import com.test.test.mapper.TestCaseResultMapper;
|
||||
import com.test.test.mapper.TestDatasourceMapper;
|
||||
import com.test.test.mapper.*;
|
||||
import com.test.test.service.ITestCaseService;
|
||||
import com.test.test.service.ITestCaseStepService;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -49,6 +43,10 @@ public class TestCaseServiceImpl implements ITestCaseService
|
||||
private TestDatasourceMapper testDatasourceMapper;
|
||||
@Resource
|
||||
private TestCaseLogMapper testCaseLogMapper;
|
||||
@Resource
|
||||
private TestPlanMapper testPlanMapper;
|
||||
@Resource
|
||||
private TestPlanCaseMapper testPlanCaseMapper;
|
||||
|
||||
@Autowired
|
||||
private ITestCaseStepService testCaseStepService;
|
||||
@@ -76,6 +74,14 @@ public class TestCaseServiceImpl implements ITestCaseService
|
||||
return testCaseMapper.selectTestCaseList(qo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询测试计划可关联的用例列表
|
||||
*/
|
||||
@Override
|
||||
public List<TestCase> selectValidTestPlanCaseList(TestCaseListQO qo) {
|
||||
return testCaseMapper.selectValidTestPlanCaseList(qo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TestCase> selectTestCaseList(TestCase testCase) {
|
||||
return testCaseMapper.selectTestCaseListNoGroupId(testCase);
|
||||
@@ -201,6 +207,102 @@ public class TestCaseServiceImpl implements ITestCaseService
|
||||
return caseSid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行测试计划关联的用例
|
||||
*
|
||||
* @param testPlanCase 测试计划关联用例查询条件
|
||||
* @param jmeterHomePath jmeter安装路径
|
||||
* @param caseSid 用例执行uuid
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public void executeTestCaseByPlanCase(TestPlanCase testPlanCase, String jmeterHomePath, String caseSid) {
|
||||
List<TestPlanCase> testPlanCaseList = testPlanCaseMapper.selectTestPlanCaseList(testPlanCase);
|
||||
if (CollectionUtils.isEmpty(testPlanCaseList)) {
|
||||
log.error("计划关联测试用例为空,不能执行!");
|
||||
return ;
|
||||
}
|
||||
TestPlan testPlan = testPlanMapper.selectTestPlanById(testPlanCase.getPlanId());
|
||||
testPlan.setStatus("1");
|
||||
testPlan.setUpdateTime(DateUtils.getNowDate());
|
||||
testPlanMapper.updateTestPlan(testPlan);
|
||||
for (TestPlanCase input : testPlanCaseList) {
|
||||
boolean isSuccess = true;
|
||||
input.setExecuteTime(DateUtils.getNowDate());
|
||||
input.setExecuteBy(SecurityUtils.getUsername());
|
||||
TestCase testCase = this.selectTestCaseById(input.getCaseId());
|
||||
Long id = input.getCaseId();
|
||||
Map<String, String> contextResultMap = new HashMap<>();
|
||||
testCase.setContextResultMap(contextResultMap);
|
||||
TestCaseLog testCaseLog = new TestCaseLog();
|
||||
testCaseLog.setCaseId(id);
|
||||
testCaseLog.setOperTime(DateUtils.getNowDate());
|
||||
testCaseLog.setOperType("执行");
|
||||
testCaseLog.setCaseSid(caseSid);
|
||||
testCase.setCaseSid(caseSid);
|
||||
List<TestCaseStep> testCaseStepList = testCaseStepService.selectTestCaseStepListByCaseId(id);
|
||||
for (TestCaseStep testCaseStep : testCaseStepList) {
|
||||
if (testCaseStep.getType() == 1L) {
|
||||
// http接口处理
|
||||
boolean httpTestResult = doHttpRequestTest(testCase, testCaseStep, jmeterHomePath);
|
||||
if (!httpTestResult) {
|
||||
testCaseLog.setOperDetail("失败");
|
||||
testCaseLogMapper.insertTestCaseLog(testCaseLog);
|
||||
log.error("用例步骤:{}执行失败!", testCaseStep.getName());
|
||||
isSuccess = false;
|
||||
break;
|
||||
}
|
||||
} else if (testCaseStep.getType() == 2L) {
|
||||
// 数据库接口处理
|
||||
boolean dateSourceTestResult = doDateSourceRequestTest(testCase, testCaseStep);
|
||||
if (!dateSourceTestResult) {
|
||||
testCaseLog.setOperDetail("失败");
|
||||
testCaseLogMapper.insertTestCaseLog(testCaseLog);
|
||||
log.error("数据源用例步骤:{}执行失败!", testCaseStep.getName());
|
||||
isSuccess = false;
|
||||
break;
|
||||
}
|
||||
} else if (testCaseStep.getType() == 3L) {
|
||||
// 循环节点处理
|
||||
boolean pollTestResult = doPollRequestTest(testCase, testCaseStep, jmeterHomePath);
|
||||
if (!pollTestResult) {
|
||||
testCaseLog.setOperDetail("失败");
|
||||
testCaseLogMapper.insertTestCaseLog(testCaseLog);
|
||||
log.error("循环用例步骤:{}执行失败!", testCaseStep.getName());
|
||||
isSuccess = false;
|
||||
break;
|
||||
}
|
||||
} else if (testCaseStep.getType() == 4L) {
|
||||
// 轮询节点处理
|
||||
boolean loopTestResult = doLoopRequestTest(testCase, testCaseStep, jmeterHomePath);
|
||||
if (!loopTestResult) {
|
||||
testCaseLog.setOperDetail("失败");
|
||||
testCaseLogMapper.insertTestCaseLog(testCaseLog);
|
||||
log.error("轮询用例步骤:{}执行失败!", testCaseStep.getName());
|
||||
isSuccess = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
log.error("错误的用例步骤类型!");
|
||||
isSuccess = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isSuccess) {
|
||||
testCaseLog.setOperDetail("成功");
|
||||
input.setExecuteResult("成功");
|
||||
} else {
|
||||
testCaseLog.setOperDetail("失败");
|
||||
input.setExecuteResult("失败");
|
||||
}
|
||||
testCaseLogMapper.insertTestCaseLog(testCaseLog);
|
||||
testPlanCaseMapper.updateTestPlanCase(input);
|
||||
}
|
||||
testPlan.setUpdateTime(DateUtils.getNowDate());
|
||||
testPlan.setStatus("2");
|
||||
testPlanMapper.updateTestPlan(testPlan);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理http接口测试
|
||||
* @param testCase
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.test.test.service.impl;
|
||||
|
||||
import com.test.common.utils.DateUtils;
|
||||
import com.test.common.utils.SecurityUtils;
|
||||
import com.test.test.domain.TestPlanCase;
|
||||
import com.test.test.domain.qo.TestPlanCaseQO;
|
||||
import com.test.test.mapper.TestPlanCaseMapper;
|
||||
import com.test.test.service.ITestPlanCaseService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试计划用例关联Service业务层处理
|
||||
*
|
||||
* @author test
|
||||
* @date 2025-04-25
|
||||
*/
|
||||
@Service
|
||||
public class TestPlanCaseServiceImpl implements ITestPlanCaseService
|
||||
{
|
||||
@Resource
|
||||
private TestPlanCaseMapper testPlanCaseMapper;
|
||||
|
||||
/**
|
||||
* 查询测试计划用例关联
|
||||
*
|
||||
* @param id 测试计划用例关联主键
|
||||
* @return 测试计划用例关联
|
||||
*/
|
||||
@Override
|
||||
public TestPlanCase selectTestPlanCaseById(Long id)
|
||||
{
|
||||
return testPlanCaseMapper.selectTestPlanCaseById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询测试计划用例关联列表
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 测试计划用例关联
|
||||
*/
|
||||
@Override
|
||||
public List<TestPlanCase> selectTestPlanCaseList(TestPlanCase testPlanCase)
|
||||
{
|
||||
return testPlanCaseMapper.selectTestPlanCaseList(testPlanCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存测试计划用例关联列表
|
||||
*
|
||||
* @param testPlanCaseQO 测试计划用例关联
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void saveRelate(TestPlanCaseQO testPlanCaseQO)
|
||||
{
|
||||
List<Long> testCaseIdList = testPlanCaseQO.getTestCaseIdList();
|
||||
for (Long testCaseId : testCaseIdList) {
|
||||
TestPlanCase testPlanCase = new TestPlanCase();
|
||||
testPlanCase.setPlanId(testPlanCaseQO.getPlanId());
|
||||
testPlanCase.setCaseId(testCaseId);
|
||||
testPlanCase.setType(testPlanCaseQO.getType());
|
||||
List<TestPlanCase> testPlanCaseList = selectTestPlanCaseList(testPlanCase);
|
||||
if (!CollectionUtils.isEmpty(testPlanCaseList)) {
|
||||
// 防止重复
|
||||
continue;
|
||||
}
|
||||
testPlanCase.setCreateBy(SecurityUtils.getUsername());
|
||||
testPlanCase.setCreateTime(DateUtils.getNowDate());
|
||||
testPlanCaseMapper.insertTestPlanCase(testPlanCase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增测试计划用例关联
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertTestPlanCase(TestPlanCase testPlanCase)
|
||||
{
|
||||
testPlanCase.setCreateTime(DateUtils.getNowDate());
|
||||
return testPlanCaseMapper.insertTestPlanCase(testPlanCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改测试计划用例关联
|
||||
*
|
||||
* @param testPlanCase 测试计划用例关联
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateTestPlanCase(TestPlanCase testPlanCase)
|
||||
{
|
||||
testPlanCase.setUpdateTime(DateUtils.getNowDate());
|
||||
return testPlanCaseMapper.updateTestPlanCase(testPlanCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除测试计划用例关联
|
||||
*
|
||||
* @param ids 需要删除的测试计划用例关联主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestPlanCaseByIds(Long[] ids)
|
||||
{
|
||||
return testPlanCaseMapper.deleteTestPlanCaseByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除测试计划用例关联信息
|
||||
*
|
||||
* @param id 测试计划用例关联主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestPlanCaseById(Long id)
|
||||
{
|
||||
return testPlanCaseMapper.deleteTestPlanCaseById(id);
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,30 @@
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectValidTestPlanCaseList" parameterType="TestCaseListQO" resultMap="TestCaseResult">
|
||||
select tc.id,
|
||||
tc.group_id,
|
||||
tc.project_id,
|
||||
tc.name,
|
||||
tc.importance,
|
||||
tc.status,
|
||||
tc.del_flag,
|
||||
tc.create_by,
|
||||
tc.create_time,
|
||||
tc.update_by,
|
||||
tc.update_time
|
||||
from test_case tc
|
||||
where tc.del_flag = '0'
|
||||
<if test="groupId != null and groupId != ''">
|
||||
and tc.group_id = #{groupId}
|
||||
</if>
|
||||
and not exists(select 1 from test_plan_case tp
|
||||
where tc.id = tp.case_id
|
||||
and tp.plan_id = #{planId}
|
||||
and tp.type = #{type})
|
||||
order by tc.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectTestCaseListNoGroupId" parameterType="TestCase" resultMap="TestCaseResult">
|
||||
<include refid="selectTestCaseVo"/>
|
||||
<where>
|
||||
|
||||
111
test-test/src/main/resources/mapper/test/TestPlanCaseMapper.xml
Normal file
111
test-test/src/main/resources/mapper/test/TestPlanCaseMapper.xml
Normal file
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.test.test.mapper.TestPlanCaseMapper">
|
||||
|
||||
<resultMap type="TestPlanCase" id="TestPlanCaseResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="planId" column="plan_id" />
|
||||
<result property="caseId" column="case_id" />
|
||||
<result property="type" column="type" />
|
||||
<result property="executeResult" column="execute_result" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="executeTime" column="execute_time" />
|
||||
<result property="executeBy" column="execute_by" />
|
||||
<result property="version" column="version" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="caseName" column="name" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectTestPlanCaseVo">
|
||||
select id, plan_id, case_id, type, execute_result, create_time, create_by, update_time, execute_time, execute_by, version, del_flag from test_plan_case
|
||||
</sql>
|
||||
|
||||
<select id="selectTestPlanCaseList" parameterType="TestPlanCase" resultMap="TestPlanCaseResult">
|
||||
SELECT
|
||||
tp.id,
|
||||
tp.case_id,
|
||||
tc.name ,
|
||||
tp.execute_result,
|
||||
tp.create_by,
|
||||
tp.execute_by,
|
||||
tp.execute_time,
|
||||
tp.create_time
|
||||
FROM test_plan_case tp
|
||||
LEFT JOIN test_case tc ON tc.id = tp.case_id
|
||||
where tp.del_flag = '0'
|
||||
<if test="caseName != null and caseName != ''"> AND tc.name LIKE concat('%', #{caseName}, '%') </if>
|
||||
<if test="caseId != null"> and case_id = #{caseId}</if>
|
||||
<if test="type != null"> and type = #{type}</if>
|
||||
<if test="planId != null"> and plan_id = #{planId}</if>
|
||||
</select>
|
||||
|
||||
<select id="selectTestPlanCaseById" parameterType="Long" resultMap="TestPlanCaseResult">
|
||||
<include refid="selectTestPlanCaseVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<insert id="insertTestPlanCase" parameterType="TestPlanCase">
|
||||
insert into test_plan_case
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">id,</if>
|
||||
<if test="planId != null and planId != ''">plan_id,</if>
|
||||
<if test="caseId != null and caseId != ''">case_id,</if>
|
||||
type,
|
||||
<if test="executeResult != null">execute_result,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="executeTime != null">execute_time,</if>
|
||||
<if test="executeBy != null">execute_by,</if>
|
||||
<if test="version != null">version,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">#{id},</if>
|
||||
<if test="planId != null and planId != ''">#{planId},</if>
|
||||
<if test="caseId != null and caseId != ''">#{caseId},</if>
|
||||
#{type},
|
||||
<if test="executeResult != null">#{executeResult},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="executeTime != null">#{executeTime},</if>
|
||||
<if test="executeBy != null">#{executeBy},</if>
|
||||
<if test="version != null">#{version},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateTestPlanCase" parameterType="TestPlanCase">
|
||||
update test_plan_case
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="planId != null and planId != ''">plan_id = #{planId},</if>
|
||||
<if test="caseId != null and caseId != ''">case_id = #{caseId},</if>
|
||||
<if test="type != null and type != ''">type = #{type},</if>
|
||||
<if test="executeResult != null">execute_result = #{executeResult},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="executeTime != null">execute_time = #{executeTime},</if>
|
||||
<if test="executeBy != null">execute_by = #{executeBy},</if>
|
||||
<if test="version != null">version = #{version},</if>
|
||||
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteTestPlanCaseById" parameterType="Long">
|
||||
delete from test_plan_case where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteTestPlanCaseByIds" parameterType="String">
|
||||
delete from test_plan_case where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
51
test-ui/src/api/test/planCase.js
Normal file
51
test-ui/src/api/test/planCase.js
Normal 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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
267
test-ui/src/views/test/testplan/execute/index.vue
Normal file
267
test-ui/src/views/test/testplan/execute/index.vue
Normal 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>
|
||||
80
test-ui/src/views/test/testplan/execute/relateCase.vue
Normal file
80
test-ui/src/views/test/testplan/execute/relateCase.vue
Normal 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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user