From 71c512174dc838a3f97d5b7b62efc29189c1a7ec Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 31 Mar 2021 12:22:14 +0800 Subject: [PATCH 01/23] =?UTF-8?q?fix(=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95)?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=BC=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=81=B6=E5=B0=94=E4=BC=9A=E4=BC=A0=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../performance/test/components/ExistFiles.vue | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/src/business/components/performance/test/components/ExistFiles.vue b/frontend/src/business/components/performance/test/components/ExistFiles.vue index e264843c2b..b2cd851e1a 100644 --- a/frontend/src/business/components/performance/test/components/ExistFiles.vue +++ b/frontend/src/business/components/performance/test/components/ExistFiles.vue @@ -173,11 +173,12 @@ export default { updateTime: row.lastModified, }); } + // + rows.forEach(row => { + this.fileList.push(row); + }) if (this.loadType === 'resource') { - rows.forEach(row => { - this.fileList.push(row); - }) this.$success(this.$t('test_track.case.import.success')); this.close(); return; @@ -197,8 +198,6 @@ export default { tg.options = {}; this.scenarios.push(tg); }); - let file = new File([d.jmx], d.name); - this.uploadList.push(file); }); this.$emit('fileChange', this.scenarios); From 8c7e941ee40bc21f50bad1efed95b70d03fc6c1f Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 31 Mar 2021 12:24:38 +0800 Subject: [PATCH 02/23] chore: sync --- frontend/src/business/components/xpack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index 07951ba17a..a37e6bb56f 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit 07951ba17aef6f29e50cfd68e40de3266f9a60cd +Subproject commit a37e6bb56ffaa7ecc4ee128640e9415304ad41b6 From 4811432acc8b78266518dd39bddef2f204c3bf57 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 31 Mar 2021 12:59:48 +0800 Subject: [PATCH 03/23] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E4=BF=AE=E5=A4=8Dcsv=20=E5=88=86=E9=9A=94?= =?UTF-8?q?=E7=AC=A6=E4=B8=8D=E8=83=BD=E7=BC=96=E8=BE=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/automation/scenario/variable/VariableList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue b/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue index 493fae9fb5..8f23c32cb6 100644 --- a/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue +++ b/frontend/src/business/components/api/automation/scenario/variable/VariableList.vue @@ -226,7 +226,7 @@ this.headers = headers; } this.visible = true; - this.editData = {type: "CONSTANT"}; + this.editData = {type: "CONSTANT", delimiter: ","}; this.addParameters(this.editData); this.disabled = disabled; }, From e092a7a130fc42495e1b910517f2411ccad9814a Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 31 Mar 2021 13:03:33 +0800 Subject: [PATCH 04/23] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E6=94=BE=E5=BC=80=E5=85=A8=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/api/automation/scenario/EnvSelect.vue | 6 +++--- frontend/src/business/components/xpack | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/business/components/api/automation/scenario/EnvSelect.vue b/frontend/src/business/components/api/automation/scenario/EnvSelect.vue index 6340706b4d..bfb759b091 100644 --- a/frontend/src/business/components/api/automation/scenario/EnvSelect.vue +++ b/frontend/src/business/components/api/automation/scenario/EnvSelect.vue @@ -243,9 +243,9 @@ } }) } else { - // this.checkFullUrl(data); - // sign = this.isFullUrl; - sign = false; + this.checkFullUrl(data); + sign = this.isFullUrl; + //sign = false; } // 校验是否全是全路径 diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index a37e6bb56f..07951ba17a 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit a37e6bb56ffaa7ecc4ee128640e9415304ad41b6 +Subproject commit 07951ba17aef6f29e50cfd68e40de3266f9a60cd From ed3e076a014612cb092562c27062490a0da2364e Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 31 Mar 2021 13:17:05 +0800 Subject: [PATCH 05/23] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E6=94=BE=E5=BC=80=E5=85=A8=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/api/automation/scenario/EnvSelect.vue | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/frontend/src/business/components/api/automation/scenario/EnvSelect.vue b/frontend/src/business/components/api/automation/scenario/EnvSelect.vue index bfb759b091..5bdd88307f 100644 --- a/frontend/src/business/components/api/automation/scenario/EnvSelect.vue +++ b/frontend/src/business/components/api/automation/scenario/EnvSelect.vue @@ -243,13 +243,11 @@ } }) } else { - this.checkFullUrl(data); - sign = this.isFullUrl; - //sign = false; + sign = false; } - // 校验是否全是全路径 - + this.checkFullUrl(data); + sign = this.isFullUrl; } if (!sign) { From d62391e6ca59bd55af60a7f508b0753a0c8e8686 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 31 Mar 2021 13:20:53 +0800 Subject: [PATCH 06/23] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E6=B3=A8=E9=87=8A=E5=85=A8=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/components/api/automation/scenario/EnvSelect.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/business/components/api/automation/scenario/EnvSelect.vue b/frontend/src/business/components/api/automation/scenario/EnvSelect.vue index 5bdd88307f..27a4cb1918 100644 --- a/frontend/src/business/components/api/automation/scenario/EnvSelect.vue +++ b/frontend/src/business/components/api/automation/scenario/EnvSelect.vue @@ -246,8 +246,8 @@ sign = false; } // 校验是否全是全路径 - this.checkFullUrl(data); - sign = this.isFullUrl; + //this.checkFullUrl(data); + //sign = this.isFullUrl; } if (!sign) { From 4045f5546fa25243df8c1f70837d4bf4dc0ec413 Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 31 Mar 2021 13:23:26 +0800 Subject: [PATCH 07/23] chore: sync --- frontend/src/business/components/xpack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index 07951ba17a..a37e6bb56f 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit 07951ba17aef6f29e50cfd68e40de3266f9a60cd +Subproject commit a37e6bb56ffaa7ecc4ee128640e9415304ad41b6 From 0cb2188cd23c3283c24684b32b5f2a6a792a93d0 Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 31 Mar 2021 13:24:50 +0800 Subject: [PATCH 08/23] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E6=81=A2=E5=A4=8Dxpack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/business/components/xpack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/business/components/xpack b/frontend/src/business/components/xpack index 07951ba17a..a37e6bb56f 160000 --- a/frontend/src/business/components/xpack +++ b/frontend/src/business/components/xpack @@ -1 +1 @@ -Subproject commit 07951ba17aef6f29e50cfd68e40de3266f9a60cd +Subproject commit a37e6bb56ffaa7ecc4ee128640e9415304ad41b6 From d55bbc6dd8fd24ee330ce39c2d127f23bf7b70fb Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 31 Mar 2021 13:43:43 +0800 Subject: [PATCH 09/23] =?UTF-8?q?fix:=20=E6=8E=A5=E5=8F=A3=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E6=B2=A1=E6=9C=89=E5=B8=A6=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/definition/components/module/ApiModule.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/business/components/api/definition/components/module/ApiModule.vue b/frontend/src/business/components/api/definition/components/module/ApiModule.vue index 1d2e735ff6..22a88d9139 100644 --- a/frontend/src/business/components/api/definition/components/module/ApiModule.vue +++ b/frontend/src/business/components/api/definition/components/module/ApiModule.vue @@ -133,11 +133,16 @@ this.data.forEach(node => { buildTree(node, {path: ''}); }); - this.$emit('setModuleOptions', this.data); this.$emit('setNodeTree', this.data); if (this.$refs.nodeTree) { this.$refs.nodeTree.filter(this.condition.filterText); } + let moduleOptions = []; + this.data.forEach(node => { + buildNodePath(node, {path: ''}, moduleOptions); + }); + this.moduleOptions = moduleOptions; + this.$emit('setModuleOptions', moduleOptions); } }); }, From 57bddf4bd09ccf362d9351b0049086a94c870a11 Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 31 Mar 2021 14:21:56 +0800 Subject: [PATCH 10/23] =?UTF-8?q?fix:=20=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E5=AF=BC=E5=85=A5=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/listener/TestCaseDataListener.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java b/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java index ba941aad35..05615842c0 100644 --- a/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java +++ b/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java @@ -142,7 +142,7 @@ public class TestCaseDataListener extends EasyExcelListener { public void saveData() { //excel中用例都有错误时就返回,只要有用例可用于更新或者插入就不返回 - if (!errList.isEmpty() && list.size() == 0 && updateList.size() == 0) { + if (!errList.isEmpty()) { return; } @@ -231,15 +231,23 @@ public class TestCaseDataListener extends EasyExcelListener { */ public String modifyTagPattern(TestCaseExcelData data){ String tags = data.getTags(); - if (tags != null) { - Stream stringStream = Arrays.stream(tags.split("[,;,;]")); //当标签值以中英文的逗号和分号分隔时才能正确解析 - List tagList = stringStream.map(tag -> tag = "\"" + tag + "\"") - .collect(Collectors.toList()); - String modifiedTags = StringUtils.join(tagList, ","); - modifiedTags = "[" + modifiedTags + "]"; - return modifiedTags; - }else { - return null; + try { + if (StringUtils.isNotBlank(tags)) { + JSONArray.parse(tags); + return tags; + } + return "[]"; + } catch (Exception e) { + if (tags != null) { + Stream stringStream = Arrays.stream(tags.split("[,;,;]")); //当标签值以中英文的逗号和分号分隔时才能正确解析 + List tagList = stringStream.map(tag -> tag = "\"" + tag + "\"") + .collect(Collectors.toList()); + String modifiedTags = StringUtils.join(tagList, ","); + modifiedTags = "[" + modifiedTags + "]"; + return modifiedTags; + } else { + return "[]"; + } } } From 2279c17d73f50eaf18d82d23a308cfc4ec486b9f Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 31 Mar 2021 14:33:04 +0800 Subject: [PATCH 11/23] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E4=BF=AE=E6=94=B9=E8=BD=AC=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/api/definition/components/case/ApiCaseList.vue | 1 + frontend/src/business/components/api/test/Upgrade.vue | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue index f63c1e8f92..d1e3834198 100644 --- a/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue +++ b/frontend/src/business/components/api/definition/components/case/ApiCaseList.vue @@ -152,6 +152,7 @@ saveApiAndCase(api) { this.visible = true; this.api = api; + this.currentApi = api; this.addCase(); }, setEnvironment(environment) { diff --git a/frontend/src/business/components/api/test/Upgrade.vue b/frontend/src/business/components/api/test/Upgrade.vue index 0c3b568be8..40f70cbd05 100644 --- a/frontend/src/business/components/api/test/Upgrade.vue +++ b/frontend/src/business/components/api/test/Upgrade.vue @@ -11,7 +11,6 @@ Date: Wed, 31 Mar 2021 14:43:59 +0800 Subject: [PATCH 12/23] =?UTF-8?q?fix:=20=E6=8E=A5=E5=8F=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=A6=96=E9=A1=B5=E5=A2=9E=E5=8A=A0"=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=A6=86=E7=9B=96=E7=8E=87=E7=BB=9F=E8=AE=A1"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 接口测试首页增加"接口覆盖率统计" --- .../api/controller/APITestController.java | 54 +++++-- .../datacount/response/ApiDataCountDTO.java | 5 + .../api/service/ApiAutomationService.java | 132 ++++++++++++++++++ .../api/service/ApiDefinitionService.java | 4 + .../api/service/ApiTestCaseService.java | 4 + .../mapper/ext/ExtApiDefinitionMapper.java | 2 + .../mapper/ext/ExtApiDefinitionMapper.xml | 5 + .../base/mapper/ext/ExtApiScenarioMapper.java | 3 +- .../base/mapper/ext/ExtApiScenarioMapper.xml | 3 + .../base/mapper/ext/ExtApiTestCaseMapper.java | 2 + .../base/mapper/ext/ExtApiTestCaseMapper.xml | 3 + .../api/homepage/ApiTestHomePage.vue | 7 +- .../api/homepage/components/SceneInfoCard.vue | 29 +++- frontend/src/i18n/en-US.js | 1 + frontend/src/i18n/zh-CN.js | 1 + frontend/src/i18n/zh-TW.js | 1 + 16 files changed, 237 insertions(+), 19 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/controller/APITestController.java b/backend/src/main/java/io/metersphere/api/controller/APITestController.java index d43ea2acb9..185abbd176 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APITestController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APITestController.java @@ -12,8 +12,7 @@ import io.metersphere.api.dto.datacount.response.TaskInfoResult; import io.metersphere.api.dto.definition.RunDefinitionRequest; import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter; import io.metersphere.api.service.*; -import io.metersphere.base.domain.ApiTest; -import io.metersphere.base.domain.Schedule; +import io.metersphere.base.domain.*; import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.constants.ScheduleGroup; import io.metersphere.commons.utils.CronUtils; @@ -30,13 +29,15 @@ import org.apache.commons.lang3.StringUtils; import org.apache.jorphan.collections.HashTree; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; -import org.python.core.AstList; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; import static io.metersphere.commons.utils.JsonPathUtils.getListJson; @@ -251,9 +252,7 @@ public class APITestController { @GetMapping("/testSceneInfoCount/{projectId}") public ApiDataCountDTO testSceneInfoCount(@PathVariable String projectId) { - ApiDataCountDTO apiCountResult = new ApiDataCountDTO(); - long scenarioCountNumber = apiAutomationService.countScenarioByProjectID(projectId); apiCountResult.setAllApiDataCountNumber(scenarioCountNumber); @@ -272,17 +271,46 @@ public class APITestController { //未执行、未通过、已通过 List countResultByRunResult = apiAutomationService.countRunResultByProjectID(projectId); apiCountResult.countRunResult(countResultByRunResult); - long allCount = apiCountResult.getUnexecuteCount() + apiCountResult.getExecutionPassCount() + apiCountResult.getExecutionFailedCount(); - + DecimalFormat df = new DecimalFormat("0.0"); if (allCount != 0) { + //通过率 float coverageRageNumber = (float) apiCountResult.getExecutionPassCount() * 100 / allCount; - DecimalFormat df = new DecimalFormat("0.0"); apiCountResult.setPassRage(df.format(coverageRageNumber) + "%"); } - return apiCountResult; + } + @GetMapping("/countInterfaceCoverage/{projectId}") + public String countInterfaceCoverage(@PathVariable String projectId) { + String returnStr = "100%"; + /** + * 接口覆盖率 + * 复制的接口定义/复制或引用的单接口用例/ 添加的自定义请求 url 路径与现有的接口定义一致的请求 + */ + long startTime1 = System.currentTimeMillis(); + List allScenarioInfoList = apiAutomationService.selectIdAndScenarioByProjectId(projectId); + long startTime2 = System.currentTimeMillis(); + System.out.println("Search data time : " + (startTime2 - startTime1)); + startTime1 = System.currentTimeMillis(); + List allEffectiveApiIdList = apiDefinitionService.selectEffectiveIdByProjectId(projectId); + startTime2 = System.currentTimeMillis(); + System.out.println("Search data time (api info) : " + (startTime2 - startTime1)); + List allEffectiveApiCaseList = apiTestCaseService.selectEffectiveTestCaseByProjectId(projectId); + long startTime3 = System.currentTimeMillis(); + System.out.println("Search data time (case info): " + (startTime3 - startTime2)); + + try { + startTime1 = System.currentTimeMillis(); + float intetfaceCoverageRageNumber = apiAutomationService.countInterfaceCoverage(allScenarioInfoList, allEffectiveApiIdList, allEffectiveApiCaseList); + startTime2 = System.currentTimeMillis(); + System.out.println("Count data time : " + (startTime2 - startTime1)); + DecimalFormat df = new DecimalFormat("0.0"); + returnStr = df.format(intetfaceCoverageRageNumber) + "%"; + }catch (Exception e){ + e.printStackTrace(); + } + return returnStr; } @GetMapping("/scheduleTaskInfoCount/{projectId}") @@ -346,11 +374,11 @@ public class APITestController { @GetMapping("/runningTask/{projectID}/{callFrom}") public List runningTask(@PathVariable String projectID, @PathVariable String callFrom) { List typeFilter = new ArrayList<>(); - if(StringUtils.equals(callFrom, "api_test")) { // 接口测试首页显示的运行中定时任务,只要这3种,不需要 性能测试、api_test(旧版) + if (StringUtils.equals(callFrom, "api_test")) { // 接口测试首页显示的运行中定时任务,只要这3种,不需要 性能测试、api_test(旧版) typeFilter.add(ScheduleGroup.API_SCENARIO_TEST.name()); typeFilter.add(ScheduleGroup.SWAGGER_IMPORT.name()); typeFilter.add(ScheduleGroup.TEST_PLAN_TEST.name()); - } else if(StringUtils.equals(callFrom, "track_home")) { // 测试跟踪首页只显示测试计划的定时任务 + } else if (StringUtils.equals(callFrom, "track_home")) { // 测试跟踪首页只显示测试计划的定时任务 typeFilter.add(ScheduleGroup.TEST_PLAN_TEST.name()); } List resultList = scheduleService.findRunningTaskInfoByProjectID(projectID, typeFilter); @@ -386,7 +414,7 @@ public class APITestController { String testName = runRequest.getName(); //将jmx处理封装为通用方法 - JmxInfoDTO dto = apiTestService.updateJmxString(jmxString,testName,false); + JmxInfoDTO dto = apiTestService.updateJmxString(jmxString, testName, false); dto.setName(runRequest.getName() + ".jmx"); return dto; } diff --git a/backend/src/main/java/io/metersphere/api/dto/datacount/response/ApiDataCountDTO.java b/backend/src/main/java/io/metersphere/api/dto/datacount/response/ApiDataCountDTO.java index 1ed49369c7..088cb896f5 100644 --- a/backend/src/main/java/io/metersphere/api/dto/datacount/response/ApiDataCountDTO.java +++ b/backend/src/main/java/io/metersphere/api/dto/datacount/response/ApiDataCountDTO.java @@ -111,6 +111,11 @@ public class ApiDataCountDTO { */ private String successRage = " 0%"; + /** + * 接口覆盖率 + */ + private String interfaceCoverage = " 0%"; + public ApiDataCountDTO(){} /** 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 33626513da..1694d72efe 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -1,6 +1,7 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONPath; import com.fasterxml.jackson.core.type.TypeReference; @@ -710,6 +711,10 @@ public class ApiAutomationService { return extApiScenarioMapper.countByProjectID(projectId); } + public List selectIdAndScenarioByProjectId(String projectId) { + return extApiScenarioMapper.selectIdAndScenarioByProjectId(projectId); + } + public long countScenarioByProjectIDAndCreatInThisWeek(String projectId) { Map startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date()); Date firstTime = startAndEndDateInWeek.get("firstTime"); @@ -1031,4 +1036,131 @@ public class ApiAutomationService { this.deleteBatch(request.getIds()); } + + /** + * 统计接口覆盖率 + * 1.场景中复制的接口 + * 2.场景中引用/复制的案例 + * 3.场景中的自定义路径与接口定义中的匹配 + * + * @param allScenarioInfoList 场景集合(id / scenario大字段 必须有数据) + * @param allEffectiveApiList 接口集合(id / path 必须有数据) + * @param allEffectiveApiCaseList 案例集合(id /api_definition_id 必须有数据) + * @return + */ + public float countInterfaceCoverage(List allScenarioInfoList, List allEffectiveApiList, List allEffectiveApiCaseList) { +// float coverageRageNumber = (float) apiCountResult.getExecutionPassCount() * 100 / allCount; + float intetfaceCoverage = 0; + if (allEffectiveApiList == null || allEffectiveApiList.isEmpty()) { + return 100; + } + + /** + * 前置工作: + * 1。将接口集合转化数据结构: map> urlMap 用来做3的筛选 + * 2。将案例集合转化数据结构:map> caseIdMap 用来做2的筛选 + * 3。将接口集合转化数据结构: List allApiIdList 用来做1的筛选 + * 4。自定义List coveragedIdList 已覆盖的id集合。 最终计算公式是 coveragedIdList/allApiIdList + * + * 解析allScenarioList的scenarioDefinition字段。 + * 1。提取每个步骤的url。 在 urlMap筛选 + * 2。提取每个步骤的id. 在caseIdMap 和 allApiIdList。 + */ + Map> urlMap = new HashMap<>(); + List allApiIdList = new ArrayList<>(); + Map> caseIdMap = new HashMap<>(); + for (ApiDefinition model : allEffectiveApiList) { + String url = model.getPath(); + String id = model.getId(); + allApiIdList.add(id); + if (urlMap.containsKey(url)) { + urlMap.get(url).add(id); + } else { + List list = new ArrayList<>(); + list.add(id); + urlMap.put(url, list); + } + } + for (ApiTestCase model : allEffectiveApiCaseList){ + String caseId = model.getId(); + String apiId = model.getApiDefinitionId(); + if (urlMap.containsKey(caseId)) { + urlMap.get(caseId).add(apiId); + } else { + List list = new ArrayList<>(); + list.add(apiId); + urlMap.put(caseId, list); + } + } + + if (allApiIdList.isEmpty()) { + return 100; + } + + List urlList = new ArrayList<>(); + List idList= new ArrayList<>(); + + for (ApiScenarioWithBLOBs model : allScenarioInfoList) { + String scenarioDefiniton = model.getScenarioDefinition(); + this.addUrlAndIdToList(scenarioDefiniton,urlList,idList); + } + + List containsApiIdList = new ArrayList<>(); + + for (String url : urlList) { + List apiIdList = urlMap.get(url); + if(apiIdList!=null ){ + for (String api : apiIdList) { + if(!containsApiIdList.contains(api)){ + containsApiIdList.add(api); + } + } + } + } + + for (String id : idList) { + List apiIdList = caseIdMap.get(id); + if(apiIdList!=null ){ + for (String api : apiIdList) { + if(!containsApiIdList.contains(api)){ + containsApiIdList.add(api); + } + } + } + + if(allApiIdList.contains(id)){ + if(!containsApiIdList.contains(id)){ + containsApiIdList.add(id); + } + } + } + + float coverageRageNumber = (float) containsApiIdList.size() * 100 / allApiIdList.size(); + return coverageRageNumber; + } + + private void addUrlAndIdToList(String scenarioDefiniton, List urlList, List idList) { + try { + JSONObject scenarioObj = JSONObject.parseObject(scenarioDefiniton); + if(scenarioObj.containsKey("hashTree")){ + JSONArray hashArr = scenarioObj.getJSONArray("hashTree"); + for (int i = 0; i < hashArr.size(); i++) { + JSONObject elementObj = hashArr.getJSONObject(i); + if(elementObj.containsKey("id")){ + String id = elementObj.getString("id"); + idList.add(id); + } + if(elementObj.containsKey("url")){ + String url = elementObj.getString("url"); + urlList.add(url); + } + if(elementObj.containsKey("path")){ + String path = elementObj.getString("path"); + urlList.add(path); + } + } + } + }catch (Exception e){ + } + } } 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 7884538fcc..eb3847aaf5 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -912,4 +912,8 @@ public class ApiDefinitionService { } return apiExportResult; } + + public List selectEffectiveIdByProjectId(String projectId) { + return extApiDefinitionMapper.selectEffectiveIdByProjectId(projectId); + } } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index aa7f0724a4..341c68747e 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -648,4 +648,8 @@ public class ApiTestCaseService { public ApiDefinitionExecResult getInfo(String id){ return apiDefinitionExecResultMapper.selectByPrimaryKey(id); } + + public List selectEffectiveTestCaseByProjectId(String projectId) { + return extApiTestCaseMapper.selectEffectiveTestCaseByProjectId(projectId); + } } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java index 44cf4c6abe..3230662b65 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.java @@ -38,4 +38,6 @@ public interface ExtApiDefinitionMapper { List listRelevance(@Param("request")ApiDefinitionRequest request); List listRelevanceReview(@Param("request")ApiDefinitionRequest request); List selectIds(@Param("request") BaseQueryRequest query); + + List selectEffectiveIdByProjectId(String projectId); } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml index bfaa0afcd0..7067ce9a49 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiDefinitionMapper.xml @@ -465,6 +465,11 @@ + diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java index 6bd9153db2..d7d397f6bb 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java @@ -6,7 +6,6 @@ import io.metersphere.api.dto.datacount.ApiDataCountResult; import io.metersphere.base.domain.ApiScenario; import io.metersphere.base.domain.ApiScenarioExample; import io.metersphere.base.domain.ApiScenarioWithBLOBs; -import io.metersphere.controller.request.BaseQueryRequest; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -28,6 +27,8 @@ public interface ExtApiScenarioMapper { long countByProjectID(String projectId); + List selectIdAndScenarioByProjectId(String projectId); + long countByProjectIDAndCreatInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp); List countRunResultByProjectID(String projectId); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml index c7db6225fe..db83f076af 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml @@ -304,6 +304,9 @@ + select name from api_test_case where project_id = #{projectId} + \ No newline at end of file diff --git a/frontend/src/business/components/api/homepage/ApiTestHomePage.vue b/frontend/src/business/components/api/homepage/ApiTestHomePage.vue index dd5236a8e8..1bd4373d58 100644 --- a/frontend/src/business/components/api/homepage/ApiTestHomePage.vue +++ b/frontend/src/business/components/api/homepage/ApiTestHomePage.vue @@ -34,7 +34,7 @@ - + @@ -82,6 +82,7 @@ export default { sceneCountData: {}, testCaseCountData: {}, scheduleTaskCountData: {}, + interfaceCoverage: "waitting...", tipsType: "1", result: {}, } @@ -109,6 +110,10 @@ export default { this.sceneCountData = response.data; }); + this.$get("/api/countInterfaceCoverage/" + selectProjectId, response => { + this.interfaceCoverage = response.data; + }); + this.$get("/api/testCaseInfoCount/" + selectProjectId, response => { this.testCaseCountData = response.data; }); diff --git a/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue b/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue index e048e5c050..19f64837d2 100644 --- a/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue +++ b/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue @@ -52,16 +52,29 @@ - - + + {{$t('api_test.home_page.detail_card.rate.pass')+":"}} - - + + {{sceneCountData.passRage}} + + + {{$t('api_test.home_page.detail_card.rate.interface_coverage')+":"}} + + + + {{interfaceCoverage}} + + + {{interfaceCoverage}} + + + @@ -120,6 +133,7 @@ export default { props:{ sceneCountData:{}, + interfaceCoverage:String, }, methods: { @@ -141,6 +155,13 @@ export default { margin:20px auto; } +.rows-count-number{ + font-family:'ArialMT', 'Arial', sans-serif; + font-size:30px; + color: var(--count_number); + margin:20px auto; +} + .main-number-show { width: 100px; height: 100px; diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 94837b728c..3ffb614514 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -1001,6 +1001,7 @@ export default { coverage: "Coverage rate", pass: "Pass rate", success: "Success rate", + interface_coverage: "Interface coverage", }, }, api_details_card: { diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 251d71ac48..5039195966 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -1005,6 +1005,7 @@ export default { coverage: "覆盖率", pass: "通过率", success: "成功率", + interface_coverage: "接口覆盖率", }, }, api_details_card: { diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index e9f8dddcd4..2a6ca86ab7 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -1003,6 +1003,7 @@ export default { coverage: "覆蓋率", pass: "通過率", success: "成功率", + interface_coverage: "接口覆蓋率", }, }, api_details_card: { From bbfa3d0cb4418f8a42f3ad5c330f0e563a7c665b Mon Sep 17 00:00:00 2001 From: "Captain.B" Date: Wed, 31 Mar 2021 14:55:19 +0800 Subject: [PATCH 13/23] =?UTF-8?q?refactor:=20=E5=8D=87=E7=BA=A7=20openapi?= =?UTF-8?q?=20swagger=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index c54fc88b7c..7c5cb8a95b 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -139,7 +139,7 @@ org.springdoc springdoc-openapi-ui - 1.2.32 + 1.5.6 @@ -280,7 +280,7 @@ io.swagger.parser.v3 swagger-parser - 2.0.22 + 2.0.24 From cb1ba0e0aaf680e69039011bf0d373c607a4efbe Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Wed, 31 Mar 2021 15:04:09 +0800 Subject: [PATCH 14/23] =?UTF-8?q?style(=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89):=20=E9=80=9A=E7=94=A8=E4=B8=8B=E6=8B=89=E6=A0=91=20?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=86=85=E5=AE=B9=E8=BF=87=E9=95=BF=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=B8=8D=E5=85=A8=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/components/common/select-tree/SelectTree.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/business/components/common/select-tree/SelectTree.vue b/frontend/src/business/components/common/select-tree/SelectTree.vue index 903273af67..c971151fea 100644 --- a/frontend/src/business/components/common/select-tree/SelectTree.vue +++ b/frontend/src/business/components/common/select-tree/SelectTree.vue @@ -379,14 +379,17 @@ .common-tree { overflow: auto; - height: 200px; + min-height: 200px; + max-height: 400px; } .ms-tree-select { width: 100%; z-index: 111; } - + /deep/.el-tree-node__children{ + overflow: inherit; + } .ok { float: right; } From ace4c51f0cfae5f536efec770ff21695129e247d Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Wed, 31 Mar 2021 15:08:41 +0800 Subject: [PATCH 15/23] =?UTF-8?q?fix:=E7=94=A8=E4=BE=8B=E6=AD=A5=E9=AA=A4?= =?UTF-8?q?=E9=A2=9C=E8=89=B2=E5=8A=A0=E6=B7=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/comonents/functional/FunctionalTestCaseEdit.vue | 3 ++- .../track/review/view/components/TestReviewTestCaseEdit.vue | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue index d6b91f5552..ff3554b01d 100644 --- a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue +++ b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseEdit.vue @@ -711,7 +711,7 @@ export default { .border-hidden >>> .el-textarea__inner { border-style: hidden; background-color: white; - color: #606266; + color: #060505; } .cast_label { @@ -785,4 +785,5 @@ p { height: 550px; overflow: auto; } + diff --git a/frontend/src/business/components/track/review/view/components/TestReviewTestCaseEdit.vue b/frontend/src/business/components/track/review/view/components/TestReviewTestCaseEdit.vue index e2aab0f143..eb03657f6b 100644 --- a/frontend/src/business/components/track/review/view/components/TestReviewTestCaseEdit.vue +++ b/frontend/src/business/components/track/review/view/components/TestReviewTestCaseEdit.vue @@ -549,4 +549,10 @@ export default { .comment-card >>> .el-card__body { height: calc(100vh - 120px); } + +.tb-edit >>> .el-textarea__inner { + border-style: hidden; + background-color: white; + color: #060505; +} From 7881414af87dff7ad8c9862930bd28a5edf0de05 Mon Sep 17 00:00:00 2001 From: wenyann <64353056+wenyann@users.noreply.github.com> Date: Wed, 31 Mar 2021 15:25:36 +0800 Subject: [PATCH 16/23] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=A7=84?= =?UTF-8?q?=E5=88=92&=E6=89=A7=E8=A1=8C=E6=B5=8B=E8=AF=95=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E6=B2=A1=E6=9C=89=E6=9D=83=E9=99=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/track/controller/TestPlanController.java | 4 ++-- .../java/io/metersphere/track/service/TestPlanService.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java index 68736be502..3942c92a74 100644 --- a/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java +++ b/backend/src/main/java/io/metersphere/track/controller/TestPlanController.java @@ -91,8 +91,8 @@ public class TestPlanController { @PostMapping("/edit") @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) - public void editTestPlan(@RequestBody TestPlanDTO testPlanDTO) { - testPlanService.editTestPlan(testPlanDTO, true); + public String editTestPlan(@RequestBody TestPlanDTO testPlanDTO) { + return testPlanService.editTestPlan(testPlanDTO, true); } @PostMapping("/edit/status/{planId}") diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index 7d9c4047ac..e1da5af7a8 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -176,7 +176,7 @@ public class TestPlanService { return Optional.ofNullable(testPlanMapper.selectByPrimaryKey(testPlanId)).orElse(new TestPlan()); } - public int editTestPlan(TestPlanDTO testPlan, Boolean isSendMessage) { + public String editTestPlan(TestPlanDTO testPlan, Boolean isSendMessage) { checkTestPlanExist(testPlan); TestPlan res = testPlanMapper.selectByPrimaryKey(testPlan.getId()); // 先查一次库 testPlan.setUpdateTime(System.currentTimeMillis()); @@ -230,7 +230,7 @@ public class TestPlanService { .build(); noticeSendService.send(NoticeConstants.TaskType.TEST_PLAN_TASK, noticeModel); } - return i; + return testPlan.getId(); } //计划内容 From 7cc2737a5f8269e1e3ead9e6d0c52f25d5e9716b Mon Sep 17 00:00:00 2001 From: "song.tianyang" Date: Wed, 31 Mar 2021 15:58:50 +0800 Subject: [PATCH 17/23] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96excel=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E5=AF=BC=E5=85=A5=EF=BC=8C=E6=A8=A1=E5=9D=97=E5=AD=97?= =?UTF-8?q?=E6=95=B0=E8=B6=85=E6=A0=87=E7=9A=84=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化excel模板导入,模块字数超标的提示 --- .../excel/listener/TestCaseDataListener.java | 10 ++++++++++ .../definition/components/case/ApiCaseItem.vue | 16 +++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java b/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java index 05615842c0..f1d2d639c5 100644 --- a/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java +++ b/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java @@ -67,6 +67,16 @@ public class TestCaseDataListener extends EasyExcelListener { break; } } + //增加字数校验,每一层不能超过100字 + for (int i = 0; i < nodes.length; i++) { + String nodeStr = nodes[i]; + if(StringUtils.isNotEmpty(nodeStr)){ + if(nodeStr.trim().length()>100){ + stringBuilder.append(Translator.get("module") + Translator.get("test_track.length_less_than") + "100:"+nodeStr); + break; + } + } + } } // if (StringUtils.equals(data.getType(), TestCaseConstants.Type.Functional.getValue()) && StringUtils.equals(data.getMethod(), TestCaseConstants.Method.Auto.getValue())) { diff --git a/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue b/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue index 227102ac01..ec53fe028a 100644 --- a/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue +++ b/frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue @@ -27,7 +27,7 @@ + @blur="saveTestCase(apiCase,true)" :placeholder="$t('commons.input_name')" ref="nameEdit"/> {{ apiCase.id ? apiCase.name : '' }} @@ -48,7 +48,7 @@
- +
@@ -291,7 +291,7 @@ } }); }, - saveCase(row) { + saveCase(row,hideAlert) { let tmp = JSON.parse(JSON.stringify(row)); this.isShowInput = false; if (this.validate(tmp)) { @@ -328,16 +328,18 @@ row.createTime = data.createTime; row.updateTime = data.updateTime; if (!row.message) { - this.$success(this.$t('commons.save_success')); - this.$emit('refresh'); + if(!hideAlert){ + this.$success(this.$t('commons.save_success')); + this.$emit('refresh'); + } } }); }, - saveTestCase(row) { + saveTestCase(row,hideAlert) { if (this.api.saved) { this.addModule(row); } else { - this.saveCase(row); + this.saveCase(row,hideAlert); } }, showInput(row) { From 5b3df1ab1526d9f6264b72c78358e987ef8e386b Mon Sep 17 00:00:00 2001 From: "song.tianyang" Date: Wed, 31 Mar 2021 16:13:16 +0800 Subject: [PATCH 18/23] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=A6=86=E7=9B=96=E7=8E=87=E7=9A=84loading=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=9A=E6=94=B9=E4=B8=BA=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化接口覆盖率的loading方式:改为图标 --- .../components/api/homepage/components/SceneInfoCard.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue b/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue index 19f64837d2..130628bdf8 100644 --- a/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue +++ b/frontend/src/business/components/api/homepage/components/SceneInfoCard.vue @@ -68,7 +68,7 @@
- {{interfaceCoverage}} + {{interfaceCoverage}} @@ -161,7 +161,11 @@ export default { color: var(--count_number); margin:20px auto; } - +.lading-icon{ + font-size: 25px; + color: var(--count_number); + font-weight: bold; +} .main-number-show { width: 100px; height: 100px; From b2b83a57f50971d06b31c5875e6c1705063ededc Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 31 Mar 2021 16:50:04 +0800 Subject: [PATCH 20/23] =?UTF-8?q?fix:=20=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E6=97=A0=E6=B3=95=E9=80=89=E6=8B=A9=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/definition/components/module/ApiModule.vue | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/frontend/src/business/components/api/definition/components/module/ApiModule.vue b/frontend/src/business/components/api/definition/components/module/ApiModule.vue index 22a88d9139..1d2e735ff6 100644 --- a/frontend/src/business/components/api/definition/components/module/ApiModule.vue +++ b/frontend/src/business/components/api/definition/components/module/ApiModule.vue @@ -133,16 +133,11 @@ this.data.forEach(node => { buildTree(node, {path: ''}); }); + this.$emit('setModuleOptions', this.data); this.$emit('setNodeTree', this.data); if (this.$refs.nodeTree) { this.$refs.nodeTree.filter(this.condition.filterText); } - let moduleOptions = []; - this.data.forEach(node => { - buildNodePath(node, {path: ''}, moduleOptions); - }); - this.moduleOptions = moduleOptions; - this.$emit('setModuleOptions', moduleOptions); } }); }, From 3d939cbd8321cf1cb394a11ccbad896bf5fc2a4c Mon Sep 17 00:00:00 2001 From: song-tianyang <75963100+song-tianyang@users.noreply.github.com> Date: Wed, 31 Mar 2021 16:57:11 +0800 Subject: [PATCH 21/23] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=B5=8B=E8=AF=95=E9=A6=96=E9=A1=B5=E5=85=B3=E9=97=AD?= =?UTF-8?q?swagger=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E4=B8=8D=E5=BD=BB?= =?UTF-8?q?=E5=BA=95=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复接口测试首页关闭swagger定时任务不彻底的问题 --- .../io/metersphere/api/service/ApiAutomationService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 1694d72efe..05dc4aee97 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -30,6 +30,7 @@ import io.metersphere.commons.utils.*; import io.metersphere.controller.request.ScheduleRequest; import io.metersphere.i18n.Translator; import io.metersphere.job.sechedule.ApiScenarioTestJob; +import io.metersphere.job.sechedule.SwaggerUrlImportJob; import io.metersphere.job.sechedule.TestPlanTestJob; import io.metersphere.service.ScheduleService; import io.metersphere.track.dto.TestPlanDTO; @@ -816,7 +817,9 @@ public class ApiAutomationService { if (StringUtils.equals(request.getGroup(), ScheduleGroup.TEST_PLAN_TEST.name())) { scheduleService.addOrUpdateCronJob( request, TestPlanTestJob.getJobKey(request.getResourceId()), TestPlanTestJob.getTriggerKey(request.getResourceId()), TestPlanTestJob.class); - } else { + }else if(StringUtils.equals(request.getGroup(), ScheduleGroup.SWAGGER_IMPORT.name())){ + scheduleService.addOrUpdateCronJob(request, SwaggerUrlImportJob.getJobKey(request.getResourceId()), SwaggerUrlImportJob.getTriggerKey(request.getResourceId()), SwaggerUrlImportJob.class); + } else{ scheduleService.addOrUpdateCronJob( request, ApiScenarioTestJob.getJobKey(request.getResourceId()), ApiScenarioTestJob.getTriggerKey(request.getResourceId()), ApiScenarioTestJob.class); } From b68a0a4586880f62899a05afa6521fc137d0c67b Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 31 Mar 2021 17:26:05 +0800 Subject: [PATCH 22/23] =?UTF-8?q?fix:=20=E5=AF=BC=E5=85=A5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=B2=A1=E6=9C=89=E5=B8=A6=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/components/list/ApiList.vue | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/frontend/src/business/components/api/definition/components/list/ApiList.vue b/frontend/src/business/components/api/definition/components/list/ApiList.vue index c13957ac04..8844291a23 100644 --- a/frontend/src/business/components/api/definition/components/list/ApiList.vue +++ b/frontend/src/business/components/api/definition/components/list/ApiList.vue @@ -248,6 +248,7 @@ import {Api_List} from "@/business/components/common/model/JsonData"; import HeaderCustom from "@/business/components/common/head/HeaderCustom"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; import {Body} from "@/business/components/api/definition/model/ApiTestModel"; +import {buildNodePath} from "@/business/components/api/definition/model/NodeTree"; export default { @@ -768,13 +769,21 @@ export default { }); }, buildApiPath(apis) { - apis.forEach((api) => { + try { + let options = []; this.moduleOptions.forEach(item => { - if (api.moduleId === item.id) { - api.modulePath = item.path; - } + buildNodePath(item, {path: ''}, options); }); - }); + apis.forEach((api) => { + options.forEach((item) => { + if (api.moduleId === item.id) { + api.modulePath = item.path; + } + }) + }); + } catch (e) { + console.log(e); + } }, sort(column) { // 每次只对一个字段排序 From a2faa2bc87005f9a33639afd4f2456a8fd313edc Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Wed, 31 Mar 2021 17:40:24 +0800 Subject: [PATCH 23/23] =?UTF-8?q?fix:=20=E5=9C=BA=E6=99=AF=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=E6=97=A0=E6=B3=95=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/metersphere/api/service/ApiAutomationService.java | 1 + 1 file changed, 1 insertion(+) 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 05dc4aee97..c4c71db6f1 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -232,6 +232,7 @@ public class ApiAutomationService { scenario.setPrincipal(request.getPrincipal()); scenario.setStepTotal(request.getStepTotal()); scenario.setUpdateTime(System.currentTimeMillis()); + scenario.setDescription(request.getDescription()); scenario.setScenarioDefinition(JSON.toJSONString(request.getScenarioDefinition())); if (StringUtils.isNotEmpty(request.getStatus())) { scenario.setStatus(request.getStatus());