This commit is contained in:
chenjianxing 2020-11-03 17:34:26 +08:00
commit 4dc7d457f3
15 changed files with 128 additions and 73 deletions

View File

@ -38,9 +38,21 @@
- [x] 其他:消息通知
- [x] 其他:报告导出
## v1.4 (已发布)
- [x] 测试跟踪模块编辑测试用例支持上传附件
- [x] 支持上传并引用自定义Jar包
- [x] 接口测试支持TCP协议请求
- [x] 全新的消息通知设置,支持企业微信、钉钉机器人通知
## v1.5 (开发中)
- [ ] 性能测试:优化并发数、持续时间等压力配置方式
- [ ] 性能测试:支持使用了额外插件的 JMX 文件
- [ ] 性能测试:自动修改 csv 等数据文件引用路径
- [ ] 性能测试:优化性能测试报告展示
- [ ] 测试跟踪:支持对接禅道同步缺陷
- [ ] 其他Jenkins 插件支持 pipeline 方式调用
## 规划中
- [ ] 接口测试支持添加 TCP 协议请求
- [ ] 接口测试支持添加 WebSocket 协议请求
- [ ] 接口管理功能
- [ ] 集成云平台动态管理测试资源池

View File

@ -31,4 +31,11 @@ public interface ExtTestPlanTestCaseMapper {
List<String> getTestPlanTestCaseIds(String testId);
/**
* 根据项目 ids 查询 TestPlanCaseDTO 列表
* @param ids project id list
* @return List<TestPlanCaseDTO>
*/
List<TestPlanCaseDTO> listTestCaseByProjectIds(@Param("ids") List<String> ids);
}

View File

@ -210,6 +210,14 @@
</foreach>
</if>
</select>
<select id="listTestCaseByProjectIds" resultType="io.metersphere.track.dto.TestPlanCaseDTO">
select distinct * from test_plan_test_case, test_case
where test_plan_test_case.case_id = test_case.id
and test_case.project_id in
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
<select id="listByNode" resultType="io.metersphere.track.dto.TestPlanCaseDTO">
select test_plan_test_case.*, test_case.*
from test_plan_test_case

View File

@ -12,4 +12,11 @@ public interface ExtTestReviewCaseMapper {
List<TestReviewCaseDTO> list(@Param("request") QueryCaseReviewRequest request);
List<String> getStatusByReviewId(String reviewId);
List<String> findRelateTestReviewId(@Param("userId") String userId, @Param("workspaceId") String workspaceId);
/**
* 根据项目 ids 查询 TestReviewCaseDTO 列表
* @param ids project id list
* @return List<TestReviewCaseDTO>
*/
List<TestReviewCaseDTO> listTestCaseByProjectIds(@Param("ids") List<String> ids);
}

View File

@ -195,4 +195,12 @@
where test_case_review_test_case.review_id = #{userId}
and project.workspace_id = #{workspaceId}
</select>
<select id="listTestCaseByProjectIds" resultType="io.metersphere.track.dto.TestReviewCaseDTO">
select distinct * from test_case_review_test_case, test_case
where test_case_review_test_case.case_id = test_case.id
and test_case.project_id in
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
</mapper>

View File

@ -6,6 +6,7 @@ import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.taobao.api.ApiException;
import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.notice.domain.MessageDetail;
import io.metersphere.notice.domain.UserDetail;
import io.metersphere.service.UserService;
@ -62,7 +63,7 @@ public class DingTaskService {
try {
response = client.execute(request);
} catch (ApiException e) {
e.printStackTrace();
LogUtil.error(e);
}
System.out.println(response.getErrcode());
}

View File

@ -1,6 +1,7 @@
package io.metersphere.notice.service;
import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.notice.domain.MessageDetail;
import io.metersphere.notice.domain.UserDetail;
import io.metersphere.notice.message.TextMessage;
@ -55,7 +56,7 @@ public class WxChatTaskService {
SendResult result = WxChatbotClient.send(Webhook, message);
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
LogUtil.error(e);
}
}

View File

@ -19,7 +19,6 @@ import io.metersphere.dto.LoadTestDTO;
import io.metersphere.dto.ScheduleDao;
import io.metersphere.i18n.Translator;
import io.metersphere.job.sechedule.PerformanceTestJob;
import io.metersphere.notice.domain.NoticeDetail;
import io.metersphere.performance.engine.Engine;
import io.metersphere.performance.engine.EngineFactory;
import io.metersphere.performance.notice.PerformanceNoticeTask;
@ -230,12 +229,10 @@ public class PerformanceTestService {
startEngine(loadTest, engine, request.getTriggerMode());
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(engine.getReportId());
loadTestReport.setTriggerMode("API");
if (StringUtils.equals(NoticeConstants.API, loadTestReport.getTriggerMode()) || StringUtils.equals(NoticeConstants.SCHEDULE, loadTestReport.getTriggerMode())) {
performanceNoticeTask.registerNoticeTask(loadTestReport);
}
/*if (StringUtils.equals(NoticeConstants.API, loadTestReport.getTriggerMode()) || StringUtils.equals(NoticeConstants.SCHEDULE, "SCHEDULE")) {
performanceNoticeTask.registerNoticeTask(loadTestReport);
}*/
return engine.getReportId();
}
@ -305,15 +302,10 @@ public class PerformanceTestService {
} catch (MSException e) {
// 启动失败之后清理任务
engine.stop();
LogUtil.error(e);
loadTest.setStatus(PerformanceTestStatus.Error.name());
loadTest.setDescription(e.getMessage());
loadTestMapper.updateByPrimaryKeySelective(loadTest);
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(engine.getReportId());
if (StringUtils.equals(NoticeConstants.API, loadTestReport.getTriggerMode()) || StringUtils.equals(NoticeConstants.SCHEDULE, loadTestReport.getTriggerMode())) {
performanceNoticeTask.registerNoticeTask(loadTestReport);
}
throw e;
}
}
@ -436,17 +428,6 @@ public class PerformanceTestService {
reportService.stopEngine(loadTest, engine);
// 停止测试之后设置报告的状态
reportService.updateStatus(reportId, PerformanceTestStatus.Completed.name());
List<NoticeDetail> noticeList = null;
if (loadTestReport.getTriggerMode().equals("SCHEDULE")) {
/* try {
noticeList = noticeService.queryNotice(loadTest.getId());
mailService.sendPerformanceNotification(noticeList, loadTestReport.getStatus(), loadTest, loadTestReport.getId());
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
}*/
}
}
}

View File

@ -62,7 +62,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
/**
* 获取平台与项目相关的属性
* @return
* @return 其他平台和本地项目绑定的属性值
*/
abstract String getProjectId();

View File

@ -9,31 +9,30 @@ public interface IssuesPlatform {
/**
* 获取平台相关联的缺陷
* @return
* @return platform issues list
*/
List<Issues> getIssue();
/**
* 添加缺陷到缺陷平台
* @param issuesRequest
* @param issuesRequest issueRequest
*/
void addIssue(IssuesRequest issuesRequest);
/**
* 删除缺陷平台缺陷
* @param id
* @param id issue id
*/
void deleteIssue(String id);
/**
* 测试缺陷平台连通性
* @param
* 测试平台联通性
*/
void testAuth();
/**
* 获取缺陷平台项目下的相关人员
* @return
* @return platform user list
*/
List<PlatformUser> getPlatformUser();
}

View File

@ -586,9 +586,14 @@ public class TestCaseNodeService {
}
// 测试用例同级模块排序
/**
* 测试用例同级模块排序
* @param ids 被拖拽模块相邻的前一个模块 id
* 被拖拽的模块 id
* 被拖拽模块相邻的后一个模块 id
*/
public void sort(List<String> ids) {
// 获取相邻节点
// 获取相邻节点 id
String before = ids.get(0);
String id = ids.get(1);
String after = ids.get(2);
@ -598,6 +603,7 @@ public class TestCaseNodeService {
TestCaseNode caseNode = getCaseNode(id);
// 获取相邻节点
if (StringUtils.isNotBlank(before)) {
beforeCase = getCaseNode(before);
beforeCase = beforeCase.getLevel().equals(caseNode.getLevel()) ? beforeCase : null;
@ -625,6 +631,14 @@ public class TestCaseNodeService {
}
}
/**
* 按照指定排序方式获取同级模块的列表
* @param projectId 所属项目 id
* @param level node level
* @param parentId node parent id
* @param order pos 排序方式
* @return 按照指定排序方式排序的同级模块列表
*/
private List<TestCaseNode> getPos(String projectId, int level, String parentId, String order) {
TestCaseNodeExample example = new TestCaseNodeExample();
TestCaseNodeExample.Criteria criteria = example.createCriteria();
@ -636,6 +650,12 @@ public class TestCaseNodeService {
return testCaseNodeMapper.selectByExample(example);
}
/**
* 刷新同级模块的 pos
* @param projectId project id
* @param level node level
* @param parentId node parent id
*/
private void refreshPos(String projectId, int level, String parentId) {
List<TestCaseNode> nodes = getPos(projectId, level, parentId, "pos asc");
if (!CollectionUtils.isEmpty(nodes)) {
@ -650,7 +670,15 @@ public class TestCaseNodeService {
}
}
public double getNextLevelPos(String projectId, int level, String parentId) {
/**
* 获得同级模块下一个 pos
* @param projectId project id
* @param level node level
* @param parentId node parent id
* @return 同级模块下一个 pos
*/
private double getNextLevelPos(String projectId, int level, String parentId) {
List<TestCaseNode> list = getPos(projectId, level, parentId, "pos desc");
if (!CollectionUtils.isEmpty(list)) {
return list.get(0).getPos() + 65536;

View File

@ -8,6 +8,7 @@ import io.metersphere.base.mapper.ext.ExtTestCaseReviewMapper;
import io.metersphere.base.mapper.ext.ExtTestReviewCaseMapper;
import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.constants.TestCaseReviewStatus;
import io.metersphere.commons.constants.TestPlanStatus;
import io.metersphere.commons.constants.TestReviewCaseStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.user.SessionUser;
@ -184,28 +185,31 @@ public class TestCaseReviewService {
testCaseReview.setUpdateTime(System.currentTimeMillis());
checkCaseReviewExist(testCaseReview);
testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview);
List<String> userIds=new ArrayList<>();
List<String> userIds = new ArrayList<>();
userIds.addAll(testCaseReview.getUserIds());
try {
String context = getReviewContext(testCaseReview, NoticeConstants.CREATE);
MessageSettingDetail messageSettingDetail = noticeService.searchMessage();
List<MessageDetail> taskList = messageSettingDetail.getReviewTask();
taskList.forEach(r -> {
switch (r.getType()) {
case NoticeConstants.NAIL_ROBOT:
dingTaskService.sendNailRobot(r, userIds, context, NoticeConstants.CREATE);
break;
case NoticeConstants.WECHAT_ROBOT:
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.CREATE);
break;
case NoticeConstants.EMAIL:
mailService.sendReviewerNotice(r, userIds, testCaseReview, NoticeConstants.CREATE);
break;
}
});
} catch (Exception e) {
LogUtil.error(e);
if (StringUtils.equals(TestPlanStatus.Completed.name(), testCaseReview.getStatus())) {
try {
String context = getReviewContext(testCaseReview, NoticeConstants.UPDATE);
MessageSettingDetail messageSettingDetail = noticeService.searchMessage();
List<MessageDetail> taskList = messageSettingDetail.getReviewTask();
taskList.forEach(r -> {
switch (r.getType()) {
case NoticeConstants.NAIL_ROBOT:
dingTaskService.sendNailRobot(r, userIds, context, NoticeConstants.UPDATE);
break;
case NoticeConstants.WECHAT_ROBOT:
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.UPDATE);
break;
case NoticeConstants.EMAIL:
mailService.sendReviewerNotice(r, userIds, testCaseReview, NoticeConstants.UPDATE);
break;
}
});
} catch (Exception e) {
LogUtil.error(e);
}
}
}
private void editCaseReviewer(SaveTestCaseReviewRequest testCaseReview) {
@ -480,7 +484,7 @@ public class TestCaseReviewService {
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
request.setReviewIds(extTestReviewCaseMapper.findRelateTestReviewId(user.getId(), SessionUtils.getCurrentWorkspaceId()));
List<String> projectIds = extProjectMapper.getProjectIdByWorkspaceId(SessionUtils.getCurrentOrganizationId());
List<String> projectIds = extProjectMapper.getProjectIdByWorkspaceId(SessionUtils.getCurrentWorkspaceId());
List<TestReviewDTOWithMetric> testReviews = extTestCaseReviewMapper.listRelate(request);
@ -549,10 +553,11 @@ public class TestCaseReviewService {
return name;
}
public List<TestReviewCaseDTO> listTestCaseByProjectIds(List<String> projectIds) {
QueryCaseReviewRequest request = new QueryCaseReviewRequest();
request.setProjectIds(projectIds);
return extTestReviewCaseMapper.list(request);
private List<TestReviewCaseDTO> listTestCaseByProjectIds(List<String> projectIds) {
if (CollectionUtils.isEmpty(projectIds)) {
return new ArrayList<>();
}
return extTestReviewCaseMapper.listTestCaseByProjectIds(projectIds);
}
/*编辑,新建,完成,删除通知内容*/

View File

@ -165,20 +165,20 @@ public class TestPlanService {
//已完成写入实际完成时间
testPlan.setActualEndTime(System.currentTimeMillis());
try {
BeanUtils.copyBean(testPlans, testPlan);
String context = getTestPlanContext(testPlans, NoticeConstants.CREATE);
BeanUtils.copyBean(testPlans, getTestPlan(testPlan.getId()));
String context = getTestPlanContext(testPlans, NoticeConstants.UPDATE);
MessageSettingDetail messageSettingDetail = noticeService.searchMessage();
List<MessageDetail> taskList = messageSettingDetail.getReviewTask();
List<MessageDetail> taskList = messageSettingDetail.getTestCasePlanTask();
taskList.forEach(r -> {
switch (r.getType()) {
case NoticeConstants.NAIL_ROBOT:
dingTaskService.sendNailRobot(r, userIds, context, NoticeConstants.CREATE);
dingTaskService.sendNailRobot(r, userIds, context, NoticeConstants.UPDATE);
break;
case NoticeConstants.WECHAT_ROBOT:
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.CREATE);
wxChatTaskService.sendWechatRobot(r, userIds, context, NoticeConstants.UPDATE);
break;
case NoticeConstants.EMAIL:
mailService.sendTestPlanStartNotice(r, userIds, testPlans, NoticeConstants.CREATE);
mailService.sendTestPlanStartNotice(r, userIds, testPlans, NoticeConstants.UPDATE);
break;
}
});
@ -365,7 +365,7 @@ public class TestPlanService {
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
request.setPlanIds(extTestPlanTestCaseMapper.findRelateTestPlanId(user.getId(), SessionUtils.getCurrentWorkspaceId()));
List<String> projectIds = extProjectMapper.getProjectIdByWorkspaceId(SessionUtils.getCurrentOrganizationId());
List<String> projectIds = extProjectMapper.getProjectIdByWorkspaceId(SessionUtils.getCurrentWorkspaceId());
List<TestPlanDTOWithMetric> testPlans = extTestPlanMapper.listRelate(request);
@ -411,10 +411,11 @@ public class TestPlanService {
return testPlanTestCaseService.list(request);
}
public List<TestPlanCaseDTO> listTestCaseByProjectIds(List<String> projectIds) {
QueryTestPlanCaseRequest request = new QueryTestPlanCaseRequest();
request.setProjectIds(projectIds);
return extTestPlanTestCaseMapper.list(request);
private List<TestPlanCaseDTO> listTestCaseByProjectIds(List<String> projectIds) {
if (CollectionUtils.isEmpty(projectIds)) {
return new ArrayList<>();
}
return extTestPlanTestCaseMapper.listTestCaseByProjectIds(projectIds);
}
public TestCaseReportMetricDTO getMetric(String planId) {

View File

@ -1,3 +0,0 @@
alter table message_task
alter column create_time set default 0;

View File

@ -43,7 +43,7 @@
<AppenderRef ref="gui-log-event" />
<AppenderRef ref="Kafka" />
</Root>
<Logger name="org.apache.kafka" level="INFO" />
<Logger name="org.apache.jmeter.junit" level="debug" />
<!--
<Logger name="org.apache.jmeter.control" level="debug" />