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 cee93da86b..786ffc536a 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -155,10 +155,9 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl public void teardownTest(BackendListenerContext context) throws Exception { TestResult testResult = new TestResult(); testResult.setTestId(testId); - testResult.setTotal(queue.size()); testResult.setSetReportId(this.setReportId); testResult.setConsole(getConsole()); - + testResult.setTotal(0); // 一个脚本里可能包含多个场景(ThreadGroup),所以要区分开,key: 场景Id final Map scenarios = new LinkedHashMap<>(); queue.forEach(result -> { @@ -198,11 +197,12 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl testResult.addPassAssertions(requestResult.getPassAssertions()); testResult.addTotalAssertions(requestResult.getTotalAssertions()); - + testResult.setTotal(testResult.getTotal()+1); scenarioResult.addPassAssertions(requestResult.getPassAssertions()); scenarioResult.addTotalAssertions(requestResult.getTotalAssertions()); } }); + testResult.getScenarios().addAll(scenarios.values()); testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getId)); ApiTestReport report = null; 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 060ce66d97..168152a24e 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java @@ -1,6 +1,7 @@ package io.metersphere.api.jmeter; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import io.metersphere.commons.constants.DelimiterConstants; import lombok.Data; import org.apache.commons.collections.CollectionUtils; @@ -46,6 +47,11 @@ public class TestResult { private Map margeScenariMap = new HashMap<>(); + private Map scenarioStepMap = new HashMap<>(); + + private int scenarioStepSuccess = 0; + private int scenarioStepError = 0; + private int scenarioStepTotal = 0; public void addError(int count) { this.error += count; } @@ -74,12 +80,33 @@ public class TestResult { } } + private void setStepStatus(String step_names, boolean status) { + if (!scenarioStepMap.containsKey(step_names) || status) { + scenarioStepMap.put(step_names, status); + } + } + + public void addScenario(ScenarioResult result) { if (result != null && CollectionUtils.isNotEmpty(result.getRequestResults())) { result.getRequestResults().forEach(item -> { + String itemScenarioName = ""; if (StringUtils.isNotEmpty(item.getScenario())) { - List id_names = JSON.parseObject(item.getScenario(), List.class); - this.setStatus(id_names, item.getError() > 0); + List all_id_names = JSON.parseObject(item.getScenario(), List.class); + if(all_id_names.size()>1){ + List id_names = new ArrayList<>(); + all_id_names.forEach(name -> { + if(!name.endsWith(result.getName())){ + id_names.add(name); + } + }); + this.setStatus(id_names, item.getError() > 0); + itemScenarioName = JSONArray.toJSONString(id_names); + }else{ + this.setStatus(all_id_names, item.getError() > 0); + itemScenarioName = JSONArray.toJSONString(all_id_names); + } + } if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf(SEPARATOR) != -1) { String array[] = item.getName().split(SEPARATOR); @@ -102,17 +129,38 @@ public class TestResult { } }); } + this.setStepStatus(item.getName()+itemScenarioName,item.getError()>0); }); scenarios.add(result); } - for (String key : margeScenariMap.keySet()) { - if (margeScenariMap.get(key)) { - this.scenarioError++; + /** + * 1.10.2 场景成功/失败统计,不再按照请求为纬度,按照场景为纬度, + */ + for (String key : scenarioStepMap.keySet()) { + if (scenarioStepMap .get(key)) { + this.scenarioStepError++; } else { - this.scenarioSuccess++; + this.scenarioStepSuccess++; } } - this.setScenarioTotal(this.margeScenariMap.size()); + boolean hasError = false; + for (String key : margeScenariMap.keySet()) { + if (margeScenariMap.get(key)) { + hasError = true; + break; + } + } + if(!margeScenariMap.isEmpty()){ + if(hasError){ + this.scenarioError ++; + }else { + this.scenarioSuccess++; + } + this.scenarioTotal++; + } + + + this.setScenarioStepTotal(this.scenarioStepMap.size()); } } 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 c47bc4511f..465275f94e 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -411,6 +411,9 @@ public class ApiScenarioReportService { testResult.setScenarioSuccess(testResult.getScenarioSuccess() + scenarioResult.getScenarioSuccess()); testResult.setScenarioError(testResult.getScenarioError() + scenarioResult.getScenarioError()); testResult.setConsole(scenarioResult.getConsole()); + testResult.setScenarioStepError(scenarioResult.getScenarioStepError()+testResult.getScenarioStepError()); + testResult.setScenarioStepSuccess(scenarioResult.getScenarioStepSuccess()+testResult.getScenarioStepSuccess()); + testResult.setScenarioStepTotal(scenarioResult.getScenarioStepTotal()+testResult.getScenarioStepTotal()); } catch (Exception e) { LogUtil.error(e.getMessage()); } diff --git a/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue b/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue index 1ec68ac2c4..8ef77d8709 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue @@ -2,7 +2,20 @@
- + + + + + + + {{ report.name }} + + + {{ report.name }} + + + + {{ report.createTime | timestampFormatDate }} @@ -20,6 +33,8 @@ @@ -55,5 +91,13 @@ .export-button { float: right; } + .scenario-name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 13px; + width: 100%; + } + 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 add6a6d5f0..a1fde5b8eb 100644 --- a/frontend/src/business/components/api/automation/report/components/MetricChart.vue +++ b/frontend/src/business/components/api/automation/report/components/MetricChart.vue @@ -38,23 +38,44 @@
-
+
{{ 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') }}
+ + + +
+
{{ content.scenarioStepTotal ? content.scenarioStepTotal : 0}}
+
{{ $t('test_track.plan_view.step') }}
+
+ +
+
{{ content.scenarioStepSuccess ? content.scenarioStepSuccess: 0 }}
+
{{ $t('api_report.success') }}
+
+ + +
+
{{ content.scenarioStepError ? content.scenarioStepError : 0 }}
+
{{ $t('api_report.fail') }}
+
+
+
+
diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index f74f1ed9c3..02bac6dfcf 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -317,6 +317,7 @@ export default { }, data() { return { + showConfigButtonWithOutPermission:false, onSampleError: false, props: { label: "label",