From 51a331c757c463b04bc34f2a6b90b71e6998119c Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Thu, 6 May 2021 17:35:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96=20):=20=E6=8A=A5=E5=91=8A=E4=BC=98=E5=8C=96-=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=9C=BA=E6=99=AF=E6=AD=A5=E9=AA=A4=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/definition/request/MsTestElement.java | 24 +- .../request/processors/MsJSR223Processor.java | 8 +- .../request/sampler/MsDubboSampler.java | 8 +- .../request/sampler/MsHTTPSamplerProxy.java | 13 +- .../request/sampler/MsJDBCSampler.java | 8 +- .../request/sampler/MsTCPSampler.java | 8 +- .../api/jmeter/APIBackendListenerClient.java | 1 + .../metersphere/api/jmeter/JMeterService.java | 3 +- .../metersphere/api/jmeter/RequestResult.java | 2 + .../io/metersphere/api/jmeter/TestResult.java | 36 +- .../api/service/ApiAutomationService.java | 12 +- .../ApiDefinitionExecResultService.java | 10 +- .../api/service/ApiDefinitionService.java | 4 +- .../api/service/ApiScenarioReportService.java | 3 + .../service/task/SerialScenarioExecTask.java | 5 + .../commons/constants/DelimiterConstants.java | 15 + .../commons/constants/RunModeConstants.java | 17 + .../service/TestPlanLoadCaseService.java | 3 +- .../apache/jmeter/samplers/SampleResult.java | 15 +- .../report/components/MetricChart.vue | 379 ++++++++++-------- .../automation/scenario/EditApiScenario.vue | 2 +- 21 files changed, 368 insertions(+), 208 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/commons/constants/DelimiterConstants.java create mode 100644 backend/src/main/java/io/metersphere/commons/constants/RunModeConstants.java diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java index c1fd881aad..4b8c83b4ae 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java @@ -26,6 +26,7 @@ import io.metersphere.api.dto.scenario.KeyValue; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.service.ApiTestEnvironmentService; import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs; +import io.metersphere.commons.constants.DelimiterConstants; import io.metersphere.commons.constants.LoopConstants; import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.exception.MSException; @@ -206,7 +207,7 @@ public abstract class MsTestElement { } csvDataSet.setIgnoreFirstLine(false); // csvDataSet.setProperty("quotedData",true); - csvDataSet.setProperty("shareMode","shareMode.group"); + csvDataSet.setProperty("shareMode", "shareMode.group"); csvDataSet.setProperty("recycle", true); csvDataSet.setProperty("delimiter", item.getDelimiter()); csvDataSet.setComment(StringUtils.isEmpty(item.getDescription()) ? "" : item.getDescription()); @@ -259,12 +260,22 @@ public abstract class MsTestElement { } } - public void getFullPath(MsTestElement element, StringBuilder path) { + public String getFullPath(MsTestElement element, String path) { + if (element.getParent() == null) { + return path; + } + path = StringUtils.isEmpty(element.getName()) ? element.getType() : element.getName() + DelimiterConstants.STEP_DELIMITER.toString() + path; + return getFullPath(element.getParent(), path); + } + + public void getScenarioSet(MsTestElement element, List id_names) { + if (StringUtils.equals(element.getType(), "scenario")) { + id_names.add(element.getResourceId() + "_" + element.getName()); + } if (element.getParent() == null) { return; } - path.append(StringUtils.isEmpty(element.getName()) ? element.getType() : element.getName()).append("^@~@^"); - getFullPath(element.getParent(), path); + getScenarioSet(element.getParent(), id_names); } protected String getParentName(MsTestElement parent) { @@ -282,9 +293,8 @@ public abstract class MsTestElement { } } // 获取全路径以备后面使用 - StringBuilder fullPath = new StringBuilder(); - getFullPath(parent, fullPath); - return fullPath + "<->" + parent.getName(); + String fullPath = getFullPath(parent, new String()); + return fullPath + DelimiterConstants.SEPARATOR.toString() + parent.getName(); } return ""; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java index f3665a7d09..c05bedc7b9 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/processors/MsJSR223Processor.java @@ -1,9 +1,11 @@ package io.metersphere.api.dto.definition.request.processors; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import io.metersphere.api.dto.definition.request.MsTestElement; import io.metersphere.api.dto.definition.request.ParameterConfig; +import io.metersphere.commons.constants.DelimiterConstants; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; @@ -13,6 +15,7 @@ import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; import org.apache.jorphan.collections.HashTree; +import java.util.LinkedList; import java.util.List; @Data @@ -42,9 +45,12 @@ public class MsJSR223Processor extends MsTestElement { } String name = this.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { - processor.setName(this.getName() + "<->" + name); + processor.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } processor.setProperty("MS-ID", this.getId()); + List id_names = new LinkedList<>(); + this.getScenarioSet(this, id_names); + processor.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); processor.setProperty(TestElement.TEST_CLASS, JSR223Sampler.class.getName()); processor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java index 8c04584a10..578bf39854 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsDubboSampler.java @@ -1,5 +1,6 @@ package io.metersphere.api.dto.definition.request.sampler; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.annotation.JsonProperty; @@ -19,6 +20,7 @@ import io.metersphere.api.service.ApiDefinitionService; import io.metersphere.api.service.ApiTestCaseService; import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ApiTestCaseWithBLOBs; +import io.metersphere.commons.constants.DelimiterConstants; import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; @@ -31,6 +33,7 @@ import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; import org.apache.jorphan.collections.HashTree; +import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; @@ -133,11 +136,14 @@ public class MsDubboSampler extends MsTestElement { sampler.setName(this.getName()); String name = this.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { - sampler.setName(this.getName() + "<->" + name); + sampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } sampler.setProperty(TestElement.TEST_CLASS, DubboSample.class.getName()); sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("DubboSampleGui")); sampler.setProperty("MS-ID", this.getId()); + List id_names = new LinkedList<>(); + this.getScenarioSet(this, id_names); + sampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); sampler.addTestElement(configCenter(this.getConfigCenter())); sampler.addTestElement(registryCenter(this.getRegistryCenter())); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java index eeedc79765..6bede2597f 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java @@ -1,5 +1,6 @@ package io.metersphere.api.dto.definition.request.sampler; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.core.type.TypeReference; @@ -20,6 +21,7 @@ import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ApiTestCaseWithBLOBs; import io.metersphere.base.domain.TestPlanApiCase; import io.metersphere.commons.constants.ConditionType; +import io.metersphere.commons.constants.DelimiterConstants; import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; @@ -42,10 +44,7 @@ import org.apache.jorphan.collections.HashTree; import java.net.URL; import java.net.URLDecoder; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -163,11 +162,15 @@ public class MsHTTPSamplerProxy extends MsTestElement { } String name = this.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { - sampler.setName(this.getName() + "<->" + name); + sampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName()); sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("HttpTestSampleGui")); sampler.setProperty("MS-ID", this.getId()); + List id_names = new LinkedList<>(); + this.getScenarioSet(this, id_names); + sampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); + sampler.setMethod(this.getMethod()); sampler.setContentEncoding("UTF-8"); sampler.setConnectTimeout(this.getConnectTimeout() == null ? "6000" : this.getConnectTimeout()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java index d7a42a6cdf..f76a9c9c7f 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java @@ -1,5 +1,6 @@ package io.metersphere.api.dto.definition.request.sampler; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; @@ -17,6 +18,7 @@ import io.metersphere.api.service.ApiTestEnvironmentService; import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ApiTestCaseWithBLOBs; import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs; +import io.metersphere.commons.constants.DelimiterConstants; import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.CommonBeanFactory; @@ -33,6 +35,7 @@ import org.apache.jmeter.testelement.TestElement; import org.apache.jorphan.collections.HashTree; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; @@ -231,11 +234,14 @@ public class MsJDBCSampler extends MsTestElement { sampler.setName(this.getName()); String name = this.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { - sampler.setName(this.getName() + "<->" + name); + sampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } sampler.setProperty(TestElement.TEST_CLASS, JDBCSampler.class.getName()); sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); sampler.setProperty("MS-ID", this.getId()); + List id_names = new LinkedList<>(); + this.getScenarioSet(this, id_names); + sampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); // request.getDataSource() 是ID,需要转换为Name sampler.setProperty("dataSource", this.dataSource.getName()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java index 36bc12d123..a3629274b9 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java @@ -1,5 +1,6 @@ package io.metersphere.api.dto.definition.request.sampler; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; import com.fasterxml.jackson.core.type.TypeReference; @@ -15,6 +16,7 @@ import io.metersphere.api.service.ApiDefinitionService; import io.metersphere.api.service.ApiTestCaseService; import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ApiTestCaseWithBLOBs; +import io.metersphere.commons.constants.DelimiterConstants; import io.metersphere.commons.constants.MsTestElementConstants; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.LogUtil; @@ -34,6 +36,7 @@ import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.ListedHashTree; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.Random; @@ -174,9 +177,12 @@ public class MsTCPSampler extends MsTestElement { tcpSampler.setName(this.getName()); String name = this.getParentName(this.getParent()); if (StringUtils.isNotEmpty(name) && !config.isOperating()) { - tcpSampler.setName(this.getName() + "<->" + name); + tcpSampler.setName(this.getName() + DelimiterConstants.SEPARATOR.toString() + name); } tcpSampler.setProperty("MS-ID", this.getId()); + List id_names = new LinkedList<>(); + this.getScenarioSet(this, id_names); + tcpSampler.setProperty("MS-SCENARIO", JSON.toJSONString(id_names)); tcpSampler.setProperty(TestElement.TEST_CLASS, TCPSampler.class.getName()); tcpSampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TCPSamplerGui")); diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index 3e6ed774d7..5664d8c40b 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -420,6 +420,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl requestResult.setTotalAssertions(result.getAssertionResults().length); requestResult.setSuccess(result.isSuccessful()); requestResult.setError(result.getErrorCount()); + requestResult.setScenario(result.getScenario()); if (result instanceof HTTPSampleResult) { HTTPSampleResult res = (HTTPSampleResult) result; requestResult.setCookies(res.getCookies()); diff --git a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java index 25792ad886..b383e97724 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/JMeterService.java @@ -8,6 +8,7 @@ import io.metersphere.api.dto.scenario.request.BodyFile; import io.metersphere.base.domain.JarConfig; import io.metersphere.base.domain.TestResource; import io.metersphere.commons.constants.ApiRunMode; +import io.metersphere.commons.constants.RunModeConstants; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.*; import io.metersphere.config.JmeterProperties; @@ -122,7 +123,7 @@ public class JMeterService { BackendListener backendListener = new BackendListener(); backendListener.setName(testId); Arguments arguments = new Arguments(); - if (config != null && config.getMode().equals("serial") && config.getReportType().equals("setReport")) { + if (config != null && config.getMode().equals(RunModeConstants.SERIAL.toString()) && config.getReportType().equals(RunModeConstants.SET_REPORT.toString())) { arguments.addArgument(APIBackendListenerClient.TEST_REPORT_ID, config.getReportId()); } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java b/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java index 74ae9c12d4..e2b82595dd 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/RequestResult.java @@ -16,6 +16,8 @@ public class RequestResult { private String method; + private String scenario; + private long requestSize; private long startTime; diff --git a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java index 400001dc55..8cdf2d8221 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java @@ -1,11 +1,15 @@ package io.metersphere.api.jmeter; +import com.alibaba.fastjson.JSON; +import io.metersphere.commons.constants.DelimiterConstants; import lombok.Data; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Data public class TestResult { @@ -14,6 +18,12 @@ public class TestResult { private String setReportId; + private int scenarioTotal; + + private int scenarioSuccess; + + private int scenarioError; + private String userId; private boolean isDebug; @@ -32,6 +42,8 @@ public class TestResult { private List scenarios = new ArrayList<>(); + private Map margeScenariMap = new HashMap<>(); + public void addError(int count) { this.error += count; } @@ -48,11 +60,25 @@ public class TestResult { this.passAssertions += count; } - private static final String SEPARATOR = "<->"; + private static final String SEPARATOR = DelimiterConstants.SEPARATOR.toString(); + + private void setStatus(List id_names, boolean status) { + if (CollectionUtils.isNotEmpty(id_names)) { + id_names.forEach(item -> { + if (!margeScenariMap.containsKey(item) || status) { + margeScenariMap.put(item, status); + } + }); + } + } public void addScenario(ScenarioResult result) { if (result != null && CollectionUtils.isNotEmpty(result.getRequestResults())) { result.getRequestResults().forEach(item -> { + if (StringUtils.isNotEmpty(item.getScenario())) { + List id_names = JSON.parseObject(item.getScenario(), List.class); + this.setStatus(id_names, item.getError() > 0); + } if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf(SEPARATOR) != -1) { String array[] = item.getName().split(SEPARATOR); item.setName(array[1] + array[0]); @@ -63,5 +89,13 @@ public class TestResult { }); scenarios.add(result); } + for (String key : margeScenariMap.keySet()) { + if (margeScenariMap.get(key)) { + this.scenarioError++; + } else { + this.scenarioSuccess++; + } + } + this.setScenarioTotal(this.margeScenariMap.size()); } } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index b41d3d9ca9..71523d95c5 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -597,7 +597,7 @@ public class ApiAutomationService { } report.setUpdateTime(System.currentTimeMillis()); report.setCreateTime(System.currentTimeMillis()); - if (config != null && config.getMode().equals("serial")) { + if (config != null && config.getMode().equals(RunModeConstants.SERIAL.toString())) { report.setCreateTime(System.currentTimeMillis() + 2000); report.setUpdateTime(System.currentTimeMillis() + 2000); } @@ -751,8 +751,8 @@ public class ApiAutomationService { // 环境检查 this.checkEnv(request, apiScenarios); - if (request.getConfig() != null && request.getConfig().getMode().equals("serial")) { - if (StringUtils.isNotEmpty(request.getConfig().getReportName())) { + if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { + if (StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString()) && StringUtils.isNotEmpty(request.getConfig().getReportName())) { request.setExecuteType(ExecuteType.Completed.name()); } } @@ -806,7 +806,7 @@ public class ApiAutomationService { // 生成集成报告 String serialReportId = null; - if (request.getConfig() != null && request.getConfig().getMode().equals("serial") && StringUtils.equals(request.getConfig().getReportType(), "setReport") && StringUtils.isNotEmpty(request.getConfig().getReportName())) { + if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString()) && StringUtils.equals(request.getConfig().getReportType(), RunModeConstants.SET_REPORT.toString()) && StringUtils.isNotEmpty(request.getConfig().getReportName())) { request.getConfig().setReportId(UUID.randomUUID().toString()); APIScenarioReportResult report = createScenarioReport(request.getConfig().getReportId(), JSON.toJSONString(scenarioIds), scenarioNames.deleteCharAt(scenarioNames.toString().length() - 1).toString(), ReportTriggerMode.MANUAL.name(), ExecuteType.Saved.name(), request.getProjectId(), request.getReportUserID(), request.getConfig()); @@ -823,7 +823,7 @@ public class ApiAutomationService { private void run(Map map, RunScenarioRequest request, String serialReportId) { // 开始选择执行模式 ExecutorService executorService = Executors.newFixedThreadPool(map.size()); - if (request.getConfig() != null && request.getConfig().getMode().equals("serial")) { + if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { // 开始串行执行 Thread thread = new Thread(new Runnable() { @Override @@ -1057,7 +1057,7 @@ public class ApiAutomationService { public String run(RunScenarioRequest request) { if (request.getConfig() != null) { - if (request.getConfig().getMode().equals("parallel")) { + if (request.getConfig().getMode().equals(RunModeConstants.PARALLEL.toString())) { // 校验并发数量 int count = 50; BaseSystemConfigDTO dto = systemParameterService.getBaseInfo(); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java index 558941ff45..862edfd466 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java @@ -3,11 +3,15 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult; import io.metersphere.api.jmeter.TestResult; -import io.metersphere.base.domain.*; +import io.metersphere.base.domain.ApiDefinitionExecResult; +import io.metersphere.base.domain.ApiDefinitionExecResultExample; +import io.metersphere.base.domain.ApiTestCaseWithBLOBs; +import io.metersphere.base.domain.TestPlanApiCase; import io.metersphere.base.mapper.ApiDefinitionExecResultMapper; import io.metersphere.base.mapper.ApiTestCaseMapper; import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper; import io.metersphere.commons.constants.ApiRunMode; +import io.metersphere.commons.constants.DelimiterConstants; import io.metersphere.commons.utils.DateUtils; import io.metersphere.commons.utils.SessionUtils; import io.metersphere.track.dto.TestPlanDTO; @@ -61,8 +65,8 @@ public class ApiDefinitionExecResultService { saveResult.setCreateTime(item.getStartTime()); saveResult.setUserId(result.getUserId()); saveResult.setName(item.getName()); - if (item.getName().indexOf("<->") != -1) { - saveResult.setName(item.getName().substring(0, item.getName().indexOf("<->"))); + if (item.getName().indexOf(DelimiterConstants.SEPARATOR.toString()) != -1) { + saveResult.setName(item.getName().substring(0, item.getName().indexOf(DelimiterConstants.SEPARATOR.toString()))); } saveResult.setResourceId(item.getName()); saveResult.setContent(JSON.toJSONString(item)); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 8b7b70b1fb..353354ede9 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -583,8 +583,8 @@ public class ApiDefinitionService { public void addResult(TestResult res) { if (res != null && CollectionUtils.isNotEmpty(res.getScenarios()) && res.getScenarios().get(0) != null && CollectionUtils.isNotEmpty(res.getScenarios().get(0).getRequestResults())) { RequestResult result = res.getScenarios().get(0).getRequestResults().get(0); - if (result.getName().indexOf("<->") != -1) { - result.setName(result.getName().substring(0, result.getName().indexOf("<->"))); + if (result.getName().indexOf(DelimiterConstants.SEPARATOR.toString()) != -1) { + result.setName(result.getName().substring(0, result.getName().indexOf(DelimiterConstants.SEPARATOR.toString()))); } cache.put(res.getTestId(), result); } else { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index 7ac5d6451e..a0d74bf9ed 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -396,6 +396,9 @@ public class ApiScenarioReportService { testResult.setPassAssertions(testResult.getPassAssertions() + scenarioResult.getPassAssertions()); testResult.setSuccess(testResult.getSuccess() + scenarioResult.getSuccess()); testResult.setTotalAssertions(scenarioResult.getTotalAssertions() + testResult.getTotalAssertions()); + testResult.setScenarioTotal(testResult.getScenarioTotal() + scenarioResult.getScenarioTotal()); + testResult.setScenarioSuccess(testResult.getScenarioSuccess() + scenarioResult.getScenarioSuccess()); + testResult.setScenarioError(testResult.getScenarioError() + scenarioResult.getScenarioError()); } catch (Exception e) { LogUtil.error(e.getMessage()); } diff --git a/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java b/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java index 38f6ec1616..c9a8bbff81 100644 --- a/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java +++ b/backend/src/main/java/io/metersphere/api/service/task/SerialScenarioExecTask.java @@ -45,6 +45,11 @@ public class SerialScenarioExecTask implements Callable { break; } } + // 执行失败了,恢复报告状态 + if (index == 200 && report != null && report.getStatus().equals(APITestStatus.Running.name())) { + report.setStatus(APITestStatus.Error.name()); + apiScenarioReportMapper.updateByPrimaryKey(report); + } return (T) report; } catch (Exception ex) { LogUtil.error(ex.getMessage()); diff --git a/backend/src/main/java/io/metersphere/commons/constants/DelimiterConstants.java b/backend/src/main/java/io/metersphere/commons/constants/DelimiterConstants.java new file mode 100644 index 0000000000..9fd19e0a66 --- /dev/null +++ b/backend/src/main/java/io/metersphere/commons/constants/DelimiterConstants.java @@ -0,0 +1,15 @@ +package io.metersphere.commons.constants; + +public enum DelimiterConstants { + STEP_DELIMITER("^@~@^"), SEPARATOR("<->"); + private String value; + + DelimiterConstants(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } +} diff --git a/backend/src/main/java/io/metersphere/commons/constants/RunModeConstants.java b/backend/src/main/java/io/metersphere/commons/constants/RunModeConstants.java new file mode 100644 index 0000000000..49a1cb3a52 --- /dev/null +++ b/backend/src/main/java/io/metersphere/commons/constants/RunModeConstants.java @@ -0,0 +1,17 @@ +package io.metersphere.commons.constants; + +public enum RunModeConstants { + + SERIAL("serial"), SET_REPORT("setReport"), PARALLEL("parallel"); + + private String value; + + RunModeConstants(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } +} diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java index be6a9ca812..70a41a89c1 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseService.java @@ -6,6 +6,7 @@ import io.metersphere.base.mapper.LoadTestReportMapper; import io.metersphere.base.mapper.TestPlanLoadCaseMapper; import io.metersphere.base.mapper.TestPlanMapper; import io.metersphere.base.mapper.ext.ExtTestPlanLoadCaseMapper; +import io.metersphere.commons.constants.RunModeConstants; import io.metersphere.commons.constants.TestPlanStatus; import io.metersphere.commons.exception.MSException; import io.metersphere.controller.request.OrderRequest; @@ -129,7 +130,7 @@ public class TestPlanLoadCaseService { } public void runBatch(RunBatchTestPlanRequest request) { - if (request.getConfig() != null && request.getConfig().getMode().equals("serial")) { + if (request.getConfig() != null && request.getConfig().getMode().equals(RunModeConstants.SERIAL.toString())) { try { serialRun(request); } catch (Exception e) { diff --git a/backend/src/main/java/org/apache/jmeter/samplers/SampleResult.java b/backend/src/main/java/org/apache/jmeter/samplers/SampleResult.java index e76248499f..943eeeb2f8 100644 --- a/backend/src/main/java/org/apache/jmeter/samplers/SampleResult.java +++ b/backend/src/main/java/org/apache/jmeter/samplers/SampleResult.java @@ -23,7 +23,6 @@ import org.apache.jmeter.gui.Searchable; import org.apache.jmeter.testelement.TestPlan; import org.apache.jmeter.threads.JMeterContext.TestLogicalAction; import org.apache.jmeter.threads.JMeterContextService; -import org.apache.jmeter.threads.JMeterVariables; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.util.JOrphanUtils; import org.slf4j.Logger; @@ -164,12 +163,25 @@ public class SampleResult implements Serializable, Cloneable, Searchable { } } + /** + * 定制自定义添加 ================= + */ private String samplerId; public String getSamplerId() { return this.samplerId; } + // 数据格式 List 多层父级按照同级统计 + private String scenario; + + public String getScenario() { + return this.scenario; + } + + /** + * 定制自定义添加 ================= + */ private SampleSaveConfiguration saveConfig; private SampleResult parent; @@ -336,6 +348,7 @@ public class SampleResult implements Serializable, Cloneable, Searchable { Sampler sampler = JMeterContextService.getContext().getCurrentSampler(); if (sampler != null) { this.samplerId = sampler.getPropertyAsString("MS-ID"); + this.scenario = sampler.getPropertyAsString("MS-SCENARIO"); } } diff --git a/frontend/src/business/components/api/automation/report/components/MetricChart.vue b/frontend/src/business/components/api/automation/report/components/MetricChart.vue index 3643ca5e4e..6557378569 100644 --- a/frontend/src/business/components/api/automation/report/components/MetricChart.vue +++ b/frontend/src/business/components/api/automation/report/components/MetricChart.vue @@ -26,6 +26,30 @@
+ +
+ + +
+
{{ content.scenarioTotal ? content.scenarioTotal : 0}}
+
{{ $t('api_test.scenario.scenario') }}
+
+ +
+
{{ content.scenarioSuccess ? content.scenarioSuccess: 0 }}
+
{{ $t('api_report.success') }}
+
+
+ +
+
{{ content.scenarioError ? content.scenarioError : 0 }}
+
{{ $t('api_report.fail') }}
+
+
+
+
+
+
@@ -50,206 +74,209 @@ diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 256cf34a6d..ef4888ee89 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -994,7 +994,7 @@ }, getApiScenario() { this.loading = true; - if (this.currentScenario.tags != undefined && !(this.currentScenario.tags instanceof Array)) { + if (this.currentScenario.tags != undefined && this.currentScenario.tags && !(this.currentScenario.tags instanceof Array)) { this.currentScenario.tags = JSON.parse(this.currentScenario.tags); } if (!this.currentScenario.variables) {