Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
8e5105d5
M
metersphere
项目概览
MeterSphere
/
metersphere
上一次同步 3 年多
通知
25
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
metersphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8e5105d5
编写于
1月 04, 2021
作者:
S
song.tianyang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 接口用例、用例列表、场景用例列表增加创建性能测试的功能
接口用例、用例列表、场景用例列表增加创建性能测试的功能
上级
3cb27580
变更
13
展开全部
隐藏空白更改
内联
并排
Showing
13 changed file
with
945 addition
and
370 deletion
+945
-370
backend/src/main/java/io/metersphere/api/controller/APITestController.java
...java/io/metersphere/api/controller/APITestController.java
+66
-40
backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java
...o/metersphere/api/controller/ApiAutomationController.java
+29
-0
backend/src/main/java/io/metersphere/api/controller/ApiTestCaseController.java
.../io/metersphere/api/controller/ApiTestCaseController.java
+13
-0
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
...java/io/metersphere/api/service/ApiAutomationService.java
+147
-0
backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java
...tersphere/performance/service/PerformanceTestService.java
+14
-2
backend/src/main/java/io/metersphere/service/FileService.java
...end/src/main/java/io/metersphere/service/FileService.java
+19
-0
frontend/src/business/components/api/automation/scenario/ScenarioExtendBtns.vue
...components/api/automation/scenario/ScenarioExtendBtns.vue
+24
-0
frontend/src/business/components/api/definition/components/basis/SetEnvironment.vue
...onents/api/definition/components/basis/SetEnvironment.vue
+112
-0
frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue
...components/api/definition/components/case/ApiCaseItem.vue
+2
-2
frontend/src/business/components/api/definition/components/case/ApiCaseList.vue
...components/api/definition/components/case/ApiCaseList.vue
+1
-0
frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue
...ents/api/definition/components/list/ApiCaseSimpleList.vue
+409
-326
frontend/src/business/components/api/definition/components/reference/ApiCaseTableExtendBtns.vue
...efinition/components/reference/ApiCaseTableExtendBtns.vue
+53
-0
frontend/src/business/components/api/definition/components/reference/ApiExtendBtns.vue
...nts/api/definition/components/reference/ApiExtendBtns.vue
+56
-0
未找到文件。
backend/src/main/java/io/metersphere/api/controller/APITestController.java
浏览文件 @
8e5105d5
...
...
@@ -9,10 +9,14 @@ import io.metersphere.api.dto.datacount.request.ScheduleInfoRequest;
import
io.metersphere.api.dto.datacount.response.ApiDataCountDTO
;
import
io.metersphere.api.dto.datacount.response.ExecutedCaseInfoDTO
;
import
io.metersphere.api.dto.datacount.response.TaskInfoResult
;
import
io.metersphere.api.dto.definition.RunDefinitionRequest
;
import
io.metersphere.api.dto.definition.request.MsTestElement
;
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.LoadTest
;
import
io.metersphere.base.domain.Schedule
;
import
io.metersphere.commons.constants.PerformanceTestStatus
;
import
io.metersphere.commons.constants.RoleConstants
;
import
io.metersphere.commons.constants.ScheduleGroup
;
import
io.metersphere.commons.utils.CronUtils
;
...
...
@@ -21,19 +25,23 @@ import io.metersphere.commons.utils.Pager;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.controller.request.QueryScheduleRequest
;
import
io.metersphere.dto.ScheduleDao
;
import
io.metersphere.performance.service.PerformanceTestService
;
import
io.metersphere.service.CheckPermissionService
;
import
io.metersphere.service.FileService
;
import
io.metersphere.service.ScheduleService
;
import
io.metersphere.track.request.testplan.SaveTestPlanRequest
;
import
org.apache.http.entity.ContentType
;
import
org.apache.jorphan.collections.HashTree
;
import
org.apache.shiro.authz.annotation.Logical
;
import
org.apache.shiro.authz.annotation.RequiresRoles
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.io.ByteArrayInputStream
;
import
java.io.InputStream
;
import
java.text.DecimalFormat
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.*
;
import
static
io
.
metersphere
.
commons
.
utils
.
JsonPathUtils
.
getListJson
;
...
...
@@ -60,6 +68,10 @@ public class APITestController {
private
ScheduleService
scheduleService
;
@Resource
private
APIReportService
apiReportService
;
@Resource
private
PerformanceTestService
performanceTestService
;
@Resource
private
CheckPermissionService
checkPermissionService
;
@GetMapping
(
"recent/{count}"
)
public
List
<
APITestResult
>
recentTest
(
@PathVariable
int
count
)
{
...
...
@@ -109,6 +121,7 @@ public class APITestController {
public
void
mergeCreate
(
@RequestPart
(
"request"
)
SaveAPITestRequest
request
,
@RequestPart
(
value
=
"file"
)
MultipartFile
file
,
@RequestPart
(
value
=
"selectIds"
)
List
<
String
>
selectIds
)
{
apiTestService
.
mergeCreate
(
request
,
file
,
selectIds
);
}
@PostMapping
(
value
=
"/update"
,
consumes
=
{
"multipart/form-data"
})
public
void
update
(
@RequestPart
(
"request"
)
SaveAPITestRequest
request
,
@RequestPart
(
value
=
"file"
)
MultipartFile
file
,
@RequestPart
(
value
=
"files"
)
List
<
MultipartFile
>
bodyFiles
)
{
checkownerService
.
checkApiTestOwner
(
request
.
getId
());
...
...
@@ -189,19 +202,19 @@ public class APITestController {
//查询完成率、进行中、已完成
List
<
ApiDataCountResult
>
countResultByStatelList
=
apiDefinitionService
.
countStateByProjectID
(
projectId
);
apiCountResult
.
countStatus
(
countResultByStatelList
);
long
allCount
=
apiCountResult
.
getFinishedCount
()
+
apiCountResult
.
getRunningCount
()+
apiCountResult
.
getNotStartedCount
();
long
allCount
=
apiCountResult
.
getFinishedCount
()
+
apiCountResult
.
getRunningCount
()
+
apiCountResult
.
getNotStartedCount
();
if
(
allCount
!=
0
)
{
float
complateRageNumber
=
(
float
)
apiCountResult
.
getFinishedCount
()*
100
/
allCount
;
if
(
allCount
!=
0
)
{
float
complateRageNumber
=
(
float
)
apiCountResult
.
getFinishedCount
()
*
100
/
allCount
;
DecimalFormat
df
=
new
DecimalFormat
(
"0.0"
);
apiCountResult
.
setCompletionRage
(
df
.
format
(
complateRageNumber
)
+
"%"
);
apiCountResult
.
setCompletionRage
(
df
.
format
(
complateRageNumber
)
+
"%"
);
}
apiCountResult
.
setHttpCountStr
(
"HTTP <br/><br/>"
+
apiCountResult
.
getHttpApiDataCountNumber
());
apiCountResult
.
setRpcCountStr
(
"RPC <br/><br/>"
+
apiCountResult
.
getRpcApiDataCountNumber
());
apiCountResult
.
setTcpCountStr
(
"TCP <br/><br/>"
+
apiCountResult
.
getTcpApiDataCountNumber
());
apiCountResult
.
setSqlCountStr
(
"SQL <br/><br/>"
+
apiCountResult
.
getSqlApiDataCountNumber
());
return
apiCountResult
;
apiCountResult
.
setHttpCountStr
(
"HTTP <br/><br/>"
+
apiCountResult
.
getHttpApiDataCountNumber
());
apiCountResult
.
setRpcCountStr
(
"RPC <br/><br/>"
+
apiCountResult
.
getRpcApiDataCountNumber
());
apiCountResult
.
setTcpCountStr
(
"TCP <br/><br/>"
+
apiCountResult
.
getTcpApiDataCountNumber
());
apiCountResult
.
setSqlCountStr
(
"SQL <br/><br/>"
+
apiCountResult
.
getSqlApiDataCountNumber
());
return
apiCountResult
;
}
@GetMapping
(
"/testCaseInfoCount/{projectId}"
)
...
...
@@ -222,21 +235,21 @@ public class APITestController {
//未覆盖 已覆盖: 统计当前接口下是否含有案例
List
<
ApiDataCountResult
>
countResultByApiCoverageList
=
apiDefinitionService
.
countApiCoverageByProjectID
(
projectId
);
apiCountResult
.
countApiCoverage
(
countResultByApiCoverageList
);
long
allCount
=
apiCountResult
.
getCoverageCount
()
+
apiCountResult
.
getUncoverageCount
();
long
allCount
=
apiCountResult
.
getCoverageCount
()
+
apiCountResult
.
getUncoverageCount
();
if
(
allCount
!=
0
)
{
float
coverageRageNumber
=
(
float
)
apiCountResult
.
getCoverageCount
()*
100
/
allCount
;
if
(
allCount
!=
0
)
{
float
coverageRageNumber
=
(
float
)
apiCountResult
.
getCoverageCount
()
*
100
/
allCount
;
DecimalFormat
df
=
new
DecimalFormat
(
"0.0"
);
apiCountResult
.
setCoverageRage
(
df
.
format
(
coverageRageNumber
)
+
"%"
);
apiCountResult
.
setCoverageRage
(
df
.
format
(
coverageRageNumber
)
+
"%"
);
}
apiCountResult
.
setHttpCountStr
(
"HTTP <br/><br/>"
+
apiCountResult
.
getHttpApiDataCountNumber
());
apiCountResult
.
setRpcCountStr
(
"RPC <br/><br/>"
+
apiCountResult
.
getRpcApiDataCountNumber
());
apiCountResult
.
setTcpCountStr
(
"TCP <br/><br/>"
+
apiCountResult
.
getTcpApiDataCountNumber
());
apiCountResult
.
setSqlCountStr
(
"SQL <br/><br/>"
+
apiCountResult
.
getSqlApiDataCountNumber
());
apiCountResult
.
setHttpCountStr
(
"HTTP <br/><br/>"
+
apiCountResult
.
getHttpApiDataCountNumber
());
apiCountResult
.
setRpcCountStr
(
"RPC <br/><br/>"
+
apiCountResult
.
getRpcApiDataCountNumber
());
apiCountResult
.
setTcpCountStr
(
"TCP <br/><br/>"
+
apiCountResult
.
getTcpApiDataCountNumber
());
apiCountResult
.
setSqlCountStr
(
"SQL <br/><br/>"
+
apiCountResult
.
getSqlApiDataCountNumber
());
return
apiCountResult
;
return
apiCountResult
;
}
@GetMapping
(
"/testSceneInfoCount/{projectId}"
)
...
...
@@ -263,15 +276,15 @@ public class APITestController {
List
<
ApiDataCountResult
>
countResultByRunResult
=
apiAutomationService
.
countRunResultByProjectID
(
projectId
);
apiCountResult
.
countRunResult
(
countResultByRunResult
);
long
allCount
=
apiCountResult
.
getUnexecuteCount
()
+
apiCountResult
.
getExecutionPassCount
()+
apiCountResult
.
getExecutionFailedCount
();
long
allCount
=
apiCountResult
.
getUnexecuteCount
()
+
apiCountResult
.
getExecutionPassCount
()
+
apiCountResult
.
getExecutionFailedCount
();
if
(
allCount
!=
0
)
{
float
coverageRageNumber
=
(
float
)
apiCountResult
.
getExecutionPassCount
()*
100
/
allCount
;
if
(
allCount
!=
0
)
{
float
coverageRageNumber
=
(
float
)
apiCountResult
.
getExecutionPassCount
()
*
100
/
allCount
;
DecimalFormat
df
=
new
DecimalFormat
(
"0.0"
);
apiCountResult
.
setPassRage
(
df
.
format
(
coverageRageNumber
)
+
"%"
);
apiCountResult
.
setPassRage
(
df
.
format
(
coverageRageNumber
)
+
"%"
);
}
return
apiCountResult
;
return
apiCountResult
;
}
...
...
@@ -287,7 +300,7 @@ public class APITestController {
apiCountResult
.
setThisWeekAddedCount
(
taskCountInThisWeek
);
long
api_executedInThisWeekCountNumber
=
apiReportService
.
countByProjectIdAndCreateInThisWeek
(
projectId
);
long
scene_executedInThisWeekCountNumber
=
apiScenarioReportService
.
countByProjectIdAndCreateAndByScheduleInThisWeek
(
projectId
);
long
executedInThisWeekCountNumber
=
api_executedInThisWeekCountNumber
+
scene_executedInThisWeekCountNumber
;
long
executedInThisWeekCountNumber
=
api_executedInThisWeekCountNumber
+
scene_executedInThisWeekCountNumber
;
apiCountResult
.
setThisWeekExecutedCount
(
executedInThisWeekCountNumber
);
//统计 失败 成功 以及总数
...
...
@@ -299,41 +312,41 @@ public class APITestController {
apiCountResult
.
countScheduleExecute
(
allExecuteResult
);
long
allCount
=
apiCountResult
.
getExecutedCount
();
if
(
allCount
!=
0
)
{
float
coverageRageNumber
=
(
float
)
apiCountResult
.
getSuccessCount
()*
100
/
allCount
;
if
(
allCount
!=
0
)
{
float
coverageRageNumber
=
(
float
)
apiCountResult
.
getSuccessCount
()
*
100
/
allCount
;
DecimalFormat
df
=
new
DecimalFormat
(
"0.0"
);
apiCountResult
.
setSuccessRage
(
df
.
format
(
coverageRageNumber
)
+
"%"
);
apiCountResult
.
setSuccessRage
(
df
.
format
(
coverageRageNumber
)
+
"%"
);
}
return
apiCountResult
;
return
apiCountResult
;
}
@GetMapping
(
"/faliureCaseAboutTestPlan/{projectId}/{limitNumber}"
)
public
List
<
ExecutedCaseInfoDTO
>
faliureCaseAboutTestPlan
(
@PathVariable
String
projectId
,
@PathVariable
int
limitNumber
)
{
List
<
ExecutedCaseInfoResult
>
selectDataList
=
apiDefinitionExecResultService
.
findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays
(
projectId
,
limitNumber
);
List
<
ExecutedCaseInfoResult
>
selectDataList
=
apiDefinitionExecResultService
.
findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays
(
projectId
,
limitNumber
);
List
<
ExecutedCaseInfoDTO
>
returnList
=
new
ArrayList
<>(
limitNumber
);
for
(
int
dataIndex
=
0
;
dataIndex
<
limitNumber
;
dataIndex
++)
{
for
(
int
dataIndex
=
0
;
dataIndex
<
limitNumber
;
dataIndex
++)
{
ExecutedCaseInfoDTO
dataDTO
=
new
ExecutedCaseInfoDTO
();
dataDTO
.
setSortIndex
(
dataIndex
+
1
);
dataDTO
.
setSortIndex
(
dataIndex
+
1
);
if
(
dataIndex
<
selectDataList
.
size
())
{
if
(
dataIndex
<
selectDataList
.
size
())
{
ExecutedCaseInfoResult
selectData
=
selectDataList
.
get
(
dataIndex
);
dataDTO
.
setCaseName
(
selectData
.
getCaseName
());
dataDTO
.
setTestPlan
(
selectData
.
getTestPlan
());
dataDTO
.
setFailureTimes
(
selectData
.
getFailureTimes
());
dataDTO
.
setCaseType
(
selectData
.
getCaseType
());
}
else
{
}
else
{
dataDTO
.
setCaseName
(
""
);
dataDTO
.
setTestPlan
(
""
);
}
returnList
.
add
(
dataDTO
);
}
return
returnList
;
return
returnList
;
}
@GetMapping
(
"/runningTask/{projectID}"
)
...
...
@@ -343,11 +356,11 @@ public class APITestController {
for
(
TaskInfoResult
taskInfo
:
resultList
)
{
Date
nextExecutionTime
=
CronUtils
.
getNextTriggerTime
(
taskInfo
.
getRule
());
if
(
nextExecutionTime
!=
null
)
{
if
(
nextExecutionTime
!=
null
)
{
taskInfo
.
setNextExecutionTime
(
nextExecutionTime
.
getTime
());
}
}
return
resultList
;
return
resultList
;
}
@PostMapping
(
value
=
"/schedule/updateEnableByPrimyKey"
)
...
...
@@ -356,4 +369,17 @@ public class APITestController {
schedule
.
setEnable
(
request
.
isEnable
());
apiAutomationService
.
updateSchedule
(
schedule
);
}
@PostMapping
(
value
=
"/genPerformanceTest"
,
consumes
=
{
"multipart/form-data"
})
public
String
genPerformanceTest
(
@RequestPart
(
"request"
)
RunDefinitionRequest
runRequest
,
@RequestPart
(
value
=
"files"
)
List
<
MultipartFile
>
bodyFiles
)
{
SaveTestPlanRequest
request
=
new
SaveTestPlanRequest
();
request
.
setName
(
runRequest
.
getName
());
request
.
setProjectId
(
runRequest
.
getProjectId
());
request
.
setAdvancedConfiguration
(
"{\"timeout\":2000,\"responseTimeout\":0,\"statusCode\":[],\"params\":[],\"domains\":[]}"
);
request
.
setLoadConfiguration
(
"[]"
);
HashTree
hashTree
=
runRequest
.
getTestElement
().
generateHashTree
();
String
jmxString
=
runRequest
.
getTestElement
().
getJmx
(
hashTree
);
String
testID
=
performanceTestService
.
save
(
request
,
jmxString
.
getBytes
());
return
testID
;
}
}
backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java
浏览文件 @
8e5105d5
package
io.metersphere.api.controller
;
import
com.alibaba.fastjson.JSON
;
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
com.github.pagehelper.Page
;
import
com.github.pagehelper.PageHelper
;
import
io.metersphere.api.dto.automation.*
;
import
io.metersphere.api.dto.definition.RunDefinitionRequest
;
import
io.metersphere.api.dto.definition.request.*
;
import
io.metersphere.api.dto.scenario.KeyValue
;
import
io.metersphere.api.service.ApiAutomationService
;
import
io.metersphere.base.domain.ApiScenario
;
import
io.metersphere.base.domain.ApiScenarioWithBLOBs
;
import
io.metersphere.base.domain.Schedule
;
import
io.metersphere.commons.constants.ReportTriggerMode
;
import
io.metersphere.commons.constants.RoleConstants
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.LogUtil
;
import
io.metersphere.commons.utils.PageUtils
;
import
io.metersphere.commons.utils.Pager
;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.i18n.Translator
;
import
io.metersphere.performance.service.PerformanceTestService
;
import
io.metersphere.track.request.testcase.ApiCaseRelevanceRequest
;
import
io.metersphere.track.request.testplan.SaveTestPlanRequest
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.jmeter.save.SaveService
;
import
org.apache.jorphan.collections.HashTree
;
import
org.apache.jorphan.collections.ListedHashTree
;
import
org.apache.shiro.authz.annotation.Logical
;
import
org.apache.shiro.authz.annotation.RequiresRoles
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.io.ByteArrayOutputStream
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.UUID
;
@RestController
@RequestMapping
(
value
=
"/api/automation"
)
...
...
@@ -28,6 +48,8 @@ public class ApiAutomationController {
@Resource
ApiAutomationService
apiAutomationService
;
@Resource
PerformanceTestService
performanceTestService
;
@PostMapping
(
"/list/{goPage}/{pageSize}"
)
...
...
@@ -121,5 +143,12 @@ public class ApiAutomationController {
public
void
createSchedule
(
@RequestBody
Schedule
request
)
{
apiAutomationService
.
createSchedule
(
request
);
}
//一键创建性能测试
@PostMapping
(
value
=
"/genPerformanceTest"
)
public
String
genPerformanceTest
(
@RequestBody
RunScenarioRequest
runRequest
)
{
runRequest
.
setExecuteType
(
ExecuteType
.
Completed
.
name
());
return
apiAutomationService
.
genPerformanceTest
(
runRequest
);
}
}
backend/src/main/java/io/metersphere/api/controller/ApiTestCaseController.java
浏览文件 @
8e5105d5
...
...
@@ -34,6 +34,19 @@ public class ApiTestCaseController {
return
apiTestCaseService
.
list
(
request
);
}
@GetMapping
(
"/findById/{id}"
)
public
ApiTestCaseResult
single
(
@PathVariable
String
id
)
{
ApiTestCaseRequest
request
=
new
ApiTestCaseRequest
();
request
.
setWorkspaceId
(
SessionUtils
.
getCurrentWorkspaceId
());
request
.
setId
(
id
);
List
<
ApiTestCaseResult
>
list
=
apiTestCaseService
.
list
(
request
);
if
(!
list
.
isEmpty
()){
return
list
.
get
(
0
);
}
else
{
return
null
;
}
}
@PostMapping
(
"/list/{goPage}/{pageSize}"
)
public
Pager
<
List
<
ApiTestCaseDTO
>>
listSimple
(
@PathVariable
int
goPage
,
@PathVariable
int
pageSize
,
@RequestBody
ApiTestCaseRequest
request
)
{
Page
<
Object
>
page
=
PageHelper
.
startPage
(
goPage
,
pageSize
,
true
);
...
...
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
浏览文件 @
8e5105d5
...
...
@@ -24,19 +24,23 @@ import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
import
io.metersphere.commons.constants.*
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.DateUtils
;
import
io.metersphere.commons.utils.LogUtil
;
import
io.metersphere.commons.utils.ServiceUtils
;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.i18n.Translator
;
import
io.metersphere.job.sechedule.ApiScenarioTestJob
;
import
io.metersphere.performance.service.PerformanceTestService
;
import
io.metersphere.service.ScheduleService
;
import
io.metersphere.track.dto.TestPlanDTO
;
import
io.metersphere.track.request.testcase.ApiCaseRelevanceRequest
;
import
io.metersphere.track.request.testcase.QueryTestPlanRequest
;
import
io.metersphere.track.request.testplan.SaveTestPlanRequest
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.ibatis.session.ExecutorType
;
import
org.apache.ibatis.session.SqlSession
;
import
org.apache.ibatis.session.SqlSessionFactory
;
import
org.apache.jmeter.save.SaveService
;
import
org.apache.jorphan.collections.HashTree
;
import
org.apache.jorphan.collections.ListedHashTree
;
import
org.springframework.stereotype.Service
;
...
...
@@ -44,6 +48,7 @@ import org.springframework.transaction.annotation.Transactional;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.io.ByteArrayOutputStream
;
import
java.util.*
;
import
java.util.stream.Collectors
;
...
...
@@ -72,6 +77,8 @@ public class ApiAutomationService {
SqlSessionFactory
sqlSessionFactory
;
@Resource
private
ApiScenarioReportMapper
apiScenarioReportMapper
;
@Resource
private
PerformanceTestService
performanceTestService
;
public
List
<
ApiScenarioDTO
>
list
(
ApiScenarioRequest
request
)
{
request
.
setOrders
(
ServiceUtils
.
getDefaultOrder
(
request
.
getOrders
()));
...
...
@@ -538,4 +545,144 @@ public class ApiAutomationService {
scheduleService
.
addOrUpdateCronJob
(
request
,
ApiScenarioTestJob
.
getJobKey
(
request
.
getResourceId
()),
ApiScenarioTestJob
.
getTriggerKey
(
request
.
getResourceId
()),
ApiScenarioTestJob
.
class
);
}
public
String
genPerformanceTest1
(
RunScenarioRequest
runRequest
)
{
SaveTestPlanRequest
request
=
new
SaveTestPlanRequest
();
request
.
setName
(
runRequest
.
getName
());
request
.
setProjectId
(
runRequest
.
getProjectId
());
request
.
setAdvancedConfiguration
(
"{\"timeout\":2000,\"responseTimeout\":0,\"statusCode\":[],\"params\":[],\"domains\":[]}"
);
request
.
setLoadConfiguration
(
"[]"
);
List
<
String
>
ids
=
runRequest
.
getScenarioIds
();
if
(
runRequest
.
isSelectAllDate
())
{
ids
=
this
.
getAllScenarioIdsByFontedSelect
(
runRequest
.
getModuleIds
(),
request
.
getName
(),
request
.
getProjectId
(),
runRequest
.
getFilters
(),
runRequest
.
getUnSelectIds
());
}
List
<
ApiScenarioWithBLOBs
>
apiScenarios
=
extApiScenarioMapper
.
selectIds
(
ids
);
MsTestPlan
testPlan
=
new
MsTestPlan
();
testPlan
.
setHashTree
(
new
LinkedList
<>());
HashTree
jmeterHashTree
=
new
ListedHashTree
();
try
{
boolean
isFirst
=
true
;
for
(
ApiScenarioWithBLOBs
item
:
apiScenarios
)
{
if
(
item
.
getStepTotal
()
==
0
)
{
MSException
.
throwException
(
item
.
getName
()
+
","
+
Translator
.
get
(
"automation_exec_info"
));
break
;
}
MsThreadGroup
group
=
new
MsThreadGroup
();
group
.
setLabel
(
item
.
getName
());
group
.
setName
(
UUID
.
randomUUID
().
toString
());
// 批量执行的结果直接存储为报告
if
(
isFirst
)
{
group
.
setName
(
request
.
getId
());
isFirst
=
false
;
}
ObjectMapper
mapper
=
new
ObjectMapper
();
mapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
JSONObject
element
=
JSON
.
parseObject
(
item
.
getScenarioDefinition
());
MsScenario
scenario
=
JSONObject
.
parseObject
(
item
.
getScenarioDefinition
(),
MsScenario
.
class
);
// 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取
if
(
element
!=
null
&&
StringUtils
.
isNotEmpty
(
element
.
getString
(
"hashTree"
)))
{
LinkedList
<
MsTestElement
>
elements
=
mapper
.
readValue
(
element
.
getString
(
"hashTree"
),
new
TypeReference
<
LinkedList
<
MsTestElement
>>()
{
});
scenario
.
setHashTree
(
elements
);
}
if
(
StringUtils
.
isNotEmpty
(
element
.
getString
(
"variables"
)))
{
LinkedList
<
KeyValue
>
variables
=
mapper
.
readValue
(
element
.
getString
(
"variables"
),
new
TypeReference
<
LinkedList
<
KeyValue
>>()
{
});
scenario
.
setVariables
(
variables
);
}
group
.
setEnableCookieShare
(
scenario
.
isEnableCookieShare
());
LinkedList
<
MsTestElement
>
scenarios
=
new
LinkedList
<>();
scenarios
.
add
(
scenario
);
// 创建场景报告
// createScenarioReport(group.getName(), item.getId(), item.getName(), runRequest.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : runRequest.getTriggerMode(),
// runRequest.getExecuteType(), item.getProjectId(), runRequest.getReportUserID());
group
.
setHashTree
(
scenarios
);
testPlan
.
getHashTree
().
add
(
group
);
}
}
catch
(
Exception
ex
)
{
MSException
.
throwException
(
ex
.
getMessage
());
}
testPlan
.
toHashTree
(
jmeterHashTree
,
testPlan
.
getHashTree
(),
new
ParameterConfig
());
String
jmxString
=
testPlan
.
getJmx
(
jmeterHashTree
);
String
testID
=
performanceTestService
.
save
(
request
,
jmxString
.
getBytes
());
return
testID
;
}
public
String
genPerformanceTest
(
RunScenarioRequest
request
)
{
List
<
ApiScenarioWithBLOBs
>
apiScenarios
=
null
;
List
<
String
>
ids
=
request
.
getScenarioIds
();
if
(
request
.
isSelectAllDate
())
{
ids
=
this
.
getAllScenarioIdsByFontedSelect
(
request
.
getModuleIds
(),
request
.
getName
(),
request
.
getProjectId
(),
request
.
getFilters
(),
request
.
getUnSelectIds
());
}
apiScenarios
=
extApiScenarioMapper
.
selectIds
(
ids
);
MsTestPlan
testPlan
=
new
MsTestPlan
();
testPlan
.
setHashTree
(
new
LinkedList
<>());
HashTree
jmeterHashTree
=
new
ListedHashTree
();
try
{
boolean
isFirst
=
true
;
for
(
ApiScenarioWithBLOBs
item
:
apiScenarios
)
{
if
(
item
.
getStepTotal
()
==
0
)
{
MSException
.
throwException
(
item
.
getName
()
+
","
+
Translator
.
get
(
"automation_exec_info"
));
break
;
}
MsThreadGroup
group
=
new
MsThreadGroup
();
group
.
setLabel
(
item
.
getName
());
group
.
setName
(
UUID
.
randomUUID
().
toString
());
// 批量执行的结果直接存储为报告
if
(
isFirst
)
{
group
.
setName
(
request
.
getId
());
isFirst
=
false
;
}
ObjectMapper
mapper
=
new
ObjectMapper
();
mapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
JSONObject
element
=
JSON
.
parseObject
(
item
.
getScenarioDefinition
());
MsScenario
scenario
=
JSONObject
.
parseObject
(
item
.
getScenarioDefinition
(),
MsScenario
.
class
);
// 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取
if
(
element
!=
null
&&
StringUtils
.
isNotEmpty
(
element
.
getString
(
"hashTree"
)))
{
LinkedList
<
MsTestElement
>
elements
=
mapper
.
readValue
(
element
.
getString
(
"hashTree"
),
new
TypeReference
<
LinkedList
<
MsTestElement
>>()
{
});
scenario
.
setHashTree
(
elements
);
}
if
(
StringUtils
.
isNotEmpty
(
element
.
getString
(
"variables"
)))
{
LinkedList
<
KeyValue
>
variables
=
mapper
.
readValue
(
element
.
getString
(
"variables"
),
new
TypeReference
<
LinkedList
<
KeyValue
>>()
{
});
scenario
.
setVariables
(
variables
);
}
group
.
setEnableCookieShare
(
scenario
.
isEnableCookieShare
());
LinkedList
<
MsTestElement
>
scenarios
=
new
LinkedList
<>();
scenarios
.
add
(
scenario
);
group
.
setHashTree
(
scenarios
);
testPlan
.
getHashTree
().
add
(
group
);
}
}
catch
(
Exception
ex
)
{
MSException
.
throwException
(
ex
.
getMessage
());
}
testPlan
.
toHashTree
(
jmeterHashTree
,
testPlan
.
getHashTree
(),
new
ParameterConfig
());
String
jmx
=
testPlan
.
getJmx
(
jmeterHashTree
);
SaveTestPlanRequest
saveRequest
=
new
SaveTestPlanRequest
();
saveRequest
.
setName
(
request
.
getName
());
saveRequest
.
setProjectId
(
request
.
getProjectId
());
saveRequest
.
setAdvancedConfiguration
(
"{\"timeout\":2000,\"responseTimeout\":0,\"statusCode\":[],\"params\":[],\"domains\":[]}"
);
saveRequest
.
setLoadConfiguration
(
"[]"
);
String
testID
=
performanceTestService
.
save
(
saveRequest
,
jmx
.
getBytes
());
return
testID
;
}
}
backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java
浏览文件 @
8e5105d5
...
...
@@ -127,9 +127,7 @@ public class PerformanceTestService {
if
(
files
==
null
)
{
throw
new
IllegalArgumentException
(
Translator
.
get
(
"file_cannot_be_null"
));
}
checkQuota
(
request
,
true
);
final
LoadTestWithBLOBs
loadTest
=
saveLoadTest
(
request
);
files
.
forEach
(
file
->
{
final
FileMetadata
fileMetadata
=
fileService
.
saveFile
(
file
);
...
...
@@ -141,6 +139,20 @@ public class PerformanceTestService {
return
loadTest
.
getId
();
}
public
String
save
(
SaveTestPlanRequest
request
,
byte
[]
file
)
{
if
(
file
==
null
)
{
throw
new
IllegalArgumentException
(
Translator
.
get
(
"file_cannot_be_null"
));
}
checkQuota
(
request
,
true
);
final
LoadTestWithBLOBs
loadTest
=
saveLoadTest
(
request
);
final
FileMetadata
fileMetadata
=
fileService
.
saveFile
(
file
,
request
.
getName
()
+
".JMX"
,
new
Long
(
file
.
length
));
LoadTestFile
loadTestFile
=
new
LoadTestFile
();
loadTestFile
.
setTestId
(
loadTest
.
getId
());
loadTestFile
.
setFileId
(
fileMetadata
.
getId
());
loadTestFileMapper
.
insert
(
loadTestFile
);
return
loadTest
.
getId
();
}
private
LoadTestWithBLOBs
saveLoadTest
(
SaveTestPlanRequest
request
)
{
LoadTestExample
example
=
new
LoadTestExample
();
...
...
backend/src/main/java/io/metersphere/service/FileService.java
浏览文件 @
8e5105d5
...
...
@@ -107,6 +107,25 @@ public class FileService {
return
fileMetadata
;
}
public
FileMetadata
saveFile
(
byte
[]
fileByte
,
String
fileName
,
Long
fileSize
)
{
final
FileMetadata
fileMetadata
=
new
FileMetadata
();
fileMetadata
.
setId
(
UUID
.
randomUUID
().
toString
());
fileMetadata
.
setName
(
fileName
);
fileMetadata
.
setSize
(
fileSize
);
fileMetadata
.
setCreateTime
(
System
.
currentTimeMillis
());
fileMetadata
.
setUpdateTime
(
System
.
currentTimeMillis
());
FileType
fileType
=
getFileType
(
fileMetadata
.
getName
());
fileMetadata
.
setType
(
fileType
.
name
());
fileMetadataMapper
.
insert
(
fileMetadata
);
FileContent
fileContent
=
new
FileContent
();
fileContent
.
setFileId
(
fileMetadata
.
getId
());
fileContent
.
setFile
(
fileByte
);
fileContentMapper
.
insert
(
fileContent
);
return
fileMetadata
;
}
public
FileMetadata
copyFile
(
String
fileId
)
{
FileMetadata
fileMetadata
=
fileMetadataMapper
.
selectByPrimaryKey
(
fileId
);
FileContent
fileContent
=
getFileContent
(
fileId
);
...
...
frontend/src/business/components/api/automation/scenario/ScenarioExtendBtns.vue
浏览文件 @
8e5105d5
...
...
@@ -6,6 +6,7 @@
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
command=
"ref"
>
{{
$t
(
'
api_test.automation.view_ref
'
)
}}
</el-dropdown-item>
<el-dropdown-item
command=
"schedule"
v-tester
>
{{
$t
(
'
api_test.automation.schedule
'
)
}}
</el-dropdown-item>
<el-dropdown-item
command=
"create_performance"
v-tester
>
{{
$t
(
'
api_test.create_performance_test
'
)
}}
</el-dropdown-item>
</el-dropdown-menu>
<ms-reference-view
ref=
"viewRef"
/>
<ms-schedule-maintain
ref=
"scheduleMaintain"
/>
...
...
@@ -15,6 +16,7 @@
<
script
>
import
MsReferenceView
from
"
@/business/components/api/automation/scenario/ReferenceView
"
;
import
MsScheduleMaintain
from
"
@/business/components/api/automation/schedule/ScheduleMaintain
"
import
{
getCurrentProjectID
,
getUUID
}
from
"
@/common/js/utils
"
;
export
default
{
name
:
"
MsScenarioExtendButtons
"
,
...
...
@@ -31,8 +33,30 @@
case
"
schedule
"
:
this
.
$refs
.
scheduleMaintain
.
open
(
this
.
row
);
break
;
case
"
create_performance
"
:
this
.
createPerformance
(
this
.
row
);
break
;
}
},
createPerformance
(
row
)
{
this
.
infoDb
=
false
;
let
url
=
"
/api/automation/genPerformanceTest
"
;
let
run
=
{};
let
scenarioIds
=
[];
scenarioIds
.
push
(
row
.
id
);
run
.
projectId
=
getCurrentProjectID
();
run
.
scenarioIds
=
scenarioIds
;
run
.
id
=
getUUID
();
run
.
name
=
row
.
name
;
this
.
$post
(
url
,
run
,
response
=>
{
let
performanceId
=
response
.
data
;
if
(
performanceId
!=
null
){
this
.
$router
.
push
({
path
:
"
/performance/test/edit/
"
+
performanceId
,
})
}
});
},
}
}
</
script
>
...
...
frontend/src/business/components/api/definition/components/basis/SetEnvironment.vue
0 → 100644
浏览文件 @
8e5105d5
<
template
>
<div>
<el-dialog
:title=
"$t('api_test.environment.select_environment')"
:visible.sync=
"dialogVisible"
width=
"25%"
:destroy-on-close=
"true"
@
close=
"handleClose"
>
<el-form
label-position=
"right"
label-width=
"150px"
size=
"medium"
ref=
"form"
>
<el-form-item
prop=
"type"
>
<el-select
v-model=
"environmentId"
value-key=
"id"
size=
"small"
class=
"ms-htt-width"
:placeholder=
"$t('api_test.definition.request.run_env')"
clearable
>
<el-option
v-for=
"(environment, index) in environments"
:key=
"index"
:label=
"environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
:value=
"environment.id"
/>
<template
v-slot:empty
>
<div
class=
"empty-environment"
>
</div>
</
template
>
</el-select>
</el-form-item>
</el-form>
<
template
v-slot:footer
>
<!--
<el-button
onclick=
"this.handleClose"
>
{{
$t
(
'
commons.cancel
'
)
}}
</el-button>
-->
<el-button
type=
"primary"
@
click=
"createPerformance"
@
keydown.enter.native.prevent
>
{{
$t
(
'
commons.confirm
'
)
}}
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
script
>
import
{
listenGoBack
,
removeGoBackListener
}
from
"
@/common/js/utils
"
;
import
{
parseEnvironment
}
from
"
@/business/components/api/test/model/EnvironmentModel
"
;
import
{
getUUID
,
getCurrentProjectID
}
from
"
@/common/js/utils
"
;
export
default
{
name
:
"
MsSetEnvironment
"
,
components
:
{},
props
:
{
testCase
:
Object
,
row
:
Object
,
},
data
()
{
return
{
dialogVisible
:
false
,
filterable
:
false
,
environments
:
[],
environmentId
:
""
,
dialogTitle
:
{
type
:
String
,
default
()
{
return
this
.
$t
(
'
api_test.environment.select_environment
'
)
}
}
}
},
watch
:
{
environmentId
()
{
this
.
environmentChange
(
this
.
environmentId
);
},
},
methods
:
{
environmentChange
(
value
)
{
for
(
let
i
in
this
.
environments
)
{
if
(
this
.
environments
[
i
].
id
===
value
)
{
this
.
environment
=
this
.
environments
[
i
];
break
;
}
}
},
getEnvironments
()
{
let
selectProjectId
=
getCurrentProjectID
();
if
(
selectProjectId
)
{
this
.
$get
(
'
/api/environment/list/
'
+
selectProjectId
,
response
=>
{
this
.
environments
=
response
.
data
;
this
.
environments
.
forEach
(
environment
=>
{
parseEnvironment
(
environment
);
});
});
}
else
{
this
.
environment
=
undefined
;
}
},
open
()
{
this
.
dialogVisible
=
true
;
this
.
getEnvironments
();
listenGoBack
(
this
.
handleClose
);
},
handleClose
()
{
this
.
form
=
{};
this
.
options
=
[];
removeGoBackListener
(
this
.
handleClose
);
},
createPerformance
()
{
this
.
$get
(
'
/api/testcase/findById/
'
+
this
.
testCase
.
id
,
response
=>
{
let
testCaseInfo
=
response
.
data
;
if
(
testCaseInfo
!=
null
){
this
.
$emit
(
"
createPerformance
"
,
testCaseInfo
,
this
.
environment
);
}
});
},
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/api/definition/components/case/ApiCaseItem.vue
浏览文件 @
8e5105d5
...
...
@@ -40,7 +40,7 @@
size=
"mini"
:disabled=
"!apiCase.id || isCaseEdit"
circle
v-tester
/>
<ms-tip-button
@
click=
"deleteCase(index,apiCase)"
:tip=
"$t('commons.delete')"
icon=
"el-icon-delete"
size=
"mini"
:disabled=
"!apiCase.id || isCaseEdit"
circle
v-tester
/>
<ms-api-extend-btns
:is-case-edit=
"isCaseEdit"
:row=
"apiCase"
v-tester
/>
<ms-api-extend-btns
:is-case-edit=
"isCaseEdit"
:
environment=
"environment"
:
row=
"apiCase"
v-tester
/>
</el-col>
<el-col
:span=
"3"
>
...
...
@@ -102,7 +102,6 @@
return
{
result
:
{},
grades
:
[],
environment
:
{},
isReadOnly
:
false
,
selectedEvent
:
Object
,
priorities
:
PRIORITY
,
...
...
@@ -121,6 +120,7 @@
return
{}
}
},
environment
:
{},
index
:
{
type
:
Number
,
default
()
{
...
...
frontend/src/business/components/api/definition/components/case/ApiCaseList.vue
浏览文件 @
8e5105d5
...
...
@@ -25,6 +25,7 @@
@
singleRun=
"singleRun"
@
copyCase=
"copyCase"
@
showExecResult=
"showExecResult"
:environment=
"environment"
:is-case-edit=
"isCaseEdit"
:api=
"api"
:api-case=
"item"
:index=
"index"
/>
...
...
frontend/src/business/components/api/definition/components/list/ApiCaseSimpleList.vue
浏览文件 @
8e5105d5
此差异已折叠。
点击以展开。
frontend/src/business/components/api/definition/components/reference/ApiCaseTableExtendBtns.vue
0 → 100644
浏览文件 @
8e5105d5
<
template
>
<el-dropdown
@
command=
"handleCommand"
class=
"scenario-ext-btn"
>
<el-link
type=
"primary"
:underline=
"false"
>
<el-icon
class=
"el-icon-more"
></el-icon>
</el-link>
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
command=
"ref"
>
{{
$t
(
'
api_test.automation.view_ref
'
)
}}
</el-dropdown-item>
<el-dropdown-item
command=
"create_performance"
>
{{
$t
(
'
api_test.create_performance_test
'
)
}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</
template
>
<
script
>
export
default
{
name
:
"
MsApiCaseTableExtendBtns
"
,
components
:
{},
props
:
{
row
:
Object
,
},
data
()
{
return
{
planVisible
:
false
,
}
},
methods
:
{
handleCommand
(
cmd
)
{
if
(
this
.
row
.
id
)
{
switch
(
cmd
)
{
case
"
ref
"
:
this
.
$emit
(
"
showCaseRef
"
,
this
.
row
);
break
;
case
"
create_performance
"
:
this
.
$emit
(
"
showEnvironment
"
,
this
.
row
);
break
;
}
}
else
{
this
.
$warning
(
this
.
$t
(
'
api_test.automation.save_case_info
'
))
}
},
createPerformance
(
row
,
environment
)
{
this
.
$emit
(
"
createPerformance
"
,
row
,
environment
);
}
}
}
</
script
>
<
style
scoped
>
.scenario-ext-btn
{
margin-left
:
10px
;
}
</
style
>
frontend/src/business/components/api/definition/components/reference/ApiExtendBtns.vue
浏览文件 @
8e5105d5
...
...
@@ -6,6 +6,7 @@
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
command=
"ref"
>
{{
$t
(
'
api_test.automation.view_ref
'
)
}}
</el-dropdown-item>
<el-dropdown-item
:disabled=
"isCaseEdit"
command=
"add_plan"
>
{{
$t
(
'
api_test.automation.batch_add_plan
'
)
}}
</el-dropdown-item>
<el-dropdown-item
:disabled=
"isCaseEdit"
command=
"create_performance"
>
{{
$t
(
'
api_test.create_performance_test
'
)
}}
</el-dropdown-item>
</el-dropdown-menu>
<ms-reference-view
ref=
"viewRef"
/>
<!--测试计划-->
...
...
@@ -18,6 +19,9 @@
<
script
>
import
MsReferenceView
from
"
./ReferenceView
"
;
import
MsTestPlanList
from
"
../../../automation/scenario/testplan/TestPlanList
"
;
import
{
getBodyUploadFiles
,
getCurrentProjectID
,
getUUID
}
from
"
@/common/js/utils
"
;
import
TestPlan
from
"
@/business/components/api/definition/components/jmeter/components/test-plan
"
;
import
ThreadGroup
from
"
@/business/components/api/definition/components/jmeter/components/thread-group
"
;
export
default
{
name
:
"
MsApiExtendBtns
"
,
...
...
@@ -25,6 +29,7 @@
props
:
{
row
:
Object
,
isCaseEdit
:
Boolean
,
environment
:
{},
},
data
()
{
return
{
...
...
@@ -42,11 +47,62 @@
case
"
add_plan
"
:
this
.
addCaseToPlan
();
break
;
case
"
create_performance
"
:
this
.
createPerformance
(
this
.
row
);
break
;
}
}
else
{
this
.
$warning
(
this
.
$t
(
'
api_test.automation.save_case_info
'
))
}
},
createPerformance
(
row
){
/**
* 思路:调用后台创建性能测试的方法,把当前案例的hashTree在后台转化为jmx并文件创建性能测试。
* 然后跳转到修改性能测试的页面
*
* 性能测试保存地址: performance/save
*
*/
if
(
!
this
.
environment
||
!
this
.
environment
)
{
this
.
$warning
(
this
.
$t
(
'
api_test.environment.select_environment
'
));
return
;
}
this
.
runData
=
[];
this
.
singleLoading
=
true
;
this
.
row
.
request
.
name
=
this
.
row
.
id
;
this
.
row
.
request
.
useEnvironment
=
this
.
environment
.
id
;
this
.
runData
.
push
(
this
.
row
.
request
);
/*触发执行操作*/
let
testPlan
=
new
TestPlan
();
let
threadGroup
=
new
ThreadGroup
();
threadGroup
.
hashTree
=
[];
testPlan
.
hashTree
=
[
threadGroup
];
this
.
runData
.
forEach
(
item
=>
{
threadGroup
.
hashTree
.
push
(
item
);
})
let
reqObj
=
{
id
:
this
.
row
.
id
,
testElement
:
testPlan
,
type
:
this
.
type
,
name
:
this
.
row
.
name
,
projectId
:
getCurrentProjectID
(),
};
let
bodyFiles
=
getBodyUploadFiles
(
reqObj
,
this
.
runData
);
reqObj
.
reportId
=
"
run
"
;
let
url
=
"
/api/genPerformanceTest
"
;
this
.
$fileUpload
(
url
,
null
,
bodyFiles
,
reqObj
,
response
=>
{
let
performanceId
=
response
.
data
;
if
(
performanceId
!=
null
){
this
.
$router
.
push
({
path
:
"
/performance/test/edit/
"
+
performanceId
,
})
}
},
erro
=>
{
this
.
$emit
(
'
runRefresh
'
,
{});
});
},
addCaseToPlan
()
{
this
.
planVisible
=
true
;
},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录