feat(测试计划): 修复测试计划定时任务总是Running的问题

--bug=1005249 --user=宋天阳 【定时任务】测试计划定时任务,状态一直是running
https://www.tapd.cn/55049933/s/1026590
This commit is contained in:
song-tianyang 2021-07-20 20:36:51 +08:00 committed by 刘瑞斌
parent 47558a6438
commit b4a5a008b6
17 changed files with 765 additions and 286 deletions

View File

@ -15,6 +15,7 @@ public class TestPlanScenarioRequest {
private String projectId;
private String moduleId;
private List<String> moduleIds;
private List<String> scenarioIds;
private String name;
private String status;
private String workspaceId;

View File

@ -2342,7 +2342,6 @@ public class ApiAutomationService {
}
}
}
// uploadFiles(request, bodyFiles, scenarioFiles);
}
public DeleteCheckResult checkBeforeDelete(ApiScenarioBatchRequest request) {

View File

@ -9,15 +9,15 @@ import io.metersphere.base.mapper.ApiDefinitionMapper;
import io.metersphere.base.mapper.ApiTestCaseMapper;
import io.metersphere.base.mapper.TestCaseReviewApiCaseMapper;
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.DelimiterConstants;
import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.constants.*;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.DateUtils;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.track.dto.TestPlanDTO;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.service.TestCaseReviewApiCaseService;
import io.metersphere.track.service.TestPlanApiCaseService;
import io.metersphere.track.service.TestPlanReportService;
import io.metersphere.track.service.TestPlanService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@ -157,69 +157,89 @@ public class ApiDefinitionExecResultService {
* @param result
* @param type
*/
public void saveApiResultByScheduleTask(TestResult result, String type) {
public void saveApiResultByScheduleTask(TestResult result,String testPlanReportId, String type,String trigeMode) {
String saveResultType = type;
if (StringUtils.equalsAny(saveResultType, ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
saveResultType = ApiRunMode.API_PLAN.name();
}
String finalSaveResultType = saveResultType;
result.getScenarios().get(0).getRequestResults().forEach(item -> {
ApiDefinitionExecResult saveResult = new ApiDefinitionExecResult();
saveResult.setId(UUID.randomUUID().toString());
saveResult.setCreateTime(System.currentTimeMillis());
saveResult.setName(item.getName());
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(item.getName());
if (apiDefinitionWithBLOBs != null) {
saveResult.setName(apiDefinitionWithBLOBs.getName());
} else {
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(item.getName());
if (caseWithBLOBs != null) {
saveResult.setName(caseWithBLOBs.getName());
Map<String,String> apiIdResultMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(result.getScenarios())) {
result.getScenarios().forEach(scenarioResult -> {
if (scenarioResult != null && CollectionUtils.isNotEmpty(scenarioResult.getRequestResults())) {
scenarioResult.getRequestResults().forEach(item -> {
String status = item.isSuccess() ? "success" : "error";
ApiDefinitionExecResult saveResult = new ApiDefinitionExecResult();
saveResult.setId(UUID.randomUUID().toString());
saveResult.setCreateTime(System.currentTimeMillis());
saveResult.setName(item.getName());
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(item.getName());
if (apiDefinitionWithBLOBs != null) {
saveResult.setName(apiDefinitionWithBLOBs.getName());
apiIdResultMap.put(apiDefinitionWithBLOBs.getId(),item.isSuccess()? TestPlanApiExecuteStatus.SUCCESS.name() : TestPlanApiExecuteStatus.FAILD.name());
} else {
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(item.getName());
if (caseWithBLOBs != null) {
saveResult.setName(caseWithBLOBs.getName());
apiIdResultMap.put(caseWithBLOBs.getId(),item.isSuccess()? TestPlanApiExecuteStatus.SUCCESS.name() : TestPlanApiExecuteStatus.FAILD.name());
}else {
caseWithBLOBs = testPlanApiCaseService.getApiTestCaseById(item.getName());
if (caseWithBLOBs != null) {
saveResult.setName(caseWithBLOBs.getName());
apiIdResultMap.put(caseWithBLOBs.getId(), item.isSuccess() ? TestPlanApiExecuteStatus.SUCCESS.name() : TestPlanApiExecuteStatus.FAILD.name());
}
}
}
if (StringUtils.equals(type, ApiRunMode.JENKINS_API_PLAN.name())) {
saveResult.setTriggerMode(TriggerMode.API.name());
} else {
saveResult.setTriggerMode(TriggerMode.SCHEDULE.name());
}
saveResult.setResourceId(item.getName());
saveResult.setActuator("LOCAL");
saveResult.setContent(JSON.toJSONString(item));
saveResult.setStartTime(item.getStartTime());
saveResult.setEndTime(item.getResponseResult().getResponseTime());
saveResult.setType(finalSaveResultType);
saveResult.setStatus(status);
String userID = null;
if (StringUtils.equals(type, ApiRunMode.SCHEDULE_API_PLAN.name())) {
TestPlanApiCase apiCase = testPlanApiCaseService.getById(item.getName());
String scheduleCreateUser = testPlanService.findScheduleCreateUserById(apiCase.getTestPlanId());
userID = scheduleCreateUser;
apiCase.setStatus(status);
apiCase.setUpdateTime(System.currentTimeMillis());
testPlanApiCaseService.updateByPrimaryKeySelective(apiCase);
} else if (StringUtils.equals(type, ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
TestPlanApiCase apiCase = testPlanApiCaseService.getById(item.getName());
userID = Objects.requireNonNull(SessionUtils.getUser()).getId();
apiCase.setStatus(status);
apiCase.setUpdateTime(System.currentTimeMillis());
testPlanApiCaseService.updateByPrimaryKeySelective(apiCase);
} else {
userID = Objects.requireNonNull(SessionUtils.getUser()).getId();
testPlanApiCaseService.setExecResult(item.getName(), status, item.getStartTime());
testCaseReviewApiCaseService.setExecResult(item.getName(), status, item.getStartTime());
}
saveResult.setUserId(userID);
// 前一条数据内容清空
ApiDefinitionExecResult prevResult = extApiDefinitionExecResultMapper.selectMaxResultByResourceIdAndType(item.getName(), finalSaveResultType);
if (prevResult != null) {
prevResult.setContent(null);
apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(prevResult);
}
apiDefinitionExecResultMapper.insert(saveResult);
});
}
}
if (StringUtils.equals(type, ApiRunMode.JENKINS_API_PLAN.name())) {
saveResult.setTriggerMode(TriggerMode.API.name());
} else {
saveResult.setTriggerMode(TriggerMode.SCHEDULE.name());
}
});
}
saveResult.setResourceId(item.getName());
saveResult.setActuator("LOCAL");
saveResult.setContent(JSON.toJSONString(item));
saveResult.setStartTime(item.getStartTime());
String status = item.isSuccess() ? "success" : "error";
saveResult.setEndTime(item.getResponseResult().getResponseTime());
saveResult.setType(finalSaveResultType);
saveResult.setStatus(status);
String userID = null;
if (StringUtils.equals(type, ApiRunMode.SCHEDULE_API_PLAN.name())) {
TestPlanApiCase apiCase = testPlanApiCaseService.getById(item.getName());
String scheduleCreateUser = testPlanService.findScheduleCreateUserById(apiCase.getTestPlanId());
userID = scheduleCreateUser;
apiCase.setStatus(status);
apiCase.setUpdateTime(System.currentTimeMillis());
testPlanApiCaseService.updateByPrimaryKeySelective(apiCase);
} else if (StringUtils.equals(type, ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
TestPlanApiCase apiCase = testPlanApiCaseService.getById(item.getName());
userID = Objects.requireNonNull(SessionUtils.getUser()).getId();
apiCase.setStatus(status);
apiCase.setUpdateTime(System.currentTimeMillis());
testPlanApiCaseService.updateByPrimaryKeySelective(apiCase);
} else {
userID = Objects.requireNonNull(SessionUtils.getUser()).getId();
testPlanApiCaseService.setExecResult(item.getName(), status, item.getStartTime());
testCaseReviewApiCaseService.setExecResult(item.getName(), status, item.getStartTime());
}
saveResult.setUserId(userID);
// 前一条数据内容清空
ApiDefinitionExecResult prevResult = extApiDefinitionExecResultMapper.selectMaxResultByResourceIdAndType(item.getName(), finalSaveResultType);
if (prevResult != null) {
prevResult.setContent(null);
apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(prevResult);
}
apiDefinitionExecResultMapper.insert(saveResult);
});
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
testPlanReportService.updateExecuteApis(testPlanReportId,apiIdResultMap,null,null);
}
public void deleteByResourceId(String resourceId) {

View File

@ -23,6 +23,7 @@ import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.constants.TestPlanApiExecuteStatus;
import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*;
@ -252,7 +253,7 @@ public class ApiScenarioReportService {
return returnReport;
}
public ApiScenarioReport updateSchedulePlanCase(TestResult result, String runMode) {
public ApiScenarioReport updateSchedulePlanCase(TestResult result, String runMode) {
ApiScenarioReport lastReport = null;
List<ScenarioResult> scenarioResultList = result.getScenarios();
@ -261,6 +262,7 @@ public class ApiScenarioReportService {
List<String> reportIds = new ArrayList<>();
List<String> scenarioIdList = new ArrayList<>();
Map<String,String> scenarioAndErrorMap = new HashMap<>();
for (ScenarioResult scenarioResult : scenarioResultList) {
// 存储场景报告
@ -296,9 +298,12 @@ public class ApiScenarioReportService {
report.setScenarioId(testPlanApiScenario.getApiScenarioId());
report.setTestPlanScenarioId(planScenarioId);
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
if (scenarioResult.getError() > 0) {
scenarioAndErrorMap.put(testPlanApiScenario.getApiScenarioId(), TestPlanApiExecuteStatus.FAILD.name());
testPlanApiScenario.setLastResult(ScenarioStatus.Fail.name());
} else {
scenarioAndErrorMap.put(testPlanApiScenario.getApiScenarioId(), TestPlanApiExecuteStatus.SUCCESS.name());
testPlanApiScenario.setLastResult(ScenarioStatus.Success.name());
}
String passRate = new DecimalFormat("0%").format((float) scenarioResult.getSuccess() / (scenarioResult.getSuccess() + scenarioResult.getError()));
@ -317,18 +322,17 @@ public class ApiScenarioReportService {
testPlanApiScenario.setReportId(report.getId());
testPlanApiScenario.setUpdateTime(System.currentTimeMillis());
testPlanApiScenarioMapper.updateByPrimaryKeySelective(testPlanApiScenario);
// scenarioIds.append(scenarioResult.getName()).append(",");
scenarioIdList.add(testPlanApiScenario.getApiScenarioId());
scenarioNames.append(report.getName()).append(",");
lastReport = report;
reportIds.add(report.getId());
}
// 合并报告
// margeReport(result, scenarioIds, scenarioNames, runMode, projectId, userId, reportIds);
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
testPlanReportService.updateReport(testPlanReportIdList, runMode, lastReport.getTriggerMode(), scenarioIdList);
for (String planId :testPlanReportIdList) {
testPlanReportService.updateExecuteApis(planId,null,scenarioAndErrorMap,null);
}
// testPlanReportService.updateReport(testPlanReportIdList, runMode, lastReport.getTriggerMode(), scenarioIdList);
return lastReport;
}

View File

@ -90,21 +90,9 @@ public class TestResultService {
} else if (StringUtils.equalsAny(runMode, ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
//测试计划定时任务-接口执行逻辑的话需要同步测试计划的报告数据
if (StringUtils.equals(runMode, ApiRunMode.SCHEDULE_API_PLAN.name())) {
apiDefinitionExecResultService.saveApiResultByScheduleTask(testResult, ApiRunMode.SCHEDULE_API_PLAN.name());
List<String> testPlanReportIdList = new ArrayList<>();
testPlanReportIdList.add(debugReportId);
for (String testPlanReportId : testPlanReportIdList) { // 更新每个测试计划的状态
testPlanReportService.checkTestPlanStatus(testPlanReportId);
}
testPlanReportService.updateReport(testPlanReportIdList, ApiRunMode.SCHEDULE_API_PLAN.name(), ReportTriggerMode.SCHEDULE.name());
apiDefinitionExecResultService.saveApiResultByScheduleTask(testResult,debugReportId, ApiRunMode.SCHEDULE_API_PLAN.name(),ReportTriggerMode.SCHEDULE.name());
} else if (StringUtils.equals(runMode, ApiRunMode.JENKINS_API_PLAN.name())) {
apiDefinitionExecResultService.saveApiResultByScheduleTask(testResult, ApiRunMode.JENKINS_API_PLAN.name());
List<String> testPlanReportIdList = new ArrayList<>();
testPlanReportIdList.add(debugReportId);
for (String testPlanReportId : testPlanReportIdList) { // 更新每个测试计划的状态
testPlanReportService.checkTestPlanStatus(testPlanReportId);
}
testPlanReportService.updateReport(testPlanReportIdList, ApiRunMode.JENKINS_API_PLAN.name(), ReportTriggerMode.API.name());
apiDefinitionExecResultService.saveApiResultByScheduleTask(testResult,debugReportId, ApiRunMode.JENKINS_API_PLAN.name(),ReportTriggerMode.API.name());
} else {
apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.API_PLAN.name(), TriggerMode.MANUAL.name());
}

View File

@ -2,6 +2,7 @@ package io.metersphere.base.mapper.ext;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import io.metersphere.base.domain.TestPlanApiCase;
import org.apache.ibatis.annotations.Param;
@ -21,4 +22,6 @@ public interface ExtTestPlanApiCaseMapper {
List<String> getStatusByTestPlanId(String id);
List<String> selectIds(@Param("request") ApiTestCaseRequest request);
ApiTestCaseWithBLOBs getApiTestCaseById(String testPlanApiCaseId);
}

View File

@ -13,7 +13,11 @@
WHERE test_plan_id = #{request.testPlanId} and api_case_id = #{request.apiCaseId}
)
</insert>
<select id="getApiTestCaseById" resultType="io.metersphere.base.domain.ApiTestCaseWithBLOBs">
SELECT t.* FROM api_test_case t
INNER JOIN test_plan_api_case tpac ON t.id = tpac.api_case_id
WHERE tpac.id = #{0}
</select>
<select id="list" resultType="io.metersphere.api.dto.definition.TestPlanApiCaseDTO">
select
t.id, t.environment_id, t.create_time, t.update_time,

View File

@ -57,6 +57,12 @@
inner join project p on lt.project_id = p.id
<where>
tplc.test_plan_id = #{request.testPlanId}
<if test="request.caseIds != null and request.caseIds.size > 0">
AND lt.id IN
<foreach collection="request.caseIds" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="request.projectId != null and request.projectId != ''">
and lt.project_id = #{request.projectId}
</if>

View File

@ -30,6 +30,13 @@
and t.test_plan_id = #{request.planId}
</if>
where 1
<if test="request.scenarioIds != null and request.scenarioIds.size() > 0">
and c.id in
<foreach collection="request.scenarioIds" item="caseId" separator="," open="(" close=")">
#{caseId}
</foreach>
</if>
<if test="request.ids != null and request.ids.size() > 0">
<if test="request.projectId != null and request.projectId!=''">
and c.project_id = #{request.projectId}

View File

@ -0,0 +1,5 @@
package io.metersphere.commons.constants;
public enum TestPlanApiExecuteStatus {
PREPARE,RUNNING,SUCCESS,FAILD
}

View File

@ -9,7 +9,6 @@ import io.metersphere.commons.constants.OperLogConstants;
import io.metersphere.commons.constants.PermissionConstants;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.service.CheckPermissionService;
import io.metersphere.track.dto.ApiRunConfigDTO;
@ -162,4 +161,5 @@ public class TestPlanController {
String apiRunConfig = JSONObject.toJSONString(api);
return testPlanService.run(testplanRunRequest.getTestPlanId(), testplanRunRequest.getProjectId(), testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), apiRunConfig);
}
}

View File

@ -0,0 +1,21 @@
package io.metersphere.track.dto;
import io.metersphere.base.domain.TestPlanReport;
import lombok.Getter;
import lombok.Setter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author song.tianyang
* @Date 2021/7/20 11:22 上午
*/
@Getter
@Setter
public class TestPlanScheduleReportInfoDTO {
private TestPlanReport testPlanReport;
private Map<String, String> planScenarioIdMap = new LinkedHashMap<>();
private Map<String, String> apiTestCaseIdMap = new LinkedHashMap<>();
private Map<String, String> performanceIdMap = new LinkedHashMap<>();
}

View File

@ -492,4 +492,8 @@ public class TestPlanApiCaseService {
.andStatusEqualTo("error");
return testPlanApiCaseMapper.countByExample(example) > 0 ? true : false;
}
public ApiTestCaseWithBLOBs getApiTestCaseById(String testPlanApiCaseId) {
return extTestPlanApiCaseMapper.getApiTestCaseById(testPlanApiCaseId);
}
}

View File

@ -3,9 +3,14 @@ package io.metersphere.track.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanLoadCaseMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
import io.metersphere.base.mapper.ext.ExtTestPlanReportMapper;
import io.metersphere.commons.constants.*;
@ -18,15 +23,18 @@ import io.metersphere.notice.service.NoticeSendService;
import io.metersphere.service.SystemParameterService;
import io.metersphere.track.Factory.ReportComponentFactory;
import io.metersphere.track.domain.ReportComponent;
import io.metersphere.track.domain.ReportResultComponent;
import io.metersphere.track.dto.*;
import io.metersphere.track.request.report.QueryTestPlanReportRequest;
import io.metersphere.track.request.report.TestPlanReportSaveRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.LoadCaseRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
@ -36,18 +44,18 @@ import java.util.stream.Collectors;
/**
* @author song.tianyang
* @Date 2021/1/8 4:34 下午
* @Description
* 2021/1/8 4:34 下午
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanReportService {
@Resource
TestPlanReportMapper testPlanReportMapper;
@Resource
TestPlanReportDataMapper testPlanReportDataMapper;
@Resource
ExtTestPlanLoadCaseMapper extTestPlanLoadCaseMapper;
@Resource
TestPlanApiScenarioMapper testPlanScenarioCaseMapper;
@Resource
TestPlanApiCaseMapper testPlanApiCaseMapper;
@ -59,13 +67,16 @@ public class TestPlanReportService {
ExtTestPlanMapper extTestPlanMapper;
@Resource
ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
@Resource
TestPlanLoadCaseService testPlanLoadCaseService;
@Resource
TestPlanService testPlanService;
// @Resource
// TestPlanLoadCaseService testPlanLoadCaseService;
// @Resource
// TestPlanService testPlanService;
@Resource
LoadTestReportMapper loadTestReportMapper;
@Resource
SqlSessionFactory sqlSessionFactory;
private final ExecutorService executorService = Executors.newFixedThreadPool(20);
public List<TestPlanReportDTO> list(QueryTestPlanReportRequest request) {
@ -74,20 +85,81 @@ public class TestPlanReportService {
if (StringUtils.isNotBlank(projectId)) {
request.setProjectId(projectId);
}
List<TestPlanReportDTO> returnList = extTestPlanReportMapper.list(request);
return returnList;
return extTestPlanReportMapper.list(request);
}
public TestPlanScheduleReportInfoDTO genTestPlanReportBySchedule(String projectID, String planId, String userId, String triggerMode) {
Map<String, String> planScenarioIdMap = new LinkedHashMap<>();
Map<String, String> apiTestCaseIdMap = new LinkedHashMap<>();
Map<String, String> performanceIdMap = new LinkedHashMap<>();
TestPlanApiScenarioExample scenarioCaseExample = new TestPlanApiScenarioExample();
scenarioCaseExample.createCriteria().andTestPlanIdEqualTo(planId);
List<TestPlanApiScenario> testPlanApiScenarioList = testPlanScenarioCaseMapper.selectByExample(scenarioCaseExample);
for (TestPlanApiScenario model : testPlanApiScenarioList) {
planScenarioIdMap.put(model.getApiScenarioId(), model.getId());
}
TestPlanApiCaseExample apiCaseExample = new TestPlanApiCaseExample();
apiCaseExample.createCriteria().andTestPlanIdEqualTo(planId);
List<TestPlanApiCase> testPlanApiCaseList = testPlanApiCaseMapper.selectByExample(apiCaseExample);
for (TestPlanApiCase model :
testPlanApiCaseList) {
apiTestCaseIdMap.put(model.getApiCaseId(), model.getId());
}
LoadCaseRequest loadCaseRequest = new LoadCaseRequest();
loadCaseRequest.setTestPlanId(planId);
loadCaseRequest.setProjectId(projectID);
List<TestPlanLoadCaseDTO> testPlanLoadCaseDTOList = extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(loadCaseRequest);
for (TestPlanLoadCaseDTO dto : testPlanLoadCaseDTOList) {
performanceIdMap.put(dto.getId(), dto.getLoadCaseId());
}
String planReportId = UUID.randomUUID().toString();
List<Map<String, String>> apiCaseInfoList = new ArrayList<>();
for (String id : apiTestCaseIdMap.keySet()) {
Map<String, String> map = new HashMap<>();
map.put("id", id);
map.put("status", TestPlanApiExecuteStatus.PREPARE.name());
apiCaseInfoList.add(map);
}
List<Map<String, String>> scenarioInfoList = new ArrayList<>();
for (String id : planScenarioIdMap.keySet()) {
Map<String, String> map = new HashMap<>();
map.put("id", id);
map.put("status", TestPlanApiExecuteStatus.PREPARE.name());
scenarioInfoList.add(map);
}
List<Map<String, String>> performanceInfoList = new ArrayList<>();
for (String id : performanceIdMap.values()) {
Map<String, String> map = new HashMap<>();
map.put("id", id);
map.put("status", TestPlanApiExecuteStatus.PREPARE.name());
performanceInfoList.add(map);
}
TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(planReportId, planId, userId, triggerMode,
apiTestCaseIdMap.size() > 0, planScenarioIdMap.size() > 0, performanceIdMap.size() > 0,
JSONArray.toJSONString(apiCaseInfoList), JSONArray.toJSONString(scenarioInfoList), JSONArray.toJSONString(performanceInfoList));
TestPlanReport report = this.genTestPlanReport(saveRequest);
TestPlanScheduleReportInfoDTO returnDTO = new TestPlanScheduleReportInfoDTO();
returnDTO.setTestPlanReport(report);
returnDTO.setPlanScenarioIdMap(planScenarioIdMap);
returnDTO.setApiTestCaseIdMap(apiTestCaseIdMap);
returnDTO.setPerformanceIdMap(performanceIdMap);
return returnDTO;
}
/**
* saveRequest.reportId 报告ID(外部传入
* saveRequest.planId 测试计划ID
* saveRequest.userId 用户ID
* saveRequest.triggerMode 执行方式
* saveRequest.countResources 是否统计资源-false的话 下面三个不同资源是否运行则由参数决定 true的话则由统计后的结果决定
* saveRequest.apiCaseIsExecuting 接口案例是否执行中
* saveRequest.scenarioIsExecuting 场景案例是否执行中
* saveRequest.performanceIsExecuting 性能案例是否执行中
* @return
* saveRequest.reportId 报告ID(外部传入
* saveRequest.planId 测试计划ID
* saveRequest.userId 用户ID
* saveRequest.triggerMode 执行方式
* saveRequest.countResources 是否统计资源-false的话 下面三个不同资源是否运行则由参数决定 true的话则由统计后的结果决定
* saveRequest.apiCaseIsExecuting 接口案例是否执行中
* saveRequest.scenarioIsExecuting 场景案例是否执行中
* saveRequest.performanceIsExecuting 性能案例是否执行中
*/
public TestPlanReport genTestPlanReport(TestPlanReportSaveRequest saveRequest) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(saveRequest.getPlanId());
@ -99,7 +171,7 @@ public class TestPlanReportService {
testPlanReport.setUpdateTime(System.currentTimeMillis());
try {
testPlanReport.setName(testPlan.getName() + "-" + DateUtils.getTimeString(new Date()));
} catch (Exception e) {
} catch (Exception ignored) {
}
testPlanReport.setTriggerMode(saveRequest.getTriggerMode());
testPlanReport.setCreator(saveRequest.getUserId());
@ -115,36 +187,45 @@ public class TestPlanReportService {
apiExample.createCriteria().andTestPlanIdEqualTo(saveRequest.getPlanId());
List<String> apiCaseIdList = testPlanApiCaseMapper.selectByExample(apiExample)
.stream().map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
if (apiCaseIdList.isEmpty()) {
testPlanReport.setIsApiCaseExecuting(false);
} else {
testPlanReport.setIsApiCaseExecuting(true);
}
testPlanReport.setIsApiCaseExecuting(!apiCaseIdList.isEmpty());
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
example.createCriteria().andTestPlanIdEqualTo(saveRequest.getPlanId());
List<String> scenarioIdList = testPlanScenarioCaseMapper.selectByExample(example)
.stream().map(TestPlanApiScenario::getApiScenarioId).collect(Collectors.toList());
if (scenarioIdList.isEmpty()) {
testPlanReport.setIsScenarioExecuting(false);
} else {
testPlanReport.setIsScenarioExecuting(true);
}
testPlanReport.setIsScenarioExecuting(!scenarioIdList.isEmpty());
LoadCaseRequest loadCaseRequest = new LoadCaseRequest();
loadCaseRequest.setTestPlanId(saveRequest.getPlanId());
loadCaseRequest.setProjectId(testPlan.getProjectId());
List<String> performanceIdList = testPlanLoadCaseService.list(loadCaseRequest)
List<String> performanceIdList = extTestPlanLoadCaseMapper.selectTestPlanLoadCaseList(loadCaseRequest)
.stream().map(TestPlanLoadCaseDTO::getLoadCaseId).collect(Collectors.toList());
if (performanceIdList.isEmpty()) {
testPlanReport.setIsPerformanceExecuting(false);
} else {
testPlanReport.setIsPerformanceExecuting(true);
}
testPlanReport.setIsPerformanceExecuting(!performanceIdList.isEmpty());
testPlanReportData.setApiCaseInfo(JSONArray.toJSONString(apiCaseIdList));
testPlanReportData.setScenarioInfo(JSONArray.toJSONString(scenarioIdList));
testPlanReportData.setPerformanceInfo(JSONArray.toJSONString(performanceIdList));
List<Map<String, String>> apiCaseInfoList = new ArrayList<>();
for (String id : apiCaseIdList) {
Map<String, String> map = new HashMap<>();
map.put("id", id);
map.put("status", TestPlanApiExecuteStatus.PREPARE.name());
apiCaseInfoList.add(map);
}
List<Map<String, String>> scenarioInfoList = new ArrayList<>();
for (String id : scenarioIdList) {
Map<String, String> map = new HashMap<>();
map.put("id", id);
map.put("status", TestPlanApiExecuteStatus.PREPARE.name());
scenarioInfoList.add(map);
}
List<Map<String, String>> performanceInfoList = new ArrayList<>();
for (String id : performanceIdList) {
Map<String, String> map = new HashMap<>();
map.put("id", id);
map.put("status", TestPlanApiExecuteStatus.PREPARE.name());
performanceInfoList.add(map);
}
testPlanReportData.setApiCaseInfo(JSONArray.toJSONString(apiCaseInfoList));
testPlanReportData.setScenarioInfo(JSONArray.toJSONString(scenarioInfoList));
testPlanReportData.setPerformanceInfo(JSONArray.toJSONString(performanceInfoList));
} else {
testPlanReport.setIsApiCaseExecuting(saveRequest.isApiCaseIsExecuting());
testPlanReport.setIsScenarioExecuting(saveRequest.isScenarioIsExecuting());
@ -162,8 +243,13 @@ public class TestPlanReportService {
testPlanReport.setStatus(APITestStatus.Completed.name());
}
testPlanReportMapper.insert(testPlanReport);
testPlanReportDataMapper.insert(testPlanReportData);
SqlSession sqlSession = sqlSessionFactory.openSession(false);
TestPlanReportMapper insertReportMapper = sqlSession.getMapper(TestPlanReportMapper.class);
TestPlanReportDataMapper insertReportDataMapper = sqlSession.getMapper(TestPlanReportDataMapper.class);
insertReportMapper.insert(testPlanReport);
insertReportDataMapper.insert(testPlanReportData);
sqlSession.commit();
sqlSession.flushStatements();
//更新TestPlan状态改为进行中
testPlan.setStatus(TestPlanStatus.Underway.name());
@ -200,34 +286,316 @@ public class TestPlanReportService {
returnDTO.setStartTime(report.getStartTime());
returnDTO.setEndTime(report.getEndTime());
String testProject = testPlanService.findTestProjectNameByTestPlanID(report.getTestPlanId());
String testProject = extTestPlanMapper.findTestProjectNameByTestPlanID(report.getTestPlanId());
returnDTO.setProjectName(testProject);
}
returnDTO.setId(report.getId());
returnDTO.setName(report.getName());
returnDTO.setStartTime(report.getStartTime());
returnDTO.setEndTime(report.getEndTime());
returnDTO.setTestPlanId(report.getTestPlanId());
returnDTO.setReportComponents(report.getComponents());
}
returnDTO.setId(report.getId());
returnDTO.setName(report.getName());
returnDTO.setStartTime(report.getStartTime());
returnDTO.setEndTime(report.getEndTime());
returnDTO.setTestPlanId(report.getTestPlanId());
returnDTO.setReportComponents(report.getComponents());
return returnDTO;
}
public synchronized void updateReport(List<String> testPlanReportIdList, String runMode, String triggerMode) {
for (String planReportId : testPlanReportIdList) {
this.countReportByTestPlanReportId(planReportId, runMode, triggerMode,null);
this.countReportByTestPlanReportId(planReportId, runMode, triggerMode, null);
}
}
public synchronized void updateReport(List<String> testPlanReportIdList, String runMode, String triggerMode,List<String> scenarioIdList) {
public synchronized void updateReport(List<String> testPlanReportIdList, String runMode, String triggerMode, List<String> scenarioIdList) {
for (String planReportId : testPlanReportIdList) {
this.countReportByTestPlanReportId(planReportId, runMode, triggerMode,scenarioIdList);
this.countReportByTestPlanReportId(planReportId, runMode, triggerMode, scenarioIdList);
}
}
public TestCaseReportMetricDTO countReportData(TestPlanDTO testPlan, TestPlanReportDataWithBLOBs testPlanReportData) {
TestCaseReportMetricDTO returnDTO = new TestCaseReportMetricDTO();
ReportResultComponent reportResultComponent = new ReportResultComponent(testPlan);
reportResultComponent.afterBuild(returnDTO);
TestCaseReportAdvanceStatusResultDTO statusDTO = new TestCaseReportAdvanceStatusResultDTO();
String apiCaseExecuteMapJson = testPlanReportData.getApiCaseInfo();
String scenarioExecuteMapJson = testPlanReportData.getScenarioInfo();
String loadExecuteMapJson = testPlanReportData.getPerformanceInfo();
List<TestCaseReportStatusResultDTO> apiResult = new ArrayList<>();
List<TestCaseReportStatusResultDTO> scenarioResult = new ArrayList<>();
List<TestCaseReportStatusResultDTO> loadResult = new ArrayList<>();
List<String> faliureApiCaseIdList = new ArrayList<>();
List<String> faliureScenarioCaseIdList = new ArrayList<>();
List<String> faliureLoadCaseIdList = new ArrayList<>();
JSONArray apiCaseExecuteArr = new JSONArray();
JSONArray scenarioExecuteArr = new JSONArray();
JSONArray loadExecuteArr = new JSONArray();
if (StringUtils.isNotEmpty(apiCaseExecuteMapJson)) {
try {
apiCaseExecuteArr = JSONArray.parseArray(apiCaseExecuteMapJson);
} catch (Exception e) {
}
}
if (StringUtils.isNotEmpty(scenarioExecuteMapJson)) {
try {
scenarioExecuteArr = JSONArray.parseArray(scenarioExecuteMapJson);
} catch (Exception e) {
}
}
if (StringUtils.isNotEmpty(loadExecuteMapJson)) {
try {
loadExecuteArr = JSONArray.parseArray(loadExecuteMapJson);
} catch (Exception e) {
}
}
for (int i = 0; i < apiCaseExecuteArr.size(); i++) {
JSONObject jsonObj = apiCaseExecuteArr.getJSONObject(i);
Map<String, Integer> countMap = new HashMap<>();
if (jsonObj.containsKey("status")) {
String status = jsonObj.getString("status");
if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.SUCCESS.name())) {
if (countMap.containsKey("Pass")) {
countMap.put("Pass", countMap.get("Pass") + 1);
} else {
countMap.put("Pass", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.FAILD.name())) {
if (jsonObj.containsKey("id")) {
faliureApiCaseIdList.add(jsonObj.getString("id"));
}
if (countMap.containsKey("Failure")) {
countMap.put("Failure", countMap.get("Failure") + 1);
} else {
countMap.put("Failure", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.PREPARE.name())) {
if (jsonObj.containsKey("id")) {
faliureApiCaseIdList.add(jsonObj.getString("id"));
}
if (countMap.containsKey("Skip")) {
countMap.put("Skip", countMap.get("Skip") + 1);
} else {
countMap.put("Skip", 1);
}
} else {
if (countMap.containsKey("Underway")) {
countMap.put("Underway", countMap.get("Underway") + 1);
} else {
countMap.put("Underway", 1);
}
}
}
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
String status = entry.getKey();
Integer value = entry.getValue();
TestCaseReportStatusResultDTO dto = new TestCaseReportStatusResultDTO();
dto.setStatus(status);
dto.setCount(value);
apiResult.add(dto);
}
}
for (int i = 0; i < scenarioExecuteArr.size(); i++) {
JSONObject jsonObj = scenarioExecuteArr.getJSONObject(i);
Map<String, Integer> countMap = new HashMap<>();
if (jsonObj.containsKey("status")) {
String status = jsonObj.getString("status");
if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.SUCCESS.name())) {
if (countMap.containsKey("Pass")) {
countMap.put("Pass", countMap.get("Pass") + 1);
} else {
countMap.put("Pass", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.FAILD.name())) {
if (jsonObj.containsKey("id")) {
faliureScenarioCaseIdList.add(jsonObj.getString("id"));
}
if (countMap.containsKey("Failure")) {
countMap.put("Failure", countMap.get("Failure") + 1);
} else {
countMap.put("Failure", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.PREPARE.name())) {
if (jsonObj.containsKey("id")) {
faliureScenarioCaseIdList.add(jsonObj.getString("id"));
}
if (countMap.containsKey("Skip")) {
countMap.put("Skip", countMap.get("Skip") + 1);
} else {
countMap.put("Skip", 1);
}
} else {
if (countMap.containsKey("Underway")) {
countMap.put("Underway", countMap.get("Underway") + 1);
} else {
countMap.put("Underway", 1);
}
}
}
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
String status = entry.getKey();
Integer value = entry.getValue();
TestCaseReportStatusResultDTO dto = new TestCaseReportStatusResultDTO();
dto.setStatus(status);
dto.setCount(value);
scenarioResult.add(dto);
}
}
for (int i = 0; i < loadExecuteArr.size(); i++) {
JSONObject jsonObj = loadExecuteArr.getJSONObject(i);
Map<String, Integer> countMap = new HashMap<>();
if (jsonObj.containsKey("status")) {
String status = jsonObj.getString("status");
if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.SUCCESS.name())) {
if (countMap.containsKey("Pass")) {
countMap.put("Pass", countMap.get("Pass") + 1);
} else {
countMap.put("Pass", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.FAILD.name())) {
if (jsonObj.containsKey("id")) {
faliureLoadCaseIdList.add(jsonObj.getString("id"));
}
if (countMap.containsKey("Failure")) {
countMap.put("Failure", countMap.get("Failure") + 1);
} else {
countMap.put("Failure", 1);
}
} else if (StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.PREPARE.name())) {
if (jsonObj.containsKey("id")) {
faliureLoadCaseIdList.add(jsonObj.getString("id"));
}
if (countMap.containsKey("Skip")) {
countMap.put("Skip", countMap.get("Skip") + 1);
} else {
countMap.put("Skip", 1);
}
} else {
if (countMap.containsKey("Underway")) {
countMap.put("Underway", countMap.get("Underway") + 1);
} else {
countMap.put("Underway", 1);
}
}
}
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
String status = entry.getKey();
Integer value = entry.getValue();
TestCaseReportStatusResultDTO dto = new TestCaseReportStatusResultDTO();
dto.setStatus(status);
dto.setCount(value);
loadResult.add(dto);
}
}
statusDTO.setApiResult(apiResult);
statusDTO.setScenarioResult(scenarioResult);
statusDTO.setLoadResult(loadResult);
returnDTO.setExecuteResult(statusDTO);
//统计失败用例
FailureTestCasesAdvanceDTO failureDto = new FailureTestCasesAdvanceDTO();
failureDto.setFunctionalTestCases(new ArrayList<>());
if (!faliureApiCaseIdList.isEmpty()) {
TestPlanApiCaseService testPlanApiCaseService = CommonBeanFactory.getBean(TestPlanApiCaseService.class);
ApiTestCaseRequest request = new ApiTestCaseRequest();
request.setPlanId(testPlan.getId());
request.setIds(faliureApiCaseIdList);
List<TestPlanApiCaseDTO> testPlanApiCaseDTOList = testPlanApiCaseService.list(request);
failureDto.setApiTestCases(testPlanApiCaseDTOList);
} else {
failureDto.setApiTestCases(new ArrayList<>());
}
if (!faliureScenarioCaseIdList.isEmpty()) {
TestPlanScenarioCaseService testPlanScenarioCaseService = CommonBeanFactory.getBean(TestPlanScenarioCaseService.class);
TestPlanScenarioRequest request = new TestPlanScenarioRequest();
request.setPlanId(testPlan.getId());
request.setScenarioIds(faliureScenarioCaseIdList);
List<ApiScenarioDTO> scenarioDTOS = testPlanScenarioCaseService.list(request);
failureDto.setScenarioTestCases(scenarioDTOS);
} else {
failureDto.setScenarioTestCases(new ArrayList<>());
}
if (!faliureLoadCaseIdList.isEmpty()) {
TestPlanLoadCaseService testPlanLoadCaseService = CommonBeanFactory.getBean(TestPlanLoadCaseService.class);
LoadCaseRequest request = new LoadCaseRequest();
request.setTestPlanId(testPlan.getId());
request.setIds(faliureLoadCaseIdList);
List<TestPlanLoadCaseDTO> loadDTOs = testPlanLoadCaseService.list(request);
failureDto.setLoadTestCases(loadDTOs);
} else {
failureDto.setLoadTestCases(new ArrayList<>());
}
returnDTO.setFailureTestCases(failureDto);
return returnDTO;
}
public void updateReport(TestPlanReportDataWithBLOBs testPlanReportData, boolean apiCaseIsOk, boolean scenarioIsOk, boolean performanceIsOk) {
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(testPlanReportData.getTestPlanReportId());
if (testPlanReport == null) {
return;
}
testPlanReport.setEndTime(System.currentTimeMillis());
testPlanReport.setUpdateTime(System.currentTimeMillis());
if (apiCaseIsOk) {
testPlanReport.setIsApiCaseExecuting(false);
}
if (scenarioIsOk) {
testPlanReport.setIsScenarioExecuting(false);
}
if (performanceIsOk) {
testPlanReport.setIsPerformanceExecuting(false);
}
int[] componentIndexArr = new int[]{1, 3, 4};
testPlanReport.setComponents(JSONArray.toJSONString(componentIndexArr));
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
queryTestPlanRequest.setId(testPlanReport.getTestPlanId());
TestPlanDTO testPlan = extTestPlanMapper.list(queryTestPlanRequest).get(0);
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
JSONArray componentIds = JSONArray.parseArray(testPlanReport.getComponents());
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
testPlanService.buildApiCaseReport(testPlanReport.getTestPlanId(), components);
testPlanService.buildScenarioCaseReport(testPlanReport.getTestPlanId(), components);
testPlanService.buildLoadCaseReport(testPlanReport.getTestPlanId(), components);
TestCaseReportMetricDTO testCaseReportMetricDTO = this.countReportData(testPlan, testPlanReportData);
//统计执行的场景ID
testPlanReportData.setExecuteResult(JSONObject.toJSONString(testCaseReportMetricDTO.getExecuteResult()));
testPlanReportData.setFailurTestCases(JSONObject.toJSONString(testCaseReportMetricDTO.getFailureTestCases()));
testPlanReportData.setModuleExecuteResult(JSONArray.toJSONString(testCaseReportMetricDTO.getModuleExecuteResult()));
testPlanReportDataMapper.updateByPrimaryKeyWithBLOBs(testPlanReportData);
String testPlanStatus = this.getTestPlanReportStatus(testPlanReport, testPlanReportData);
testPlanReport.setStatus(testPlanStatus);
this.update(testPlanReport);
}
public void checkTestPlanStatus(String planReportId) {
try {
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(planReportId);
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
testPlanService.checkStatus(testPlanReport.getTestPlanId());
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
@ -239,7 +607,7 @@ public class TestPlanReportService {
* @param resourceRunMode 资源的运行模式,triggerMode非Scedule可以为null
* @param triggerMode 触发方式 ReportTriggerMode.enum
*/
public void countReportByTestPlanReportId(String planReportId, String resourceRunMode, String triggerMode,List<String> scenarioIdList) {
public void countReportByTestPlanReportId(String planReportId, String resourceRunMode, String triggerMode, List<String> scenarioIdList) {
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(planReportId);
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
@ -272,7 +640,7 @@ public class TestPlanReportService {
}
testPlanReport.setComponents(JSONArray.toJSONString(componentIndexArr));
// JSONObject content = JSONObject.parseObject("{\"components\":[1,2,3,4,5]}");
TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class);
JSONArray componentIds = JSONArray.parseArray(testPlanReport.getComponents());
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
testPlanService.buildApiCaseReport(testPlanReport.getTestPlanId(), components);
@ -326,37 +694,36 @@ public class TestPlanReportService {
testPlanReportData = testPlanReportDataList.get(0);
if (CollectionUtils.isNotEmpty(scenarioIdList)
&&StringUtils.equalsAny(triggerMode, ReportTriggerMode.SCHEDULE.name(), ReportTriggerMode.API.name())
&& StringUtils.equalsAny(resourceRunMode, ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
try{
List<String> scenarioListArr = JSONArray.parseArray(testPlanReportData.getScenarioInfo(),String.class);
TestCaseReportAdvanceStatusResultDTO savedDTO = JSONObject.parseObject(testPlanReportData.getExecuteResult(),TestCaseReportAdvanceStatusResultDTO.class);
&& StringUtils.equalsAny(triggerMode, ReportTriggerMode.SCHEDULE.name(), ReportTriggerMode.API.name())
&& StringUtils.equalsAny(resourceRunMode, ApiRunMode.SCHEDULE_SCENARIO_PLAN.name(), ApiRunMode.JENKINS_SCENARIO_PLAN.name())) {
try {
List<String> scenarioListArr = JSONArray.parseArray(testPlanReportData.getScenarioInfo(), String.class);
TestCaseReportAdvanceStatusResultDTO savedDTO = JSONObject.parseObject(testPlanReportData.getExecuteResult(), TestCaseReportAdvanceStatusResultDTO.class);
List<String> executeScenarioList = new ArrayList<>();
if(savedDTO != null){
if(savedDTO.getExecutedScenarioIds() != null){
if (savedDTO != null) {
if (savedDTO.getExecutedScenarioIds() != null) {
executeScenarioList = savedDTO.getExecutedScenarioIds();
}
}
for (String scenarioId : scenarioIdList) {
for (String scenarioId : scenarioIdList) {
if (!executeScenarioList.contains(scenarioId)) {
executeScenarioList.add(scenarioId);
}
}
if(testCaseReportMetricDTO.getExecuteResult() == null){
if (testCaseReportMetricDTO.getExecuteResult() == null) {
TestCaseReportAdvanceStatusResultDTO executeResultDTO = new TestCaseReportAdvanceStatusResultDTO();
testCaseReportMetricDTO.setExecuteResult(executeResultDTO);
}
testCaseReportMetricDTO.getExecuteResult().setExecutedScenarioIds(executeScenarioList);
if(!CollectionUtils.isEqualCollection(scenarioListArr,executeScenarioList)){
if (!CollectionUtils.isEqualCollection(scenarioListArr, executeScenarioList)) {
testPlanReport.setIsScenarioExecuting(true);
}
}catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
}
//统计执行的场景ID
testPlanReportData.setExecuteResult(JSONObject.toJSONString(testCaseReportMetricDTO.getExecuteResult()));
testPlanReportData.setFailurTestCases(JSONObject.toJSONString(testCaseReportMetricDTO.getFailureTestCases()));
testPlanReportData.setModuleExecuteResult(JSONArray.toJSONString(testCaseReportMetricDTO.getModuleExecuteResult()));
@ -390,21 +757,21 @@ public class TestPlanReportService {
JSONObject failurCaseObject = JSONObject.parseObject(failCaseString);
if (failurCaseObject.containsKey("apiTestCases") && failurCaseObject.getJSONArray("apiTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("apiTestCases");
if(array.size() > 0){
if (array.size() > 0) {
status = TestPlanReportStatus.FAILED.name();
return status;
}
}
if (failurCaseObject.containsKey("loadTestCases") && failurCaseObject.getJSONArray("loadTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("loadTestCases");
if(array.size() > 0){
if (array.size() > 0) {
status = TestPlanReportStatus.FAILED.name();
return status;
}
}
if (failurCaseObject.containsKey("scenarioTestCases") && failurCaseObject.getJSONArray("scenarioTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("scenarioTestCases");
if(array.size() > 0){
if (array.size() > 0) {
status = TestPlanReportStatus.FAILED.name();
return status;
}
@ -443,7 +810,7 @@ public class TestPlanReportService {
}
public void sendMessage(TestPlanReport testPlanReport) {
TestPlan testPlan = testPlanService.getTestPlan(testPlanReport.getTestPlanId());
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(testPlanReport.getTestPlanId());
assert testPlan != null;
SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class);
NoticeSendService noticeSendService = CommonBeanFactory.getBean(NoticeSendService.class);
@ -511,19 +878,20 @@ public class TestPlanReportService {
* @param performaneReportIDList
*/
public void updatePerformanceInfo(TestPlanReport testPlanReport, List<String> performaneReportIDList, String triggerMode) {
TestPlanReportDataExample example = new TestPlanReportDataExample();
example.createCriteria().andTestPlanReportIdEqualTo(testPlanReport.getId());
List<TestPlanReportDataWithBLOBs> reportDataList = testPlanReportDataMapper.selectByExampleWithBLOBs(example);
for (TestPlanReportDataWithBLOBs models : reportDataList) {
models.setPerformanceInfo(JSONArray.toJSONString(performaneReportIDList));
testPlanReportDataMapper.updateByPrimaryKeyWithBLOBs(models);
}
// TestPlanReportDataExample example = new TestPlanReportDataExample();
// example.createCriteria().andTestPlanReportIdEqualTo(testPlanReport.getId());
// List<TestPlanReportDataWithBLOBs> reportDataList = testPlanReportDataMapper.selectByExampleWithBLOBs(example);
// for (TestPlanReportDataWithBLOBs models : reportDataList) {
// models.setPerformanceInfo(JSONArray.toJSONString(performaneReportIDList));
// testPlanReportDataMapper.updateByPrimaryKeyWithBLOBs(models);
// }
/**
* 虽然kafka已经设置了topic推送但是当执行机器性能不够时会影响到报告状态当修改
* 同时如果执行过程中报告删除那么此时也应当记为失败
*/
List<String> updatePerformaneReportIDList = new ArrayList<>(performaneReportIDList);
Map<String, String> finishLoadTestId = new HashMap<>();
executorService.submit(() -> {
//错误数据检查集合 如果错误数据出现超过20次则取消该条数据的检查
Map<String, Integer> errorDataCheckMap = new HashMap<>();
@ -544,17 +912,23 @@ public class TestPlanReportService {
}
} else if (StringUtils.equalsAny(loadTestReportFromDatabase.getStatus(),
PerformanceTestStatus.Completed.name(), PerformanceTestStatus.Error.name())) {
finishLoadTestId.put(loadTestReportFromDatabase.getTestId(), TestPlanApiExecuteStatus.SUCCESS.name());
performaneReportIDList.remove(loadTestReportId);
}
}
if (performaneReportIDList.isEmpty()) {
for (String string : updatePerformaneReportIDList) {
TestPlanLoadCaseEventDTO eventDTO = new TestPlanLoadCaseEventDTO();
eventDTO.setReportId(string);
eventDTO.setTriggerMode(triggerMode);
eventDTO.setStatus(PerformanceTestStatus.Completed.name());
this.updatePerformanceTestStatus(eventDTO);
if (StringUtils.equals(triggerMode, ReportTriggerMode.API.name())) {
for (String string : updatePerformaneReportIDList) {
TestPlanLoadCaseEventDTO eventDTO = new TestPlanLoadCaseEventDTO();
eventDTO.setReportId(string);
eventDTO.setTriggerMode(triggerMode);
eventDTO.setStatus(PerformanceTestStatus.Completed.name());
this.updatePerformanceTestStatus(eventDTO);
}
} else {
this.updateExecuteApis(testPlanReport.getId(), null, null, finishLoadTestId);
}
} else {
try {
//查询定时任务是否关闭
@ -625,4 +999,106 @@ public class TestPlanReportService {
}
return null;
}
public synchronized void updateExecuteApis(String planReportId, Map<String, String> executeApiCaseIdMap, Map<String, String> executeScenarioCaseIdMap, Map<String, String> executePerformanceIdMap) {
TestPlanReportDataExample example = new TestPlanReportDataExample();
if(executeApiCaseIdMap == null){
executeApiCaseIdMap = new HashMap<>();
}
if(executeScenarioCaseIdMap == null){
executeScenarioCaseIdMap = new HashMap<>();
}
if(executePerformanceIdMap == null){
executePerformanceIdMap = new HashMap<>();
}
example.createCriteria().andTestPlanReportIdEqualTo(planReportId);
List<TestPlanReportDataWithBLOBs> reportDataList = testPlanReportDataMapper.selectByExampleWithBLOBs(example);
if (!reportDataList.isEmpty()) {
TestPlanReportDataWithBLOBs reportData = reportDataList.get(0);
boolean apiCaseExecuteOk = true;
try {
JSONArray executeArr = JSONArray.parseArray(reportData.getApiCaseInfo());
JSONArray newArr = new JSONArray();
for (int i = 0; i < executeArr.size(); i++) {
JSONObject caseInfo = executeArr.getJSONObject(i);
if (caseInfo.containsKey("id") && caseInfo.containsKey("status")) {
if (MapUtils.isNotEmpty(executeApiCaseIdMap)) {
String id = caseInfo.getString("id");
String status = caseInfo.getString("status");
String updateStatus = executeApiCaseIdMap.get(id);
if (StringUtils.isNotEmpty(updateStatus)
&& !StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.SUCCESS.name(), TestPlanApiExecuteStatus.FAILD.name())) {
caseInfo.put("status", updateStatus);
}
}
if (StringUtils.equals(TestPlanApiExecuteStatus.RUNNING.name(), caseInfo.getString("status"))) {
apiCaseExecuteOk = false;
}
newArr.add(caseInfo);
}
}
reportData.setApiCaseInfo(newArr.toJSONString());
} catch (Exception e) {
}
boolean scenarioExecuteOk = true;
try {
JSONArray executeArr = JSONArray.parseArray(reportData.getScenarioInfo());
JSONArray newArr = new JSONArray();
for (int i = 0; i < executeArr.size(); i++) {
JSONObject caseInfo = executeArr.getJSONObject(i);
if (caseInfo.containsKey("id") && caseInfo.containsKey("status")) {
if (MapUtils.isNotEmpty(executeScenarioCaseIdMap)) {
String id = caseInfo.getString("id");
String status = caseInfo.getString("status");
String updateStatus = executeScenarioCaseIdMap.get(id);
if (StringUtils.isNotEmpty(updateStatus)
&& !StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.SUCCESS.name(), TestPlanApiExecuteStatus.FAILD.name())) {
caseInfo.put("status", updateStatus);
}
}
if (StringUtils.equals(TestPlanApiExecuteStatus.RUNNING.name(), caseInfo.getString("status"))) {
scenarioExecuteOk = false;
}
newArr.add(caseInfo);
}
}
reportData.setScenarioInfo(newArr.toJSONString());
} catch (Exception e) {
}
boolean performanceExecuteOk = true;
try {
JSONArray executeArr = JSONArray.parseArray(reportData.getPerformanceInfo());
JSONArray newArr = new JSONArray();
for (int i = 0; i < executeArr.size(); i++) {
JSONObject caseInfo = executeArr.getJSONObject(i);
if (caseInfo.containsKey("id") && caseInfo.containsKey("status")) {
if (MapUtils.isNotEmpty(executePerformanceIdMap)) {
String id = caseInfo.getString("id");
String status = caseInfo.getString("status");
String updateStatus = executePerformanceIdMap.get(id);
if (StringUtils.isNotEmpty(updateStatus)
&& !StringUtils.equalsAnyIgnoreCase(status, TestPlanApiExecuteStatus.SUCCESS.name(), TestPlanApiExecuteStatus.FAILD.name())) {
caseInfo.put("status", updateStatus);
}
}
if (StringUtils.equals(TestPlanApiExecuteStatus.RUNNING.name(), caseInfo.getString("status"))) {
performanceExecuteOk = false;
}
newArr.add(caseInfo);
}
}
reportData.setPerformanceInfo(newArr.toJSONString());
} catch (Exception e) {
}
testPlanReportDataMapper.updateByPrimaryKeySelective(reportData);
this.updateReport(reportData, apiCaseExecuteOk, scenarioExecuteOk, performanceExecuteOk);
}
}
}

View File

@ -60,7 +60,6 @@ import java.util.*;
import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanService {
@Resource
ExtScheduleMapper extScheduleMapper;
@ -137,6 +136,8 @@ public class TestPlanService {
private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
private TestPlanReportMapper testPlanReportMapper;
@Resource
private TestPlanReportService testPlanReportService;
@Lazy
@Resource
private IssuesService issuesService;
@ -406,7 +407,6 @@ public class TestPlanService {
statusList.addAll(testPlanApiCaseService.getExecResultByPlanId(testPlanId));
statusList.addAll(testPlanScenarioCaseService.getExecResultByPlanId(testPlanId));
statusList.addAll(testPlanLoadCaseService.getStatus(testPlanId));
// Prepare, Pass, Failure, Blocking, Skip, Underway
TestPlanDTO testPlanDTO = new TestPlanDTO();
testPlanDTO.setId(testPlanId);
if (statusList.size() == 0) { // 原先status不是prepare, 但删除所有关联用例的情况
@ -866,7 +866,6 @@ public class TestPlanService {
String returnStr = null;
for (Map.Entry<String, Map<String, String>> entry : testPlanScenarioIdMap.entrySet()) {
// String testPlanId = entry.getKey();
Map<String, String> scenarioMap = entry.getValue();
RunScenarioRequest request = new RunScenarioRequest();
@ -881,8 +880,8 @@ public class TestPlanService {
request.setConfig(planScenarioExecuteRequest.getConfig());
request.setTestPlanScheduleJob(true);
request.setTestPlanReportId(planScenarioExecuteRequest.getTestPlanReportId());
// request.getConfig().getReportType()
request.setId(UUID.randomUUID().toString());
if (request.getConfig() != null) {
if (request.getConfig().getMode().equals(RunModeConstants.PARALLEL.toString())) {
// 校验并发数量
@ -998,9 +997,6 @@ public class TestPlanService {
}
public String run(String testPlanID, String projectID, String userId, String triggerMode, String apiRunConfig) {
Map<String, String> planScenarioIdMap;
Map<String, String> apiTestCaseIdMap;
Map<String, String> performanceIdMap;
if (StringUtils.isEmpty(apiRunConfig)) {
apiRunConfig =
"{\"mode\":\"parallel\"," +
@ -1009,48 +1005,23 @@ public class TestPlanService {
"\"runWithinResourcePool\":true," +
"\"resourcePoolId\":\"29773f4f-55e4-4bce-ad3d-b531b4eb59c2\"}";
}
planScenarioIdMap = new LinkedHashMap<>();
apiTestCaseIdMap = new LinkedHashMap<>();
performanceIdMap = new LinkedHashMap<>();
List<TestPlanApiScenario> testPlanApiScenarioList = testPlanScenarioCaseService.getCasesByPlanId(testPlanID);
for (TestPlanApiScenario model : testPlanApiScenarioList) {
planScenarioIdMap.put(model.getApiScenarioId(), model.getId());
}
List<TestPlanApiCase> testPlanApiCaseList = testPlanApiCaseService.getCasesByPlanId(testPlanID);
for (TestPlanApiCase model :
testPlanApiCaseList) {
apiTestCaseIdMap.put(model.getApiCaseId(), model.getId());
}
LoadCaseRequest loadCaseRequest = new LoadCaseRequest();
loadCaseRequest.setTestPlanId(testPlanID);
loadCaseRequest.setProjectId(projectID);
List<TestPlanLoadCaseDTO> testPlanLoadCaseDTOList = testPlanLoadCaseService.list(loadCaseRequest);
for (TestPlanLoadCaseDTO dto : testPlanLoadCaseDTOList) {
performanceIdMap.put(dto.getId(), dto.getLoadCaseId());
}
LogUtil.info("-------------- start testplan schedule ----------");
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
boolean apiCaseIsExcuting = false;
boolean scenarioIsExcuting = false;
boolean performaceIsExcuting = false;
String apiCaseIdArray = "";
String scenarioCaseIdArray = "";
String performanceCaseIdArray = "";
String planReportId = UUID.randomUUID().toString();
//创建测试报告然后返回的ID重新赋值为resourceID作为后续的参数
TestPlanReportSaveRequest saveRequest = new TestPlanReportSaveRequest(planReportId, testPlanID, userId, triggerMode,
apiTestCaseIdMap.size() > 0, planScenarioIdMap.size() > 0, performanceIdMap.size() > 0,
JSONArray.toJSONString(new ArrayList<>(apiTestCaseIdMap.keySet())), JSONArray.toJSONString(new ArrayList<>(planScenarioIdMap.keySet())), JSONArray.toJSONString(new ArrayList<>(performanceIdMap.values())));
TestPlanScheduleReportInfoDTO reportInfoDTO = testPlanReportService.genTestPlanReportBySchedule(projectID,testPlanID,userId,triggerMode);
TestPlanReport testPlanReport = reportInfoDTO.getTestPlanReport();
Map<String, String> planScenarioIdMap = reportInfoDTO.getPlanScenarioIdMap();
Map<String, String> apiTestCaseIdMap = reportInfoDTO.getApiTestCaseIdMap();
Map<String, String> performanceIdMap = reportInfoDTO.getPerformanceIdMap();
TestPlanReport testPlanReport = testPlanReportService.genTestPlanReport(saveRequest);
String planReportId = testPlanReport.getId();
//不同任务的执行ID
Map<String,String> executePerformanceIdMap = new HashMap<>();
Map<String,String> executeApiCaseIdMap = new HashMap<>();
Map<String,String> executeScenarioCaseIdMap = new HashMap<>();
//执行性能测试任务
List<String> performaneReportIDList = new ArrayList<>();
List<String> performanceRunCaseIdList = new ArrayList<>();
for (Map.Entry<String, String> entry : performanceIdMap.entrySet()) {
String id = entry.getKey();
String caseID = entry.getValue();
@ -1067,7 +1038,6 @@ public class TestPlanService {
reportId = performanceTestService.run(performanceRequest);
if (reportId != null) {
performaneReportIDList.add(reportId);
TestPlanLoadCase testPlanLoadCase = new TestPlanLoadCase();
testPlanLoadCase.setId(performanceRequest.getTestPlanLoadId());
testPlanLoadCase.setLoadReportId(reportId);
@ -1083,26 +1053,29 @@ public class TestPlanService {
e.printStackTrace();
}
if (StringUtils.isNotEmpty(reportId)) {
performanceRunCaseIdList.add(caseID);
executePerformanceIdMap.put(caseID,TestPlanApiExecuteStatus.RUNNING.name());
}
}
if (!performanceRunCaseIdList.isEmpty()) {
performaceIsExcuting = true;
performanceCaseIdArray = JSONArray.toJSONString(new ArrayList<>(performanceRunCaseIdList));
}
if (!performaneReportIDList.isEmpty()) {
//性能测试时保存性能测试报告ID在结果返回时用于捕捉并进行
testPlanReportService.updatePerformanceInfo(testPlanReport, performaneReportIDList, triggerMode);
}
for (Map.Entry<String, String> entry : apiTestCaseIdMap.entrySet()) {
String apiCaseID = entry.getKey();
executeApiCaseIdMap.put(apiCaseID,TestPlanApiExecuteStatus.RUNNING.name());
}
for (String id : planScenarioIdMap.keySet()) {
executeScenarioCaseIdMap.put(id,TestPlanApiExecuteStatus.RUNNING.name());
}
testPlanReportService.updateExecuteApis(planReportId,executeApiCaseIdMap,executeScenarioCaseIdMap,executePerformanceIdMap);
//执行接口案例任务
for (Map.Entry<String, String> entry : apiTestCaseIdMap.entrySet()) {
String apiCaseID = entry.getKey();
String planCaseID = entry.getValue();
// String planCaseID = entry.getValue();
ApiTestCaseWithBLOBs blobs = apiTestCaseService.get(apiCaseID);
//需要更新这里来保证PlanCase的状态能正常更改
if (StringUtils.equals(triggerMode, ReportTriggerMode.API.name())) {
@ -1110,11 +1083,7 @@ public class TestPlanService {
} else {
apiTestCaseService.run(blobs, UUID.randomUUID().toString(), planReportId, testPlanID, ApiRunMode.SCHEDULE_API_PLAN.name());
}
apiCaseIsExcuting = true;
}
if (apiCaseIsExcuting) {
apiCaseIdArray = JSONArray.toJSONString(new ArrayList<>(apiTestCaseIdMap.keySet()));
executeApiCaseIdMap.put(apiCaseID,TestPlanApiExecuteStatus.RUNNING.name());
}
//执行场景执行任务
@ -1143,19 +1112,10 @@ public class TestPlanService {
RunModeConfig runModeConfig = JSONObject.parseObject(apiRunConfig, RunModeConfig.class);
scenarioRequest.setConfig(runModeConfig);
String scenarioReportID = this.scenarioRunModeConfig(scenarioRequest);
if (StringUtils.isNotEmpty(scenarioReportID)) {
scenarioIsExcuting = true;
scenarioCaseIdArray = JSONArray.toJSONString(new ArrayList<>(planScenarioIdMap.keySet()));
}
}
//如果report参数和预期不对某些原因执行失败则更新report
if (saveRequest.isApiCaseIsExecuting() != apiCaseIsExcuting || saveRequest.isScenarioIsExecuting() != scenarioIsExcuting || saveRequest.isPerformanceIsExecuting() != performaceIsExcuting) {
testPlanReport.setIsApiCaseExecuting(apiCaseIsExcuting);
testPlanReport.setIsScenarioExecuting(scenarioIsExcuting);
testPlanReport.setIsPerformanceExecuting(performaceIsExcuting);
testPlanReportService.update(testPlanReport);
// if (StringUtils.isNotEmpty(scenarioReportID)) {
// scenarioIsExcuting = true;
// scenarioCaseIdArray = JSONArray.toJSONString(new ArrayList<>(planScenarioIdMap.keySet()));
// }
}
return testPlanReport.getId();
}

View File

@ -34,57 +34,16 @@
default() {
return {
functionalTestCases: [
{
name: 'testCase1',
priority: 'P1',
type: 'api',
method: 'auto',
nodePath: '/module1/module2',
executorName: "Tom",
status: "Failure",
updateTime: new Date(),
},
{
name: 'testCase2',
priority: 'P0',
type: 'functional',
method: 'manual',
nodePath: '/module1',
executorName: "Micheal",
status: "Failure",
updateTime: new Date()
}
],
apiTestCases: [
{
name: 'testCase3',
priority: 'P2',
path: '/module1/module2',
createUser: "Tom",
lastResult: "Failure",
updateTime: new Date(),
}
],
scenarioTestCases: [
{
name: 'testCase4',
level: 'P3',
modulePath: '/module1/module2',
stepTotal: 10,
passRate: '80%',
userId: "Tom",
lastResult: "Failure",
updateTime: new Date(),
}
],
loadTestCases: [
{
caseName: 'testCase5',
projectName: '测试项目',
userName: 'Tom',
createTime: new Date(),
caseStatus: 'error',
}
]
}
}

View File

@ -88,17 +88,37 @@
},
computed: {
showFunctional() {
return this.executeResult.functionalResult.length > 0
|| (this.executeResult.apiResult.length <= 0 && this.executeResult.scenarioResult.length <= 0 && this.executeResult.loadResult.length <= 0);
if(this.executeResult.functionalResult){
return this.executeResult.functionalResult.length > 0
|| (this.executeResult.apiResult.length <= 0 && this.executeResult.scenarioResult.length <= 0 && this.executeResult.loadResult.length <= 0);
}else {
return false;
}
},
showApi() {
return this.executeResult.apiResult.length > 0;
if(this.executeResult.apiResult){
return this.executeResult.apiResult.length > 0;
}else {
return false;
}
},
showScenario() {
return this.executeResult.scenarioResult.length > 0;
if(this.executeResult.scenarioResult){
return this.executeResult.scenarioResult.length > 0;
}else {
return false;
}
},
showLoad() {
return this.executeResult.loadResult.length > 0;
if(this.executeResult.loadResult){
return this.executeResult.loadResult.length > 0;
}else {
return false;
}
}
},
watch: {
@ -158,7 +178,9 @@
}
},
copyData(status) {
return JSON.parse(JSON.stringify(this.dataMap.get(status)))
if(this.dataMap.get(status)){
return JSON.parse(JSON.stringify(this.dataMap.get(status)))
}
},
reload() {
this.isShow = false;