fix(测试计划报告、接口定义): #1006127 【接口测试】tcp同时开两个接口,点【mock设置】按钮会串;测试计划批量执行、定时任务、Jenkins调用时报告模板更新

【【接口测试】tcp同时开两个接口,点【mock设置】按钮会串】https://www.tapd.cn/55049933/bugtrace/bugs/view?bug_id=1155049933001006127;测试计划批量执行、定时任务、Jenkins调用时报告模板更新
This commit is contained in:
song-tianyang 2021-08-24 17:33:53 +08:00 committed by 刘瑞斌
parent 23da6a5473
commit 4a46dadadc
21 changed files with 336 additions and 130 deletions

View File

@ -1,6 +1,8 @@
package io.metersphere.api.cache;
import io.metersphere.api.dto.automation.APIScenarioReportResult;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import io.metersphere.commons.constants.TestPlanApiExecuteStatus;
import io.metersphere.commons.constants.TestPlanResourceType;
import lombok.Getter;
@ -22,6 +24,11 @@ public class TestPlanExecuteInfo {
private Map<String, String> apiCaseExecInfo = new HashMap<>();
private Map<String, String> apiScenarioCaseExecInfo = new HashMap<>();
private Map<String, String> loadCaseExecInfo = new HashMap<>();
private Map<String, ApiDefinitionExecResult> apiCaseExecuteReportMap = new HashMap<>();
private Map<String, APIScenarioReportResult> apiScenarioReportReportMap = new HashMap<>();
private Map<String,String> loadCaseReportIdMap = new HashMap<>();
private boolean reportDataInDataBase;
int lastUnFinishedNumCount = 0;
@ -45,6 +52,20 @@ public class TestPlanExecuteInfo {
}
}
public synchronized void updateExecuteResult(Map<String, ApiDefinitionExecResult> apiCaseExecResultInfo, Map<String, APIScenarioReportResult> apiScenarioCaseExecResultInfo, Map<String, String> loadCaseExecResultInfo) {
if (MapUtils.isNotEmpty(apiCaseExecResultInfo)) {
this.apiCaseExecuteReportMap.putAll(apiCaseExecResultInfo);
}
if (MapUtils.isNotEmpty(apiScenarioCaseExecResultInfo)) {
this.apiScenarioReportReportMap.putAll(apiScenarioCaseExecResultInfo);
}
if (MapUtils.isNotEmpty(loadCaseExecResultInfo)) {
this.loadCaseReportIdMap.putAll(loadCaseExecResultInfo);
}
}
public synchronized int countUnFinishedNum() {
int unFinishedCount = 0;

View File

@ -1,5 +1,8 @@
package io.metersphere.api.cache;
import io.metersphere.api.dto.automation.APIScenarioReportResult;
import io.metersphere.base.domain.ApiDefinitionExecResult;
import java.util.HashMap;
import java.util.Map;
@ -43,6 +46,14 @@ public class TestPlanReportExecuteCatch {
}
}
public synchronized static void updateTestPlanExecuteResultInfo(String reportId,
Map<String, ApiDefinitionExecResult> apiCaseExecResultInfo, Map<String, APIScenarioReportResult> apiScenarioCaseExecResultInfo, Map<String, String> loadCaseExecResultInfo) {
if(testPlanReportMap != null && testPlanReportMap.containsKey(reportId)){
testPlanReportMap.get(reportId).updateExecuteResult(apiCaseExecResultInfo,apiScenarioCaseExecResultInfo,loadCaseExecResultInfo);
}
}
public static TestPlanExecuteInfo getTestPlanExecuteInfo(String reportId){
return testPlanReportMap.get(reportId);
}

View File

@ -224,6 +224,7 @@ public class ApiDefinitionExecResultService {
String finalSaveResultType = saveResultType;
Map<String, String> apiIdResultMap = new HashMap<>();
Map<String,ApiDefinitionExecResult> caseReportMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(result.getScenarios())) {
result.getScenarios().forEach(scenarioResult -> {
@ -233,25 +234,29 @@ public class ApiDefinitionExecResultService {
ApiDefinitionExecResult saveResult = new ApiDefinitionExecResult();
saveResult.setId(UUID.randomUUID().toString());
saveResult.setCreateTime(System.currentTimeMillis());
// saveResult.setName(item.getName());
saveResult.setName(getName(type, item.getName(), status, saveResult.getCreateTime(), saveResult.getId()));
saveResult.setName(getName(type, item.getName(), status, saveResult.getCreateTime(),saveResult.getId()));
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(item.getName());
String caseId = null;
if (apiDefinitionWithBLOBs != null) {
saveResult.setName(apiDefinitionWithBLOBs.getName());
apiIdResultMap.put(apiDefinitionWithBLOBs.getId(), item.isSuccess() ? TestPlanApiExecuteStatus.SUCCESS.name() : TestPlanApiExecuteStatus.FAILD.name());
caseId = apiDefinitionWithBLOBs.getId();
} else {
ApiTestCaseWithBLOBs caseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(item.getName());
if (caseWithBLOBs != null) {
caseId = caseWithBLOBs.getId();
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());
caseId = caseWithBLOBs.getId();
}
}
}
if(StringUtils.isNotEmpty(caseId)){
apiIdResultMap.put(caseId, item.isSuccess() ? TestPlanApiExecuteStatus.SUCCESS.name() : TestPlanApiExecuteStatus.FAILD.name());
}
if (StringUtils.equals(type, ApiRunMode.JENKINS_API_PLAN.name())) {
saveResult.setTriggerMode(TriggerMode.API.name());
} else if (StringUtils.equals(type, ApiRunMode.MANUAL_PLAN.name())) {
@ -295,14 +300,14 @@ public class ApiDefinitionExecResultService {
apiDefinitionExecResultMapper.updateByPrimaryKeyWithBLOBs(prevResult);
}
apiDefinitionExecResultMapper.insert(saveResult);
caseReportMap.put(caseId,saveResult);
});
}
});
}
testPlanLog.info("TestPlanReportId[" + testPlanReportId + "] APICASE OVER. API CASE STATUS:" + JSONObject.toJSONString(apiIdResultMap));
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(testPlanReportId, apiIdResultMap, null, null);
// TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
// testPlanReportService.updateExecuteApis(testPlanReportId, apiIdResultMap, null, null);
TestPlanReportExecuteCatch.updateTestPlanExecuteResultInfo(testPlanReportId,caseReportMap,null,null);
}
public void deleteByResourceId(String resourceId) {

View File

@ -735,12 +735,17 @@ public class ApiDefinitionService {
return buildAPIReportResult(result);
}
public APIReportResult getByResultId(String reportId) {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(reportId);
return buildAPIReportResult(result);
}
public APIReportResult getReportById(String testId) {
ApiDefinitionExecResult result = apiDefinitionExecResultMapper.selectByPrimaryKey(testId);
return buildAPIReportResult(result);
}
private APIReportResult buildAPIReportResult(ApiDefinitionExecResult result) {
public APIReportResult buildAPIReportResult(ApiDefinitionExecResult result) {
if (result == null) {
return null;
}

View File

@ -292,6 +292,7 @@ public class ApiScenarioReportService {
List<String> reportIds = new ArrayList<>();
List<String> scenarioIdList = new ArrayList<>();
Map<String, String> scenarioAndErrorMap = new HashMap<>();
Map<String,APIScenarioReportResult> caseReportMap = new HashMap<>();
for (ScenarioResult scenarioResult : scenarioResultList) {
// 存储场景报告
@ -337,6 +338,7 @@ public class ApiScenarioReportService {
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()));
testPlanApiScenario.setPassRate(passRate);
// 报告详情内容
@ -379,6 +381,9 @@ public class ApiScenarioReportService {
}
lastReport = report;
APIScenarioReportResult reportResult = this.get(report.getId());
caseReportMap.put(testPlanApiScenario.getApiScenarioId(),reportResult);
reportIds.add(report.getId());
}
TestPlanReportService testPlanReportService = CommonBeanFactory.getBean(TestPlanReportService.class);
@ -386,8 +391,8 @@ public class ApiScenarioReportService {
testPlanLog.info("TestPlanReportId" + JSONArray.toJSONString(testPlanReportIdList) + " EXECUTE OVER. SCENARIO STATUS : " + JSONObject.toJSONString(scenarioAndErrorMap));
for (String reportId : testPlanReportIdList) {
// testPlanReportService.updateExecuteApis(planId, null, scenarioAndErrorMap, null);
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(reportId, null, scenarioAndErrorMap, null);
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(reportId,null,scenarioAndErrorMap,null);
TestPlanReportExecuteCatch.updateTestPlanExecuteResultInfo(reportId,null,caseReportMap,null);
}
return lastReport;

View File

@ -8,6 +8,7 @@ import io.metersphere.base.domain.TestPlanApiCase;
import io.metersphere.track.dto.PlanReportCaseDTO;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
import java.util.List;
public interface ExtTestPlanApiCaseMapper {
@ -33,5 +34,7 @@ public interface ExtTestPlanApiCaseMapper {
List<PlanReportCaseDTO> selectForPlanReport(String planId);
List<TestPlanFailureApiDTO> getFailureList(@Param("planId") String planId, @Param("status") String status);
List<TestPlanFailureApiDTO> getFailureListByIds(@Param("caseIdList") Collection<String> caseIdList, @Param("planId") String planId, @Param("status") String status);
}

View File

@ -246,7 +246,9 @@
SELECT `status` FROM test_plan_api_case WHERE test_plan_id = #{0}
</select>
<select id="selectForPlanReport" resultType="io.metersphere.track.dto.PlanReportCaseDTO">
select id,status from test_plan_api_case where test_plan_id = #{planId};
select id,status from test_plan_api_case where test_plan_id = #{planId} and api_case_id IN (
SELECT id FROM api_test_case where status is null or status != 'Trash'
)
</select>
<select id="getFailureList" resultType="io.metersphere.api.dto.automation.TestPlanFailureApiDTO">
select
@ -266,4 +268,25 @@
where t.test_plan_id = #{planId};
</select>
<select id="getFailureListByIds" resultType="io.metersphere.api.dto.automation.TestPlanFailureApiDTO">
select
t.id,
c.id as case_id, c.project_id, c.name, c.api_definition_id, c.priority, c.create_user_id,
c.num,t.create_user,
t.status execResult
from
test_plan_api_case t
inner join
api_test_case c
on t.api_case_id = c.id
and t.test_plan_id = #{planId}
<if test="status != null">
and t.status = 'error'
</if>
where c.id IN
<foreach collection="caseIdList" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
</mapper>

View File

@ -5,6 +5,7 @@ import io.metersphere.track.dto.TestPlanLoadCaseDTO;
import io.metersphere.track.request.testplan.LoadCaseRequest;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
import java.util.List;
public interface ExtTestPlanLoadCaseMapper {
@ -25,4 +26,5 @@ public interface ExtTestPlanLoadCaseMapper {
List<PlanReportCaseDTO> selectForPlanReport(String planId);
List<TestPlanLoadCaseDTO> getCases(@Param("planId") String planId, @Param("status") String status);
List<TestPlanLoadCaseDTO> getCasesByIds(@Param("ids") Collection<String> ids, @Param("planId") String planId, @Param("status") String status);
}

View File

@ -188,4 +188,20 @@
</if>
where tplc.test_plan_id = #{planId}
</select>
<select id="getCasesByIds" resultType="io.metersphere.track.dto.TestPlanLoadCaseDTO">
select tplc.id, lt.id as caseId, lt.name, lt.num, lt.project_id,
tplc.status ,tplc.create_user, tplc.load_report_id
from test_plan_load_case tplc
inner join load_test lt on tplc.load_case_id = lt.id
<if test="status != null">
and tplc.status = 'error'
</if>
where tplc.test_plan_id = #{planId}
and lt.id IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
</mapper>

View File

@ -7,6 +7,7 @@ import io.metersphere.base.domain.TestPlanApiScenario;
import io.metersphere.track.dto.PlanReportCaseDTO;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
import java.util.List;
public interface ExtTestPlanScenarioCaseMapper {
@ -30,5 +31,7 @@ public interface ExtTestPlanScenarioCaseMapper {
List<TestPlanFailureScenarioDTO> getFailureList(@Param("planId") String planId, @Param("status") String status);
List<TestPlanFailureScenarioDTO> getFailureListByIds(@Param("ids") Collection<String> ids, @Param("planId") String planId, @Param("status") String status);
List<Integer> getUnderwaySteps(@Param("ids") List<String> underwayIds);
}

View File

@ -196,7 +196,10 @@
where t.test_plan_id = #{planId}
</select>
<select id="selectForPlanReport" resultType="io.metersphere.track.dto.PlanReportCaseDTO">
select id,last_result as status, report_id, api_scenario_id as caseId from test_plan_api_scenario where test_plan_id = #{planId};
select id,last_result as status, report_id, api_scenario_id as caseId from test_plan_api_scenario where test_plan_id = #{planId}
and api_scenario_id IN (
SELECT id FROM api_scenario where status is null or status != 'Trash'
)
</select>
<select id="getFailureList" resultType="io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO">
select
@ -214,6 +217,28 @@
</if>
where t.test_plan_id = #{planId}
</select>
<select id="getFailureListByIds" resultType="io.metersphere.api.dto.automation.TestPlanFailureScenarioDTO">
select
t.id, t.last_result, t.report_id, c.user_id, c.module_path, c.name, c.level,
c.status,c.step_total, c.step_total, c.project_id,
c.num, c.custom_num
from
test_plan_api_scenario t
inner join
api_scenario c
on t.api_scenario_id = c.id and c.status != 'Trash'
and t.test_plan_id = #{planId}
<if test="status != null">
and t.last_result = 'Fail'
</if>
where t.test_plan_id = #{planId}
and c.id IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
<select id="getUnderwaySteps" resultType="java.lang.Integer">
select step_total from api_scenario c
where c.id in

View File

@ -58,6 +58,8 @@ public class TestPlanUtils {
if (StringUtils.equals(successStatus, status)) {
report.setPassCount(report.getPassCount() + 1);
}
}else {
System.out.println(status);
}
TestPlanUtils.getStatusResultMap(statusResultMap, status);
});

View File

@ -559,6 +559,14 @@ public class TestPlanApiCaseService {
return buildCases(apiTestCases);
}
public List<TestPlanFailureApiDTO> getAllCases(Collection<String> caseIdList,String planId,String status) {
if(caseIdList.isEmpty()){
return new ArrayList<>();
}
List<TestPlanFailureApiDTO> apiTestCases = extTestPlanApiCaseMapper.getFailureListByIds(caseIdList,planId, status);
return buildCases(apiTestCases);
}
public List<TestPlanFailureApiDTO> buildCases(List<TestPlanFailureApiDTO> apiTestCases) {
if (CollectionUtils.isEmpty(apiTestCases)) {
return apiTestCases;

View File

@ -369,6 +369,11 @@ public class TestPlanLoadCaseService {
return buildCases(cases);
}
public List<TestPlanLoadCaseDTO> getAllCases(Collection<String> ids,String planId,String status) {
List<TestPlanLoadCaseDTO> cases = extTestPlanLoadCaseMapper.getCasesByIds(ids,planId, status);
return buildCases(cases);
}
public List<TestPlanLoadCaseDTO> getFailureCases(String planId) {
List<TestPlanLoadCaseDTO> failureCases = extTestPlanLoadCaseMapper.getCases(planId, "error");
return buildCases(failureCases);

View File

@ -507,9 +507,9 @@ public class TestPlanReportService {
return returnDTO;
}
public TestPlanReport updateReport(TestPlanReportDataWithBLOBs testPlanReportData,boolean updateTime,TestPlanExecuteInfo executeInfo) {
TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(testPlanReportData.getTestPlanReportId());
if (testPlanReport == null) {
public TestPlanReport updateReport(TestPlanReport testPlanReport,TestPlanReportContentWithBLOBs reportContent,boolean updateTime,TestPlanExecuteInfo executeInfo) {
if (testPlanReport == null || executeInfo == null) {
return null;
}
@ -522,7 +522,7 @@ public class TestPlanReportService {
boolean scenarioIsOk = executeInfo.isScenarioAllExecuted();
boolean performanceIsOk = executeInfo.isLoadCaseAllExecuted();
testPlanLog.info("ReportId[" + testPlanReportData.getTestPlanReportId() + "] count over. Testplan Execute Result: Api is over ->" + apiCaseIsOk + "; scenario is over ->" + scenarioIsOk + "; performance is over ->" + performanceIsOk);
testPlanLog.info("ReportId[" + testPlanReport.getId() + "] count over. Testplan Execute Result: Api is over ->" + apiCaseIsOk + "; scenario is over ->" + scenarioIsOk + "; performance is over ->" + performanceIsOk);
if (apiCaseIsOk) {
@ -536,7 +536,7 @@ public class TestPlanReportService {
}
if(apiCaseIsOk && scenarioIsOk && performanceIsOk){
TestPlanReportExecuteCatch.remove(testPlanReportData.getTestPlanReportId());
TestPlanReportExecuteCatch.remove(testPlanReport.getId());
}
int[] componentIndexArr = new int[]{1, 3, 4};
@ -547,7 +547,6 @@ public class TestPlanReportService {
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);
@ -556,20 +555,14 @@ public class TestPlanReportService {
testPlanService.buildLoadCaseReport(testPlanReport.getTestPlanId(), components);
Map<String, Map<String, String>> testPlanExecuteResult = executeInfo.getExecutedResult();
testPlanLog.info("ReportId[" + testPlanReport.getId() + "] COUNT OVER. COUNT RESULT :" + JSONObject.toJSONString(testPlanExecuteResult));
testPlanLog.info("ReportId[" + testPlanReportData.getTestPlanReportId() + "] COUNT OVER. COUNT RESULT :" + JSONObject.toJSONString(testPlanExecuteResult));
TestPlanSimpleReportDTO reportDTO = testPlanService.buildPlanReport(executeInfo, testPlanReport.getTestPlanId(),false);
testPlanReportContentMapper.updateByPrimaryKeySelective(parseReportDaoToReportContent(reportDTO, reportContent));
TestCaseReportMetricDTO testCaseReportMetricDTO = this.countReportData(testPlan, testPlanExecuteResult);
//统计执行的场景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);
String testPlanStatus = this.getTestPlanReportStatus(testPlanReport, reportDTO);
testPlanReport.setStatus(testPlanStatus);
testPlanReport = this.update(testPlanReport);
return testPlanReport;
}
@ -596,46 +589,10 @@ public class TestPlanReportService {
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
queryTestPlanRequest.setId(testPlanReport.getTestPlanId());
TestPlanDTO testPlan = extTestPlanMapper.list(queryTestPlanRequest).get(0);
// String issuesInfo = null;
//因为接口案例的定时任务是单个案例开线程运行 所以要检查是否都执行完成全部执行完成时才会进行统一整理
if (StringUtils.equalsAny(triggerMode, ReportTriggerMode.SCHEDULE.name(), ReportTriggerMode.API.name())
&& StringUtils.equalsAny(resourceRunMode, ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
List<String> statusList = extTestPlanApiCaseMapper.getStatusByTestPlanId(testPlan.getId());
for (String status : statusList) {
if (status == null) {
return;
}
}
} else if (StringUtils.equals(ReportTriggerMode.TEST_PLAN_SCHEDULE.name(), triggerMode)) {
}
testPlanReport.setEndTime(System.currentTimeMillis());
testPlanReport.setUpdateTime(System.currentTimeMillis());
// //手动触发的需要保存手工执行的信息
// int[] componentIndexArr = null;
// if (StringUtils.equals(ReportTriggerMode.MANUAL.name(), triggerMode)) {
// componentIndexArr = new int[]{1, 2, 3, 4, 5};
// } else {
// componentIndexArr = new int[]{1, 3, 4};
// }
// testPlanReport.setComponents(JSONArray.toJSONString(componentIndexArr));
// 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);
// if (StringUtils.equals(ReportTriggerMode.MANUAL.name(), triggerMode)) {
// List<IssuesDao> issues = testPlanService.buildFunctionalCaseReport(testPlanReport.getTestPlanId(), components);
// issuesInfo = JSONArray.toJSONString(issues);
// }
//只针对定时任务做处理
if (StringUtils.equalsAny(triggerMode, ReportTriggerMode.SCHEDULE.name(), ReportTriggerMode.API.name())
&& StringUtils.equalsAny(resourceRunMode, ApiRunMode.SCHEDULE_API_PLAN.name(), ApiRunMode.JENKINS_API_PLAN.name())) {
@ -651,22 +608,6 @@ public class TestPlanReportService {
testPlanReport.setIsScenarioExecuting(false);
testPlanReport.setIsApiCaseExecuting(false);
}
// TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
// components.forEach(component -> {
// component.afterBuild(testCaseReportMetricDTO);
// });
// if (StringUtils.equalsAny(triggerMode, ReportTriggerMode.SCHEDULE.name(), ReportTriggerMode.API.name())
// && StringUtils.equalsAny(resourceRunMode, ApiRunMode.SCHEDULE_PERFORMANCE_TEST.name(), ApiRunMode.JENKINS_PERFORMANCE_TEST.name())) {
//如果是性能测试作为触发由于延迟原因可能会出现报告已经结束但是状态还是进行中的状态
// List<TestCaseReportStatusResultDTO> loadResult = testCaseReportMetricDTO.getExecuteResult().getLoadResult();
// for (TestCaseReportStatusResultDTO dto : loadResult) {
// if (StringUtils.equals(dto.getStatus(), TestPlanTestCaseStatus.Underway.name())) {
// dto.setStatus(TestPlanTestCaseStatus.Pass.name());
// }
// }
// testCaseReportMetricDTO.getExecuteResult().setLoadResult(loadResult);
// }
TestPlanReportContentExample example = new TestPlanReportContentExample();
example.createCriteria().andTestPlanReportIdEqualTo(planReportId);
@ -677,46 +618,6 @@ public class TestPlanReportService {
TestPlanSimpleReportDTO reportDTO = testPlanService.buildPlanReport(testPlan.getId(), false);
if (!testPlanReportContentList.isEmpty()) {
testPlanReportContent = testPlanReportContentList.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);
// List<String> executeScenarioList = new ArrayList<>();
// if (savedDTO != null) {
// if (savedDTO.getExecutedScenarioIds() != null) {
// executeScenarioList = savedDTO.getExecutedScenarioIds();
// }
// }
// for (String scenarioId : scenarioIdList) {
// if (!executeScenarioList.contains(scenarioId)) {
// executeScenarioList.add(scenarioId);
// }
// }
// if (testCaseReportMetricDTO.getExecuteResult() == null) {
// TestCaseReportAdvanceStatusResultDTO executeResultDTO = new TestCaseReportAdvanceStatusResultDTO();
// testCaseReportMetricDTO.setExecuteResult(executeResultDTO);
// }
// testCaseReportMetricDTO.getExecuteResult().setExecutedScenarioIds(executeScenarioList);
//
// if (!CollectionUtils.isEqualCollection(scenarioListArr, executeScenarioList)) {
// testPlanReport.setIsScenarioExecuting(true);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//统计执行的场景ID
// testPlanReportData.setExecuteResult(JSONObject.toJSONString(testCaseReportMetricDTO.getExecuteResult()));
// testPlanReportData.setFailurTestCases(JSONObject.toJSONString(testCaseReportMetricDTO.getFailureTestCases()));
// testPlanReportData.setModuleExecuteResult(JSONArray.toJSONString(testCaseReportMetricDTO.getModuleExecuteResult()));
// if (issuesInfo != null) {
// testPlanReportData.setIssuesInfo(issuesInfo);
// }
testPlanReportContentMapper.updateByPrimaryKeySelective(parseReportDaoToReportContent(reportDTO, testPlanReportContent));
}
@ -942,6 +843,7 @@ public class TestPlanReportService {
* 同时如果执行过程中报告删除那么此时也应当记为失败
*/
Map<String, String> finishLoadTestId = new HashMap<>();
Map<String,String> caseReportMap = new HashMap<>();
executorService.submit(() -> {
//错误数据检查集合 如果错误数据出现超过20次则取消该条数据的检查
Map<String, Integer> errorDataCheckMap = new HashMap<>();
@ -960,6 +862,7 @@ public class TestPlanReportService {
performaneReportIDList.remove(loadTestReportId);
if (performaneReportIDMap.containsKey(loadTestReportId)) {
finishLoadTestId.put(performaneReportIDMap.get(loadTestReportId), TestPlanApiExecuteStatus.FAILD.name());
caseReportMap.put(performaneReportIDMap.get(loadTestReportId), loadTestReportId);
}
} else {
errorDataCheckMap.put(loadTestReportId, errorDataCheckMap.get(loadTestReportId) + 1);
@ -972,12 +875,14 @@ public class TestPlanReportService {
if (StringUtils.equalsAny(loadTestReportFromDatabase.getStatus(),
PerformanceTestStatus.Completed.name(), PerformanceTestStatus.Error.name())) {
finishLoadTestId.put(loadTestReportFromDatabase.getTestId(), TestPlanApiExecuteStatus.SUCCESS.name());
caseReportMap.put(loadTestReportFromDatabase.getTestId(), loadTestReportId);
performaneReportIDList.remove(loadTestReportId);
}
}
} catch (Exception e) {
performaneReportIDList.remove(loadTestReportId);
finishLoadTestId.put(performaneReportIDMap.get(loadTestReportId), TestPlanApiExecuteStatus.FAILD.name());
caseReportMap.put(performaneReportIDMap.get(loadTestReportId), loadTestReportId);
testPlanLog.error(e.getMessage());
}
}
@ -993,8 +898,8 @@ public class TestPlanReportService {
this.updatePerformanceTestStatus(eventDTO);
}
}
// this.updateExecuteApis(testPlanReport.getId(), null, null, finishLoadTestId);
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(testPlanReport.getId(),null,null,finishLoadTestId);
TestPlanReportExecuteCatch.updateTestPlanExecuteResultInfo(testPlanReport.getId(),null,null,caseReportMap);
} else {
try {
//查询定时任务是否关闭
@ -1102,14 +1007,17 @@ public class TestPlanReportService {
boolean updateTime = MapUtils.isNotEmpty(executeApiCaseIdMap) || MapUtils.isNotEmpty(executeScenarioCaseIdMap) || MapUtils.isNotEmpty(executePerformanceIdMap);
testPlanLog.info("ReportId[" + planReportId + "] Executed. api :" + JSONObject.toJSONString(executeApiCaseIdMap) + "; scenario:" + JSONObject.toJSONString(executeScenarioCaseIdMap) + "; performance:" + JSONObject.toJSONString(executePerformanceIdMap));
TestPlanReportDataExample example = new TestPlanReportDataExample();
TestPlanReportContentExample example = new TestPlanReportContentExample();
example.createCriteria().andTestPlanReportIdEqualTo(planReportId);
List<TestPlanReportDataWithBLOBs> reportDataList = testPlanReportDataMapper.selectByExampleWithBLOBs(example);
List<TestPlanReportContentWithBLOBs> reportDataList = testPlanReportContentMapper.selectByExampleWithBLOBs(example);
TestPlanReport report = null;
if (!reportDataList.isEmpty()) {
TestPlanReportExecuteCatch.setReportDataCheckResult(planReportId,true);
TestPlanReportDataWithBLOBs reportData = reportDataList.get(0);
report = this.updateReport(reportData,updateTime,executeInfo);
TestPlanReportContentWithBLOBs reportData = reportDataList.get(0);
report = testPlanReportMapper.selectByPrimaryKey(planReportId);
report = this.updateReport(report,reportData,updateTime,executeInfo);
} else {
TestPlanReportExecuteCatch.setReportDataCheckResult(planReportId,false);
}

View File

@ -438,6 +438,12 @@ public class TestPlanScenarioCaseService {
return buildCases(apiTestCases);
}
public List<TestPlanFailureScenarioDTO> getAllCases(Collection<String> ids,String planId,String status) {
List<TestPlanFailureScenarioDTO> apiTestCases =
extTestPlanScenarioCaseMapper.getFailureListByIds(ids,planId, status);
return buildCases(apiTestCases);
}
public List<TestPlanFailureScenarioDTO> getFailureCases(String planId) {
List<TestPlanFailureScenarioDTO> apiTestCases =
extTestPlanScenarioCaseMapper.getFailureList(planId, "Fail");

View File

@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.cache.TestPlanExecuteInfo;
import io.metersphere.api.cache.TestPlanReportExecuteCatch;
import io.metersphere.api.dto.APIReportResult;
import io.metersphere.api.dto.automation.*;
@ -1042,6 +1043,8 @@ public class TestPlanService {
}
if (StringUtils.isNotEmpty(reportId)) {
executePerformanceIdMap.put(caseID, TestPlanApiExecuteStatus.RUNNING.name());
}else {
executePerformanceIdMap.put(caseID, TestPlanApiExecuteStatus.PREPARE.name());
}
}
if (!performaneReportIDMap.isEmpty()) {
@ -1058,7 +1061,6 @@ public class TestPlanService {
executeScenarioCaseIdMap.put(id, TestPlanApiExecuteStatus.RUNNING.name());
}
testPlanLog.info("ReportId[" + planReportId + "] start run. TestPlanID:[" + testPlanID + "]. Execute api :" + JSONObject.toJSONString(executeApiCaseIdMap) + "; Execute scenario:" + JSONObject.toJSONString(executeScenarioCaseIdMap) + "; Execute performance:" + JSONObject.toJSONString(executePerformanceIdMap));
// testPlanReportService.updateExecuteApis(planReportId, executeApiCaseIdMap, executeScenarioCaseIdMap, executePerformanceIdMap);
TestPlanReportExecuteCatch.updateApiTestPlanExecuteInfo(planReportId, executeApiCaseIdMap, executeScenarioCaseIdMap, executePerformanceIdMap);
//执行接口案例任务
@ -1497,6 +1499,146 @@ public class TestPlanService {
}
}
public void buildApiReport(TestPlanSimpleReportDTO report, JSONObject config, TestPlanExecuteInfo executeInfo, String planId,boolean saveResponse) {
if(MapUtils.isEmpty(executeInfo.getApiCaseExecInfo()) && MapUtils.isEmpty(executeInfo.getApiScenarioCaseExecInfo())){
return;
}
if (checkReportConfig(config, "api")) {
List<TestPlanFailureApiDTO> apiAllCases = null;
List<TestPlanFailureScenarioDTO> scenarioAllCases = null;
if (checkReportConfig(config, "api", "all")) {
if(MapUtils.isNotEmpty(executeInfo.getApiCaseExecInfo())){
// 接口
apiAllCases = testPlanApiCaseService.getAllCases(executeInfo.getApiCaseExecInfo().keySet(),planId,null);
if (saveResponse) {
apiAllCases.forEach(item -> {
ApiDefinitionExecResult result = executeInfo.getApiCaseExecuteReportMap().get(item.getId());
if(result != null){
APIReportResult dbResult = apiDefinitionService.buildAPIReportResult(result);
if (dbResult != null && StringUtils.isNotBlank(dbResult.getContent())) {
item.setResponse(dbResult.getContent());
}
}
});
}
report.setApiAllCases(apiAllCases);
}
if(MapUtils.isNotEmpty(executeInfo.getApiScenarioCaseExecInfo())){
//场景
scenarioAllCases = testPlanScenarioCaseService.getAllCases(executeInfo.getApiScenarioCaseExecInfo().keySet(),planId,null);
if (saveResponse) {
scenarioAllCases.forEach((item) -> {
APIScenarioReportResult result = executeInfo.getApiScenarioReportReportMap().get(item.getId());
if(result != null){
item.setResponse(result);
}
});
}
report.setScenarioAllCases(scenarioAllCases);
}
}
if (checkReportConfig(config, "api", "failure")) {
// 接口
List<TestPlanFailureApiDTO> apiFailureCases = null;
if (!CollectionUtils.isEmpty(apiAllCases)) {
apiFailureCases = apiAllCases.stream()
.filter(i -> StringUtils.isNotBlank(i.getExecResult())
&& i.getExecResult().equals("error"))
.collect(Collectors.toList());
}
if (saveResponse) {
apiFailureCases.forEach(item -> {
APIReportResult dbResult = apiDefinitionService.getDbResult(item.getId());
if (dbResult != null && StringUtils.isNotBlank(dbResult.getContent())) {
item.setResponse(dbResult.getContent());
}
});
}
report.setApiFailureCases(apiFailureCases);
// 场景
List<TestPlanFailureScenarioDTO> scenarioFailureCases = null;
if (!CollectionUtils.isEmpty(scenarioAllCases)) {
scenarioFailureCases = scenarioAllCases.stream()
.filter(i -> StringUtils.isNotBlank(i.getLastResult())
&& i.getLastResult().equals("Fail"))
.collect(Collectors.toList());
}
if (saveResponse) {
scenarioFailureCases.forEach((item) -> {
item.setResponse(apiScenarioReportService.get(item.getReportId()));
});
}
report.setScenarioFailureCases(scenarioFailureCases);
}
}
}
public void buildLoadReport(TestPlanSimpleReportDTO report, JSONObject config, TestPlanExecuteInfo executeInfo, String planId, boolean saveResponse) {
if(MapUtils.isEmpty(executeInfo.getLoadCaseExecInfo())){
return;
}
if (checkReportConfig(config, "load")) {
List<TestPlanLoadCaseDTO> allCases = null;
if (checkReportConfig(config, "load", "all")) {
allCases = testPlanLoadCaseService.getAllCases(executeInfo.getLoadCaseExecInfo().keySet(),planId,null);
if (saveResponse) {
allCases.forEach(item -> {
String reportId = executeInfo.getLoadCaseReportIdMap().get(item.getId());
if(StringUtils.isNotEmpty(reportId)){
LoadCaseReportRequest request = new LoadCaseReportRequest();
request.setTestPlanLoadCaseId(item.getId());
request.setReportId(reportId);
Boolean existReport = testPlanLoadCaseService.isExistReport(request);
if (existReport) {
LoadTestReportWithBLOBs loadTestReport = performanceReportService.getLoadTestReport(reportId);
ReportTimeInfo reportTimeInfo = performanceReportService.getReportTimeInfo(reportId);
TestPlanLoadCaseDTO.ReportDTO reportDTO = new TestPlanLoadCaseDTO.ReportDTO();
if (loadTestReport != null) {
BeanUtils.copyBean(reportDTO, loadTestReport);
}
if (reportTimeInfo != null) {
BeanUtils.copyBean(reportDTO, reportTimeInfo);
}
item.setResponse(reportDTO);
// todo 报告详情
}
}
});
}
report.setLoadAllCases(allCases);
}
if (checkReportConfig(config, "load", "failure")) {
List<TestPlanLoadCaseDTO> failureCases = null;
if (!CollectionUtils.isEmpty(allCases)) {
failureCases = allCases.stream()
.filter(i -> StringUtils.isNotBlank(i.getStatus())
&& i.getStatus().equals("error"))
.collect(Collectors.toList());
}
report.setLoadFailureCases(failureCases);
}
}
}
public TestPlanSimpleReportDTO buildPlanReport(TestPlanExecuteInfo executeInfo,String planId, boolean saveResponse) {
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(planId);
if(testPlan != null){
String reportConfig = testPlan.getReportConfig();
JSONObject config = null;
if (StringUtils.isNotBlank(reportConfig)) {
config = JSONObject.parseObject(reportConfig);
}
TestPlanSimpleReportDTO report = getReport(planId);
buildApiReport(report, config, executeInfo, planId, saveResponse);
buildLoadReport(report, config, executeInfo, planId, saveResponse);
return report;
}else {
return null;
}
}
public TestPlanSimpleReportDTO buildPlanReport(String planId, boolean saveResponse) {
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(planId);
@ -1589,8 +1731,17 @@ public class TestPlanService {
testPlanApiCaseService.calculatePlanReport(planId, report);
testPlanScenarioCaseService.calculatePlanReport(planId, report);
testPlanLoadCaseService.calculatePlanReport(planId, report);
report.setExecuteRate(report.getExecuteCount() * 0.1 / report.getCaseCount());
report.setPassRate(report.getPassCount() * 0.1 / report.getCaseCount());
if(report.getExecuteCount() != 0 && report.getCaseCount() != null){
report.setExecuteRate(report.getExecuteCount() * 0.1 / report.getCaseCount());
}else {
report.setExecuteRate(0.0);
}
if(report.getPassCount() != 0 && report.getCaseCount() != null){
report.setPassRate(report.getPassCount() * 0.1 / report.getCaseCount());
}else {
report.setPassRate(0.0);
}
report.setName(testPlan.getName());
if (template == null || template.getPlatform().equals("metersphere")) {
report.setIsThirdPartIssue(false);

View File

@ -5,11 +5,13 @@
<ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" @createRootModelInTree="createRootModelInTree"
:request="request" :response="response" :project-id="projectId"
@mockConfig="mockConfig"
@changeTab="changeTab"
:basisData="currentApi" :moduleOptions="moduleOptions" :syncTabs="syncTabs"
v-if="currentProtocol === 'HTTP'" ref="httpApi"/>
<!-- TCP -->
<ms-edit-complete-tcp-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree"
@saveApi="saveApi" :basisData="currentApi"
@changeTab="changeTab"
:moduleOptions="moduleOptions" :syncTabs="syncTabs" v-if="currentProtocol === 'TCP'"
ref="tcpApi"/>
<!--DUBBO-->
@ -77,6 +79,9 @@
this.addListener();
},
methods: {
changeTab(type){
this.$emit("changeTab",type);
},
addListener() {
document.addEventListener("keydown", this.createCtrlSHandle);
// document.addEventListener("keydown", (even => handleCtrlSEvent(even, this.$refs.httpApi.saveApi)));

View File

@ -30,6 +30,7 @@
:moduleOptions="moduleOptions"
@runTest="runTest"
@saveApi="saveApi"
@changeTab="changeTab"
@createRootModel="createRootModel"
/>
</div>

View File

@ -252,6 +252,7 @@
mockSetting() {
if(this.basisData.id){
this.$store.state.currentApiCase={mock : getUUID()};
this.$emit('changeTab','mock');
}else {
this.$alert(this.$t('api_test.mock.create_error'));
}

View File

@ -219,7 +219,7 @@ export default {
},
mockSetting() {
if(this.basisData.id){
this.$store.state.currentApiCase={mock : getUUID()};
this.$emit('changeTab','mock');
}else {
this.$alert(this.$t('api_test.mock.create_error'));
}