Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
8d152a07
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,发现更多精彩内容 >>
提交
8d152a07
编写于
1月 13, 2021
作者:
S
song.tianyang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(测试计划增加定时任务、增加测试报告查看页面):
测试计划增加定时任务、增加测试报告查看页面
上级
4069654f
变更
47
展开全部
隐藏空白更改
内联
并排
Showing
47 changed file
with
3972 addition
and
160 deletion
+3972
-160
backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java
...io/metersphere/api/dto/automation/RunScenarioRequest.java
+3
-0
backend/src/main/java/io/metersphere/api/dto/automation/SchedulePlanScenarioExecuteRequest.java
...pi/dto/automation/SchedulePlanScenarioExecuteRequest.java
+38
-0
backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java
...a/io/metersphere/api/jmeter/APIBackendListenerClient.java
+19
-3
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
...java/io/metersphere/api/service/ApiAutomationService.java
+106
-22
backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java
...tersphere/api/service/ApiDefinitionExecResultService.java
+38
-0
backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
...java/io/metersphere/api/service/ApiDefinitionService.java
+5
-51
backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java
.../io/metersphere/api/service/ApiScenarioReportService.java
+66
-0
backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java
...n/java/io/metersphere/api/service/ApiTestCaseService.java
+58
-37
backend/src/main/java/io/metersphere/base/domain/TestPlanReport.java
.../main/java/io/metersphere/base/domain/TestPlanReport.java
+37
-0
backend/src/main/java/io/metersphere/base/domain/TestPlanReportData.java
...n/java/io/metersphere/base/domain/TestPlanReportData.java
+13
-0
backend/src/main/java/io/metersphere/base/domain/TestPlanReportDataExample.java
...io/metersphere/base/domain/TestPlanReportDataExample.java
+340
-0
backend/src/main/java/io/metersphere/base/domain/TestPlanReportDataWithBLOBs.java
.../metersphere/base/domain/TestPlanReportDataWithBLOBs.java
+27
-0
backend/src/main/java/io/metersphere/base/domain/TestPlanReportExample.java
...ava/io/metersphere/base/domain/TestPlanReportExample.java
+1110
-0
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportDataMapper.java
.../io/metersphere/base/mapper/TestPlanReportDataMapper.java
+37
-0
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportDataMapper.xml
...a/io/metersphere/base/mapper/TestPlanReportDataMapper.xml
+312
-0
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.java
...java/io/metersphere/base/mapper/TestPlanReportMapper.java
+30
-0
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.xml
.../java/io/metersphere/base/mapper/TestPlanReportMapper.xml
+354
-0
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.java
...metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.java
+2
-0
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.xml
.../metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.xml
+3
-0
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.java
...ava/io/metersphere/base/mapper/ext/ExtTestPlanMapper.java
+6
-0
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.xml
...java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.xml
+15
-0
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.java
.../metersphere/base/mapper/ext/ExtTestPlanReportMapper.java
+16
-0
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml
...o/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml
+33
-0
backend/src/main/java/io/metersphere/commons/constants/ApiRunMode.java
...ain/java/io/metersphere/commons/constants/ApiRunMode.java
+1
-1
backend/src/main/java/io/metersphere/job/sechedule/TestPlanTestJob.java
...in/java/io/metersphere/job/sechedule/TestPlanTestJob.java
+87
-41
backend/src/main/java/io/metersphere/track/controller/TestPlanReportController.java
...etersphere/track/controller/TestPlanReportController.java
+55
-0
backend/src/main/java/io/metersphere/track/dto/TestPlanReportDTO.java
...main/java/io/metersphere/track/dto/TestPlanReportDTO.java
+33
-0
backend/src/main/java/io/metersphere/track/request/report/QueryTestPlanReportRequest.java
...here/track/request/report/QueryTestPlanReportRequest.java
+29
-0
backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java
.../io/metersphere/track/service/TestPlanApiCaseService.java
+8
-0
backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseEvent.java
...a/io/metersphere/track/service/TestPlanLoadCaseEvent.java
+32
-0
backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java
...a/io/metersphere/track/service/TestPlanReportService.java
+407
-0
backend/src/main/java/io/metersphere/track/service/TestPlanService.java
...in/java/io/metersphere/track/service/TestPlanService.java
+8
-0
backend/src/main/resources/db/migration/V66__init_test_plan_report.sql
...ain/resources/db/migration/V66__init_test_plan_report.sql
+43
-0
frontend/package.json
frontend/package.json
+3
-3
frontend/src/business/components/common/components/search/search-components.js
.../components/common/components/search/search-components.js
+26
-0
frontend/src/business/components/track/head/TrackHeaderMenus.vue
...d/src/business/components/track/head/TrackHeaderMenus.vue
+4
-0
frontend/src/business/components/track/plan/components/TestPlanList.vue
...usiness/components/track/plan/components/TestPlanList.vue
+1
-1
frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiScenarioList.vue
...track/plan/view/comonents/api/TestPlanApiScenarioList.vue
+3
-1
frontend/src/business/components/track/report/TestPlanReport.vue
...d/src/business/components/track/report/TestPlanReport.vue
+45
-0
frontend/src/business/components/track/report/components/TestPlanReportExport.vue
...mponents/track/report/components/TestPlanReportExport.vue
+34
-0
frontend/src/business/components/track/report/components/TestPlanReportList.vue
...components/track/report/components/TestPlanReportList.vue
+161
-0
frontend/src/business/components/track/report/components/TestPlanReportView.vue
...components/track/report/components/TestPlanReportView.vue
+266
-0
frontend/src/business/components/track/router.js
frontend/src/business/components/track/router.js
+7
-0
frontend/src/i18n/en-US.js
frontend/src/i18n/en-US.js
+16
-0
frontend/src/i18n/zh-CN.js
frontend/src/i18n/zh-CN.js
+16
-0
frontend/src/i18n/zh-TW.js
frontend/src/i18n/zh-TW.js
+16
-0
package-lock.json
package-lock.json
+3
-0
未找到文件。
backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java
浏览文件 @
8d152a07
...
...
@@ -23,6 +23,9 @@ public class RunScenarioRequest {
private
String
runMode
;
//测试情景和测试计划的关联ID
private
String
planScenarioId
;
private
List
<
String
>
planCaseIds
;
private
String
reportUserID
;
...
...
backend/src/main/java/io/metersphere/api/dto/automation/SchedulePlanScenarioExecuteRequest.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.api.dto.automation
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.util.List
;
import
java.util.Map
;
@Setter
@Getter
public
class
SchedulePlanScenarioExecuteRequest
{
private
String
id
;
private
String
reportId
;
private
String
projectId
;
private
String
environmentId
;
private
String
triggerMode
;
private
String
executeType
;
private
String
runMode
;
//测试情景和测试计划的关联ID
private
String
testPlanID
;
private
List
<
String
>
planCaseIds
;
private
String
reportUserID
;
//key: test_plan.id, value: test_plan_api_scenario <->scenarioValue
private
Map
<
String
,
Map
<
String
,
String
>>
testPlanScenarioIDMap
;
private
String
testPlanReportId
;
}
backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java
浏览文件 @
8d152a07
...
...
@@ -12,6 +12,7 @@ import io.metersphere.i18n.Translator;
import
io.metersphere.notice.sender.NoticeModel
;
import
io.metersphere.notice.service.NoticeSendService
;
import
io.metersphere.service.SystemParameterService
;
import
io.metersphere.track.service.TestPlanReportService
;
import
io.metersphere.track.service.TestPlanTestCaseService
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
...
...
@@ -48,6 +49,8 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
private
ApiDefinitionExecResultService
apiDefinitionExecResultService
;
private
TestPlanReportService
testPlanReportService
;
private
ApiScenarioReportService
apiScenarioReportService
;
...
...
@@ -92,6 +95,10 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
if
(
apiDefinitionExecResultService
==
null
)
{
LogUtil
.
error
(
"apiDefinitionExecResultService is required"
);
}
testPlanReportService
=
CommonBeanFactory
.
getBean
(
TestPlanReportService
.
class
);
if
(
testPlanReportService
==
null
)
{
LogUtil
.
error
(
"testPlanReportService is required"
);
}
apiScenarioReportService
=
CommonBeanFactory
.
getBean
(
ApiScenarioReportService
.
class
);
if
(
apiScenarioReportService
==
null
)
{
...
...
@@ -169,10 +176,19 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
apiDefinitionService
.
addResult
(
testResult
);
apiDefinitionExecResultService
.
saveApiResult
(
testResult
,
ApiRunMode
.
DELIMIT
.
name
());
}
}
else
if
(
StringUtils
.
equals
(
this
.
runMode
,
ApiRunMode
.
API_PLAN
.
name
()))
{
}
else
if
(
StringUtils
.
equals
Any
(
this
.
runMode
,
ApiRunMode
.
API_PLAN
.
name
(),
ApiRunMode
.
SCHEDULE_
API_PLAN
.
name
()))
{
apiDefinitionService
.
addResult
(
testResult
);
apiDefinitionExecResultService
.
saveApiResult
(
testResult
,
ApiRunMode
.
API_PLAN
.
name
());
}
else
if
(
StringUtils
.
equalsAny
(
this
.
runMode
,
ApiRunMode
.
SCENARIO
.
name
(),
ApiRunMode
.
SCENARIO_PLAN
.
name
()))
{
//测试计划定时任务-接口执行逻辑的话,需要同步测试计划的报告数据
if
(
StringUtils
.
equals
(
this
.
runMode
,
ApiRunMode
.
SCHEDULE_API_PLAN
.
name
()))
{
apiDefinitionExecResultService
.
saveApiResultByScheduleTask
(
testResult
,
ApiRunMode
.
SCHEDULE_API_PLAN
.
name
());
List
<
String
>
testPlanReportIdList
=
new
ArrayList
<>();
testPlanReportIdList
.
add
(
debugReportId
);
testPlanReportService
.
updateReport
(
testPlanReportIdList
,
ApiRunMode
.
SCHEDULE_API_PLAN
.
name
());
}
else
{
apiDefinitionExecResultService
.
saveApiResult
(
testResult
,
ApiRunMode
.
API_PLAN
.
name
());
}
}
else
if
(
StringUtils
.
equalsAny
(
this
.
runMode
,
ApiRunMode
.
SCENARIO
.
name
(),
ApiRunMode
.
SCENARIO_PLAN
.
name
(),
ApiRunMode
.
SCHEDULE_SCENARIO_PLAN
.
name
()))
{
// 执行报告不需要存储,由用户确认后在存储
testResult
.
setTestId
(
testId
);
ApiScenarioReport
scenarioReport
=
apiScenarioReportService
.
complete
(
testResult
,
this
.
runMode
);
...
...
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
浏览文件 @
8d152a07
...
...
@@ -416,6 +416,112 @@ public class ApiAutomationService {
jMeterService
.
runDefinition
(
request
.
getId
(),
generateHashTree
(
apiScenarios
,
request
,
true
),
request
.
getReportId
(),
runMode
);
return
request
.
getId
();
}
/**
* 测试计划的定时任务--执行场景案例
*
* @param request
* @return
*/
public
String
run
(
SchedulePlanScenarioExecuteRequest
request
)
{
MsTestPlan
testPlan
=
new
MsTestPlan
();
testPlan
.
setHashTree
(
new
LinkedList
<>());
HashTree
jmeterHashTree
=
new
ListedHashTree
();
Map
<
String
,
Map
<
String
,
String
>>
testPlanScenarioIdMap
=
request
.
getTestPlanScenarioIDMap
();
for
(
Map
.
Entry
<
String
,
Map
<
String
,
String
>>
entry
:
testPlanScenarioIdMap
.
entrySet
())
{
String
testPlanID
=
entry
.
getKey
();
Map
<
String
,
String
>
planScenarioIdMap
=
entry
.
getValue
();
List
<
ApiScenarioWithBLOBs
>
apiScenarios
=
extApiScenarioMapper
.
selectIds
(
new
ArrayList
<>(
planScenarioIdMap
.
keySet
()));
try
{
boolean
isFirst
=
true
;
for
(
ApiScenarioWithBLOBs
item
:
apiScenarios
)
{
String
apiScenarioID
=
item
.
getId
();
String
planScenarioID
=
planScenarioIdMap
.
get
(
apiScenarioID
);
if
(
StringUtils
.
isEmpty
(
planScenarioID
)){
continue
;
}
if
(
item
.
getStepTotal
()
==
0
)
{
// 只有一个场景且没有测试步骤,则提示
if
(
apiScenarios
.
size
()
==
1
)
{
MSException
.
throwException
((
item
.
getName
()
+
","
+
Translator
.
get
(
"automation_exec_info"
)));
}
LogUtil
.
warn
(
item
.
getName
()
+
","
+
Translator
.
get
(
"automation_exec_info"
));
continue
;
}
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
<
ScenarioVariable
>
variables
=
mapper
.
readValue
(
element
.
getString
(
"variables"
),
new
TypeReference
<
LinkedList
<
ScenarioVariable
>>()
{
});
scenario
.
setVariables
(
variables
);
}
group
.
setEnableCookieShare
(
scenario
.
isEnableCookieShare
());
LinkedList
<
MsTestElement
>
scenarios
=
new
LinkedList
<>();
scenarios
.
add
(
scenario
);
// 创建场景报告
//不同的运行模式,第二个参数入参不同
createScenarioReport
(
group
.
getName
(),
planScenarioID
+
":"
+
request
.
getTestPlanReportId
()
,
item
.
getName
(),
request
.
getTriggerMode
()
==
null
?
ReportTriggerMode
.
MANUAL
.
name
()
:
request
.
getTriggerMode
(),
request
.
getExecuteType
(),
item
.
getProjectId
(),
request
.
getReportUserID
());
group
.
setHashTree
(
scenarios
);
testPlan
.
getHashTree
().
add
(
group
);
}
}
catch
(
Exception
ex
)
{
MSException
.
throwException
(
ex
.
getMessage
());
}
}
testPlan
.
toHashTree
(
jmeterHashTree
,
testPlan
.
getHashTree
(),
new
ParameterConfig
());
String
runMode
=
ApiRunMode
.
SCHEDULE_SCENARIO_PLAN
.
name
();
// 调用执行方法
jMeterService
.
runDefinition
(
request
.
getId
(),
jmeterHashTree
,
request
.
getReportId
(),
runMode
);
return
request
.
getId
();
}
/**
* 获取前台查询条件查询的所有(未经分页筛选)数据ID
*
* @param moduleIds 模块ID_前台查询时所选择的
* @param name 搜索条件_名称_前台查询时所输入的
* @param projectId 所属项目_前台查询时所在项目
* @param filters 过滤集合__前台查询时的过滤条件
* @param unSelectIds 未勾选ID_前台没有勾选的ID
* @return
*/
private
List
<
String
>
getAllScenarioIdsByFontedSelect
(
List
<
String
>
moduleIds
,
String
name
,
String
projectId
,
List
<
String
>
filters
,
List
<
String
>
unSelectIds
)
{
ApiScenarioRequest
selectRequest
=
new
ApiScenarioRequest
();
selectRequest
.
setModuleIds
(
moduleIds
);
selectRequest
.
setName
(
name
);
selectRequest
.
setProjectId
(
projectId
);
selectRequest
.
setFilters
(
filters
);
selectRequest
.
setWorkspaceId
(
SessionUtils
.
getCurrentWorkspaceId
());
List
<
ApiScenarioDTO
>
list
=
extApiScenarioMapper
.
list
(
selectRequest
);
List
<
String
>
allIds
=
list
.
stream
().
map
(
ApiScenarioDTO:
:
getId
).
collect
(
Collectors
.
toList
());
List
<
String
>
ids
=
allIds
.
stream
().
filter
(
id
->
!
unSelectIds
.
contains
(
id
)).
collect
(
Collectors
.
toList
());
return
ids
;
}
/**
* 场景测试执行
*
...
...
@@ -453,28 +559,6 @@ public class ApiAutomationService {
return
dto
;
}
/**
* 获取前台查询条件查询的所有(未经分页筛选)数据ID
*
* @param moduleIds 模块ID_前台查询时所选择的
* @param name 搜索条件_名称_前台查询时所输入的
* @param projectId 所属项目_前台查询时所在项目
* @param filters 过滤集合__前台查询时的过滤条件
* @param unSelectIds 未勾选ID_前台没有勾选的ID
* @return
*/
private
List
<
String
>
getAllScenarioIdsByFontedSelect
(
List
<
String
>
moduleIds
,
String
name
,
String
projectId
,
List
<
String
>
filters
,
List
<
String
>
unSelectIds
)
{
ApiScenarioRequest
selectRequest
=
new
ApiScenarioRequest
();
selectRequest
.
setModuleIds
(
moduleIds
);
selectRequest
.
setName
(
name
);
selectRequest
.
setProjectId
(
projectId
);
selectRequest
.
setFilters
(
filters
);
selectRequest
.
setWorkspaceId
(
SessionUtils
.
getCurrentWorkspaceId
());
List
<
ApiScenarioDTO
>
list
=
extApiScenarioMapper
.
list
(
selectRequest
);
List
<
String
>
allIds
=
list
.
stream
().
map
(
ApiScenarioDTO:
:
getId
).
collect
(
Collectors
.
toList
());
List
<
String
>
ids
=
allIds
.
stream
().
filter
(
id
->
!
unSelectIds
.
contains
(
id
)).
collect
(
Collectors
.
toList
());
return
ids
;
}
public
String
addScenarioToPlan
(
SaveApiPlanRequest
request
)
{
if
(
CollectionUtils
.
isEmpty
(
request
.
getPlanIds
()))
{
...
...
backend/src/main/java/io/metersphere/api/service/ApiDefinitionExecResultService.java
浏览文件 @
8d152a07
...
...
@@ -5,6 +5,7 @@ import io.metersphere.api.dto.datacount.ExecutedCaseInfoResult;
import
io.metersphere.api.jmeter.TestResult
;
import
io.metersphere.base.domain.ApiDefinitionExecResult
;
import
io.metersphere.base.domain.ApiDefinitionExecResultExample
;
import
io.metersphere.base.domain.TestPlanApiCase
;
import
io.metersphere.base.mapper.ApiDefinitionExecResultMapper
;
import
io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper
;
import
io.metersphere.commons.constants.ApiRunMode
;
...
...
@@ -59,6 +60,43 @@ public class ApiDefinitionExecResultService {
});
}
/**
* 定时任务触发的保存逻辑
* 定时任务时,userID要改为定时任务中的用户
* @param result
* @param type
*/
public
void
saveApiResultByScheduleTask
(
TestResult
result
,
String
type
)
{
result
.
getScenarios
().
get
(
0
).
getRequestResults
().
forEach
(
item
->
{
ApiDefinitionExecResult
saveResult
=
new
ApiDefinitionExecResult
();
saveResult
.
setId
(
UUID
.
randomUUID
().
toString
());
saveResult
.
setCreateTime
(
System
.
currentTimeMillis
());
saveResult
.
setName
(
item
.
getName
());
saveResult
.
setResourceId
(
item
.
getName
());
saveResult
.
setContent
(
JSON
.
toJSONString
(
item
));
saveResult
.
setStartTime
(
item
.
getStartTime
());
String
status
=
item
.
isSuccess
()
?
"success"
:
"error"
;
saveResult
.
setEndTime
(
item
.
getResponseResult
().
getResponseTime
());
saveResult
.
setType
(
type
);
saveResult
.
setStatus
(
status
);
String
userID
=
null
;
if
(
StringUtils
.
equals
(
type
,
ApiRunMode
.
SCHEDULE_API_PLAN
.
name
()))
{
TestPlanApiCase
apiCase
=
testPlanApiCaseService
.
getById
(
item
.
getName
());
String
scheduleCreateUser
=
testPlanService
.
findScheduleCreateUserById
(
apiCase
.
getTestPlanId
());
userID
=
scheduleCreateUser
;
apiCase
.
setStatus
(
status
);
testPlanApiCaseService
.
updateByPrimaryKeySelective
(
apiCase
);
}
else
{
userID
=
Objects
.
requireNonNull
(
SessionUtils
.
getUser
()).
getId
();
testPlanApiCaseService
.
setExecResult
(
item
.
getName
(),
status
);
}
saveResult
.
setUserId
(
userID
);
apiDefinitionExecResultMapper
.
insert
(
saveResult
);
});
}
public
void
deleteByResourceId
(
String
resourceId
)
{
ApiDefinitionExecResultExample
example
=
new
ApiDefinitionExecResultExample
();
example
.
createCriteria
().
andResourceIdEqualTo
(
resourceId
);
...
...
backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java
浏览文件 @
8d152a07
...
...
@@ -9,6 +9,7 @@ import io.metersphere.api.dto.APIReportResult;
import
io.metersphere.api.dto.ApiTestImportRequest
;
import
io.metersphere.api.dto.automation.ApiScenarioRequest
;
import
io.metersphere.api.dto.automation.ReferenceDTO
;
import
io.metersphere.api.dto.automation.RunScenarioRequest
;
import
io.metersphere.api.dto.datacount.ApiDataCountResult
;
import
io.metersphere.api.dto.definition.*
;
import
io.metersphere.api.dto.definition.parse.ApiDefinitionImport
;
...
...
@@ -29,6 +30,7 @@ import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
import
io.metersphere.base.mapper.ext.ExtTestPlanMapper
;
import
io.metersphere.commons.constants.APITestStatus
;
import
io.metersphere.commons.constants.ApiRunMode
;
import
io.metersphere.commons.constants.ReportTriggerMode
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.*
;
import
io.metersphere.i18n.Translator
;
...
...
@@ -43,6 +45,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
import
org.apache.jorphan.collections.HashTree
;
import
org.apache.jorphan.collections.ListedHashTree
;
import
org.aspectj.util.FileUtil
;
import
org.aspectj.weaver.ast.Test
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -334,60 +337,11 @@ public class ApiDefinitionService {
if
(
StringUtils
.
isNotBlank
(
request
.
getType
())
&&
StringUtils
.
equals
(
request
.
getType
(),
ApiRunMode
.
API_PLAN
.
name
()))
{
runMode
=
ApiRunMode
.
API_PLAN
.
name
();
}
// 调用执行方法
jMeterService
.
runDefinition
(
request
.
getId
(),
hashTree
,
request
.
getReportId
(),
runMode
);
return
request
.
getId
();
}
/**
* 内部构建HashTree 定时任务发起的执行
*
* @param request
* @return
*/
public
String
run
(
RunDefinitionRequest
request
,
ApiTestCaseWithBLOBs
item
)
{
MsTestPlan
testPlan
=
new
MsTestPlan
();
testPlan
.
setHashTree
(
new
LinkedList
<>());
HashTree
jmeterHashTree
=
new
ListedHashTree
();
try
{
MsThreadGroup
group
=
new
MsThreadGroup
();
group
.
setLabel
(
item
.
getName
());
group
.
setName
(
UUID
.
randomUUID
().
toString
());
ObjectMapper
mapper
=
new
ObjectMapper
();
mapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
JSONObject
element
=
JSON
.
parseObject
(
item
.
getRequest
());
MsScenario
scenario
=
JSONObject
.
parseObject
(
item
.
getRequest
(),
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
<
ScenarioVariable
>
variables
=
mapper
.
readValue
(
element
.
getString
(
"variables"
),
new
TypeReference
<
LinkedList
<
ScenarioVariable
>>()
{
});
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
runMode
=
ApiRunMode
.
DELIMIT
.
name
();
if
(
StringUtils
.
isNotBlank
(
request
.
getType
())
&&
StringUtils
.
equals
(
request
.
getType
(),
ApiRunMode
.
API_PLAN
.
name
()))
{
runMode
=
ApiRunMode
.
API_PLAN
.
name
();
}
System
.
out
.
println
(
testPlan
.
getJmx
(
hashTree
));
// 调用执行方法
jMeterService
.
runDefinition
(
request
.
getId
(),
jmeterH
ashTree
,
request
.
getReportId
(),
runMode
);
jMeterService
.
runDefinition
(
request
.
getId
(),
h
ashTree
,
request
.
getReportId
(),
runMode
);
return
request
.
getId
();
}
...
...
backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java
浏览文件 @
8d152a07
...
...
@@ -17,10 +17,12 @@ import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
import
io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper
;
import
io.metersphere.commons.constants.ApiRunMode
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.CommonBeanFactory
;
import
io.metersphere.commons.utils.DateUtils
;
import
io.metersphere.commons.utils.ServiceUtils
;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.i18n.Translator
;
import
io.metersphere.track.service.TestPlanReportService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
...
...
@@ -28,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
import
javax.annotation.Resource
;
import
java.nio.charset.StandardCharsets
;
import
java.text.DecimalFormat
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -46,12 +49,16 @@ public class ApiScenarioReportService {
private
ApiScenarioMapper
apiScenarioMapper
;
@Resource
private
TestPlanApiScenarioMapper
testPlanApiScenarioMapper
;
// @Resource
// private TestPlanReportService testPlanReportService;
public
ApiScenarioReport
complete
(
TestResult
result
,
String
runMode
)
{
// 更新场景
if
(
result
!=
null
)
{
if
(
StringUtils
.
equals
(
runMode
,
ApiRunMode
.
SCENARIO_PLAN
.
name
()))
{
return
updatePlanCase
(
result
);
}
else
if
(
StringUtils
.
equals
(
runMode
,
ApiRunMode
.
SCHEDULE_SCENARIO_PLAN
.
name
()))
{
return
updateSchedulePlanCase
(
result
);
}
else
{
return
updateScenario
(
result
);
}
...
...
@@ -153,6 +160,65 @@ public class ApiScenarioReportService {
return
report
;
}
public
ApiScenarioReport
updateSchedulePlanCase
(
TestResult
result
)
{
ApiScenarioReport
lastReport
=
null
;
List
<
ScenarioResult
>
scenarioResultList
=
result
.
getScenarios
();
List
<
String
>
testPlanReportIdList
=
new
ArrayList
<>();
for
(
ScenarioResult
scenarioResult
:
scenarioResultList
)
{
// 存储场景报告
ApiScenarioReport
report
=
editReport
(
scenarioResult
);
/**
* 测试计划的定时任务场景执行时,主键是提前生成的【测试报告ID】。也就是TestResult.id是【测试报告ID】。
* report.getScenarioId中存放的是 TestPlanApiScenario.id:TestPlanReport.id 由于参数限制,只得将两个ID拼接起来
* 拆分report.getScenarioId, 查出ScenarioId,将真正的场景ID赋值回去
* 同时将testPlanReportID存入集合,逻辑走完后更新TestPlanReport
*/
String
[]
idArr
=
report
.
getScenarioId
().
split
(
":"
);
String
planScenarioId
=
null
;
if
(
idArr
.
length
>
1
){
planScenarioId
=
idArr
[
0
];
String
planReportID
=
idArr
[
1
];
if
(!
testPlanReportIdList
.
contains
(
planReportID
)){
testPlanReportIdList
.
add
(
planReportID
);
}
}
else
{
planScenarioId
=
report
.
getScenarioId
();
}
TestPlanApiScenario
testPlanApiScenario
=
testPlanApiScenarioMapper
.
selectByPrimaryKey
(
planScenarioId
);
report
.
setScenarioId
(
testPlanApiScenario
.
getApiScenarioId
());
apiScenarioReportMapper
.
updateByPrimaryKeySelective
(
report
);
if
(
scenarioResult
.
getError
()
>
0
)
{
testPlanApiScenario
.
setLastResult
(
ScenarioStatus
.
Fail
.
name
());
}
else
{
testPlanApiScenario
.
setLastResult
(
ScenarioStatus
.
Success
.
name
());
}
String
passRate
=
new
DecimalFormat
(
"0%"
).
format
((
float
)
scenarioResult
.
getSuccess
()
/
(
scenarioResult
.
getSuccess
()
+
scenarioResult
.
getError
()));
testPlanApiScenario
.
setPassRate
(
passRate
);
// 报告详情内容
ApiScenarioReportDetail
detail
=
new
ApiScenarioReportDetail
();
TestResult
newResult
=
createTestResult
(
result
.
getTestId
(),
scenarioResult
);
List
<
ScenarioResult
>
scenarioResults
=
new
ArrayList
();
scenarioResult
.
setName
(
report
.
getScenarioName
());
scenarioResults
.
add
(
scenarioResult
);
newResult
.
setScenarios
(
scenarioResults
);
detail
.
setContent
(
JSON
.
toJSONString
(
newResult
).
getBytes
(
StandardCharsets
.
UTF_8
));
detail
.
setReportId
(
report
.
getId
());
detail
.
setProjectId
(
report
.
getProjectId
());
apiScenarioReportDetailMapper
.
insert
(
detail
);
testPlanApiScenario
.
setReportId
(
report
.
getId
());
testPlanApiScenarioMapper
.
updateByPrimaryKeySelective
(
testPlanApiScenario
);
lastReport
=
report
;
}
TestPlanReportService
testPlanReportService
=
CommonBeanFactory
.
getBean
(
TestPlanReportService
.
class
);
testPlanReportService
.
updateReport
(
testPlanReportIdList
,
ApiRunMode
.
SCHEDULE_SCENARIO_PLAN
.
name
());
return
lastReport
;
}
public
ApiScenarioReport
updateScenario
(
TestResult
result
)
{
ApiScenarioReport
lastReport
=
null
;
for
(
ScenarioResult
item
:
result
.
getScenarios
())
{
...
...
backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java
浏览文件 @
8d152a07
...
...
@@ -435,46 +435,11 @@ public class ApiTestCaseService {
public
String
run
(
RunCaseRequest
request
)
{
ApiTestCaseWithBLOBs
testCaseWithBLOBs
=
apiTestCaseMapper
.
selectByPrimaryKey
(
request
.
getCaseId
());
// 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取
if
(
testCaseWithBLOBs
!=
null
&&
StringUtils
.
isNotEmpty
(
testCaseWithBLOBs
.
getRequest
()))
{
try
{
ObjectMapper
mapper
=
new
ObjectMapper
();
mapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
MsTestElement
element
=
mapper
.
readValue
(
testCaseWithBLOBs
.
getRequest
(),
new
TypeReference
<
MsTestElement
>()
{
});
if
(
StringUtils
.
isBlank
(
request
.
getEnvironmentId
())){
TestPlanApiCaseExample
example
=
new
TestPlanApiCaseExample
();
example
.
createCriteria
().
andTestPlanIdEqualTo
(
request
.
getTestPlanId
()).
andApiCaseIdEqualTo
(
request
.
getCaseId
());
List
<
TestPlanApiCase
>
list
=
testPlanApiCaseMapper
.
selectByExample
(
example
);
request
.
setEnvironmentId
(
list
.
get
(
0
).
getEnvironmentId
());
element
.
setName
(
list
.
get
(
0
).
getId
());
}
else
{
element
.
setName
(
request
.
getCaseId
());
}
// 测试计划
MsTestPlan
testPlan
=
new
MsTestPlan
();
testPlan
.
setHashTree
(
new
LinkedList
<>());
HashTree
jmeterHashTree
=
new
ListedHashTree
();
// 线程组
MsThreadGroup
group
=
new
MsThreadGroup
();
group
.
setLabel
(
testCaseWithBLOBs
.
getName
());
group
.
setName
(
testCaseWithBLOBs
.
getId
());
LinkedList
<
MsTestElement
>
hashTrees
=
new
LinkedList
<>();
hashTrees
.
add
(
element
);
group
.
setHashTree
(
hashTrees
);
testPlan
.
getHashTree
().
add
(
group
);
ApiTestEnvironmentService
environmentService
=
CommonBeanFactory
.
getBean
(
ApiTestEnvironmentService
.
class
);
ApiTestEnvironmentWithBLOBs
environment
=
environmentService
.
get
(
request
.
getEnvironmentId
());
ParameterConfig
parameterConfig
=
new
ParameterConfig
();
if
(
environment
!=
null
&&
environment
.
getConfig
()
!=
null
)
{
parameterConfig
.
setConfig
(
JSONObject
.
parseObject
(
environment
.
getConfig
(),
EnvironmentConfig
.
class
));
}
testPlan
.
toHashTree
(
jmeterHashTree
,
testPlan
.
getHashTree
(),
parameterConfig
);
String
runMode
=
request
.
getRunMode
();
HashTree
jmeterHashTree
=
this
.
generateHashTree
(
request
,
testCaseWithBLOBs
);
String
runMode
=
ApiRunMode
.
DELIMIT
.
name
();
// 调用执行方法
jMeterService
.
runDefinition
(
request
.
getReportId
(),
jmeterHashTree
,
request
.
getReportId
(),
runMode
);
...
...
@@ -484,6 +449,62 @@ public class ApiTestCaseService {
}
return
request
.
getReportId
();
}
public
String
run
(
ApiTestCaseWithBLOBs
apiCaseBolbs
,
String
id
,
String
debugReportId
,
String
testPlanID
,
String
runMode
)
{
// 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取
if
(
apiCaseBolbs
!=
null
&&
StringUtils
.
isNotEmpty
(
apiCaseBolbs
.
getRequest
()))
{
try
{
ApiTestCase
apiTestCase
=
apiTestCaseMapper
.
selectByPrimaryKey
(
apiCaseBolbs
.
getId
());
RunCaseRequest
request
=
new
RunCaseRequest
();
request
.
setCaseId
(
apiTestCase
.
getId
());
request
.
setTestPlanId
(
testPlanID
);
HashTree
jmeterHashTree
=
this
.
generateHashTree
(
request
,
apiCaseBolbs
);
// 调用执行方法
jMeterService
.
runDefinition
(
id
,
jmeterHashTree
,
debugReportId
,
runMode
);
}
catch
(
Exception
ex
)
{
LogUtil
.
error
(
ex
.
getMessage
());
}
}
return
id
;
}
public
HashTree
generateHashTree
(
RunCaseRequest
request
,
ApiTestCaseWithBLOBs
testCaseWithBLOBs
)
throws
Exception
{
ObjectMapper
mapper
=
new
ObjectMapper
();
mapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
MsTestElement
element
=
mapper
.
readValue
(
testCaseWithBLOBs
.
getRequest
(),
new
TypeReference
<
MsTestElement
>()
{
});
if
(
StringUtils
.
isBlank
(
request
.
getEnvironmentId
())){
TestPlanApiCaseExample
example
=
new
TestPlanApiCaseExample
();
example
.
createCriteria
().
andTestPlanIdEqualTo
(
request
.
getTestPlanId
()).
andApiCaseIdEqualTo
(
request
.
getCaseId
());
List
<
TestPlanApiCase
>
list
=
testPlanApiCaseMapper
.
selectByExample
(
example
);
request
.
setEnvironmentId
(
list
.
get
(
0
).
getEnvironmentId
());
element
.
setName
(
list
.
get
(
0
).
getId
());
}
else
{
element
.
setName
(
request
.
getCaseId
());
}
// 测试计划
MsTestPlan
testPlan
=
new
MsTestPlan
();
testPlan
.
setHashTree
(
new
LinkedList
<>());
HashTree
jmeterHashTree
=
new
ListedHashTree
();
// 线程组
MsThreadGroup
group
=
new
MsThreadGroup
();
group
.
setLabel
(
testCaseWithBLOBs
.
getName
());
group
.
setName
(
testCaseWithBLOBs
.
getId
());
LinkedList
<
MsTestElement
>
hashTrees
=
new
LinkedList
<>();
hashTrees
.
add
(
element
);
group
.
setHashTree
(
hashTrees
);
testPlan
.
getHashTree
().
add
(
group
);
ApiTestEnvironmentService
environmentService
=
CommonBeanFactory
.
getBean
(
ApiTestEnvironmentService
.
class
);
ApiTestEnvironmentWithBLOBs
environment
=
environmentService
.
get
(
request
.
getEnvironmentId
());
ParameterConfig
parameterConfig
=
new
ParameterConfig
();
if
(
environment
!=
null
&&
environment
.
getConfig
()
!=
null
)
{
parameterConfig
.
setConfig
(
JSONObject
.
parseObject
(
environment
.
getConfig
(),
EnvironmentConfig
.
class
));
}
testPlan
.
toHashTree
(
jmeterHashTree
,
testPlan
.
getHashTree
(),
parameterConfig
);
return
jmeterHashTree
;
}
public
String
getExecResult
(
String
id
){
ApiDefinitionExecResultExample
apidefinitionexecresultexample
=
new
ApiDefinitionExecResultExample
();
...
...
backend/src/main/java/io/metersphere/base/domain/TestPlanReport.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.base.domain
;
import
java.io.Serializable
;
import
lombok.Data
;
@Data
public
class
TestPlanReport
implements
Serializable
{
private
String
id
;
private
String
testPlanId
;
private
Long
createTime
;
private
Long
updateTime
;
private
String
name
;
private
String
status
;
private
String
triggerMode
;
private
String
creator
;
private
Long
startTime
;
private
Long
endTime
;
private
Boolean
isApiCaseExecuting
;
private
Boolean
isScenarioExecuting
;
private
Boolean
isPerformanceExecuting
;
private
String
principal
;
private
static
final
long
serialVersionUID
=
1L
;
}
\ No newline at end of file
backend/src/main/java/io/metersphere/base/domain/TestPlanReportData.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.base.domain
;
import
java.io.Serializable
;
import
lombok.Data
;
@Data
public
class
TestPlanReportData
implements
Serializable
{
private
String
id
;
private
String
testPlanReportId
;
private
static
final
long
serialVersionUID
=
1L
;
}
\ No newline at end of file
backend/src/main/java/io/metersphere/base/domain/TestPlanReportDataExample.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.base.domain
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
TestPlanReportDataExample
{
protected
String
orderByClause
;
protected
boolean
distinct
;
protected
List
<
Criteria
>
oredCriteria
;
public
TestPlanReportDataExample
()
{
oredCriteria
=
new
ArrayList
<
Criteria
>();
}
public
void
setOrderByClause
(
String
orderByClause
)
{
this
.
orderByClause
=
orderByClause
;
}
public
String
getOrderByClause
()
{
return
orderByClause
;
}
public
void
setDistinct
(
boolean
distinct
)
{
this
.
distinct
=
distinct
;
}
public
boolean
isDistinct
()
{
return
distinct
;
}
public
List
<
Criteria
>
getOredCriteria
()
{
return
oredCriteria
;
}
public
void
or
(
Criteria
criteria
)
{
oredCriteria
.
add
(
criteria
);
}
public
Criteria
or
()
{
Criteria
criteria
=
createCriteriaInternal
();
oredCriteria
.
add
(
criteria
);
return
criteria
;
}
public
Criteria
createCriteria
()
{
Criteria
criteria
=
createCriteriaInternal
();
if
(
oredCriteria
.
size
()
==
0
)
{
oredCriteria
.
add
(
criteria
);
}
return
criteria
;
}
protected
Criteria
createCriteriaInternal
()
{
Criteria
criteria
=
new
Criteria
();
return
criteria
;
}
public
void
clear
()
{
oredCriteria
.
clear
();
orderByClause
=
null
;
distinct
=
false
;
}
protected
abstract
static
class
GeneratedCriteria
{
protected
List
<
Criterion
>
criteria
;
protected
GeneratedCriteria
()
{
super
();
criteria
=
new
ArrayList
<
Criterion
>();
}
public
boolean
isValid
()
{
return
criteria
.
size
()
>
0
;
}
public
List
<
Criterion
>
getAllCriteria
()
{
return
criteria
;
}
public
List
<
Criterion
>
getCriteria
()
{
return
criteria
;
}
protected
void
addCriterion
(
String
condition
)
{
if
(
condition
==
null
)
{
throw
new
RuntimeException
(
"Value for condition cannot be null"
);
}
criteria
.
add
(
new
Criterion
(
condition
));
}
protected
void
addCriterion
(
String
condition
,
Object
value
,
String
property
)
{
if
(
value
==
null
)
{
throw
new
RuntimeException
(
"Value for "
+
property
+
" cannot be null"
);
}
criteria
.
add
(
new
Criterion
(
condition
,
value
));
}
protected
void
addCriterion
(
String
condition
,
Object
value1
,
Object
value2
,
String
property
)
{
if
(
value1
==
null
||
value2
==
null
)
{
throw
new
RuntimeException
(
"Between values for "
+
property
+
" cannot be null"
);
}
criteria
.
add
(
new
Criterion
(
condition
,
value1
,
value2
));
}
public
Criteria
andIdIsNull
()
{
addCriterion
(
"id is null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdIsNotNull
()
{
addCriterion
(
"id is not null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdEqualTo
(
String
value
)
{
addCriterion
(
"id ="
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdNotEqualTo
(
String
value
)
{
addCriterion
(
"id <>"
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdGreaterThan
(
String
value
)
{
addCriterion
(
"id >"
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdGreaterThanOrEqualTo
(
String
value
)
{
addCriterion
(
"id >="
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdLessThan
(
String
value
)
{
addCriterion
(
"id <"
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdLessThanOrEqualTo
(
String
value
)
{
addCriterion
(
"id <="
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdLike
(
String
value
)
{
addCriterion
(
"id like"
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdNotLike
(
String
value
)
{
addCriterion
(
"id not like"
,
value
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdIn
(
List
<
String
>
values
)
{
addCriterion
(
"id in"
,
values
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdNotIn
(
List
<
String
>
values
)
{
addCriterion
(
"id not in"
,
values
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"id between"
,
value1
,
value2
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andIdNotBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"id not between"
,
value1
,
value2
,
"id"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdIsNull
()
{
addCriterion
(
"test_plan_report_id is null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdIsNotNull
()
{
addCriterion
(
"test_plan_report_id is not null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdEqualTo
(
String
value
)
{
addCriterion
(
"test_plan_report_id ="
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdNotEqualTo
(
String
value
)
{
addCriterion
(
"test_plan_report_id <>"
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdGreaterThan
(
String
value
)
{
addCriterion
(
"test_plan_report_id >"
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdGreaterThanOrEqualTo
(
String
value
)
{
addCriterion
(
"test_plan_report_id >="
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdLessThan
(
String
value
)
{
addCriterion
(
"test_plan_report_id <"
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdLessThanOrEqualTo
(
String
value
)
{
addCriterion
(
"test_plan_report_id <="
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdLike
(
String
value
)
{
addCriterion
(
"test_plan_report_id like"
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdNotLike
(
String
value
)
{
addCriterion
(
"test_plan_report_id not like"
,
value
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdIn
(
List
<
String
>
values
)
{
addCriterion
(
"test_plan_report_id in"
,
values
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdNotIn
(
List
<
String
>
values
)
{
addCriterion
(
"test_plan_report_id not in"
,
values
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"test_plan_report_id between"
,
value1
,
value2
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
public
Criteria
andTestPlanReportIdNotBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"test_plan_report_id not between"
,
value1
,
value2
,
"testPlanReportId"
);
return
(
Criteria
)
this
;
}
}
public
static
class
Criteria
extends
GeneratedCriteria
{
protected
Criteria
()
{
super
();
}
}
public
static
class
Criterion
{
private
String
condition
;
private
Object
value
;
private
Object
secondValue
;
private
boolean
noValue
;
private
boolean
singleValue
;
private
boolean
betweenValue
;
private
boolean
listValue
;
private
String
typeHandler
;
public
String
getCondition
()
{
return
condition
;
}
public
Object
getValue
()
{
return
value
;
}
public
Object
getSecondValue
()
{
return
secondValue
;
}
public
boolean
isNoValue
()
{
return
noValue
;
}
public
boolean
isSingleValue
()
{
return
singleValue
;
}
public
boolean
isBetweenValue
()
{
return
betweenValue
;
}
public
boolean
isListValue
()
{
return
listValue
;
}
public
String
getTypeHandler
()
{
return
typeHandler
;
}
protected
Criterion
(
String
condition
)
{
super
();
this
.
condition
=
condition
;
this
.
typeHandler
=
null
;
this
.
noValue
=
true
;
}
protected
Criterion
(
String
condition
,
Object
value
,
String
typeHandler
)
{
super
();
this
.
condition
=
condition
;
this
.
value
=
value
;
this
.
typeHandler
=
typeHandler
;
if
(
value
instanceof
List
<?>)
{
this
.
listValue
=
true
;
}
else
{
this
.
singleValue
=
true
;
}
}
protected
Criterion
(
String
condition
,
Object
value
)
{
this
(
condition
,
value
,
null
);
}
protected
Criterion
(
String
condition
,
Object
value
,
Object
secondValue
,
String
typeHandler
)
{
super
();
this
.
condition
=
condition
;
this
.
value
=
value
;
this
.
secondValue
=
secondValue
;
this
.
typeHandler
=
typeHandler
;
this
.
betweenValue
=
true
;
}
protected
Criterion
(
String
condition
,
Object
value
,
Object
secondValue
)
{
this
(
condition
,
value
,
secondValue
,
null
);
}
}
}
\ No newline at end of file
backend/src/main/java/io/metersphere/base/domain/TestPlanReportDataWithBLOBs.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.base.domain
;
import
java.io.Serializable
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.ToString
;
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@ToString
(
callSuper
=
true
)
public
class
TestPlanReportDataWithBLOBs
extends
TestPlanReportData
implements
Serializable
{
private
String
executeResult
;
private
String
failurTestCases
;
private
String
moduleExecuteResult
;
private
String
apiCaseInfo
;
private
String
scenarioInfo
;
private
String
performanceInfo
;
private
String
issuesInfo
;
private
static
final
long
serialVersionUID
=
1L
;
}
\ No newline at end of file
backend/src/main/java/io/metersphere/base/domain/TestPlanReportExample.java
0 → 100644
浏览文件 @
8d152a07
此差异已折叠。
点击以展开。
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportDataMapper.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.base.mapper
;
import
io.metersphere.base.domain.TestPlanReportData
;
import
io.metersphere.base.domain.TestPlanReportDataExample
;
import
io.metersphere.base.domain.TestPlanReportDataWithBLOBs
;
import
java.util.List
;
import
org.apache.ibatis.annotations.Param
;
public
interface
TestPlanReportDataMapper
{
long
countByExample
(
TestPlanReportDataExample
example
);
int
deleteByExample
(
TestPlanReportDataExample
example
);
int
deleteByPrimaryKey
(
String
id
);
int
insert
(
TestPlanReportDataWithBLOBs
record
);
int
insertSelective
(
TestPlanReportDataWithBLOBs
record
);
List
<
TestPlanReportDataWithBLOBs
>
selectByExampleWithBLOBs
(
TestPlanReportDataExample
example
);
List
<
TestPlanReportData
>
selectByExample
(
TestPlanReportDataExample
example
);
TestPlanReportDataWithBLOBs
selectByPrimaryKey
(
String
id
);
int
updateByExampleSelective
(
@Param
(
"record"
)
TestPlanReportDataWithBLOBs
record
,
@Param
(
"example"
)
TestPlanReportDataExample
example
);
int
updateByExampleWithBLOBs
(
@Param
(
"record"
)
TestPlanReportDataWithBLOBs
record
,
@Param
(
"example"
)
TestPlanReportDataExample
example
);
int
updateByExample
(
@Param
(
"record"
)
TestPlanReportData
record
,
@Param
(
"example"
)
TestPlanReportDataExample
example
);
int
updateByPrimaryKeySelective
(
TestPlanReportDataWithBLOBs
record
);
int
updateByPrimaryKeyWithBLOBs
(
TestPlanReportDataWithBLOBs
record
);
int
updateByPrimaryKey
(
TestPlanReportData
record
);
}
\ No newline at end of file
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportDataMapper.xml
0 → 100644
浏览文件 @
8d152a07
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"io.metersphere.base.mapper.TestPlanReportDataMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"io.metersphere.base.domain.TestPlanReportData"
>
<id
column=
"id"
jdbcType=
"VARCHAR"
property=
"id"
/>
<result
column=
"test_plan_report_id"
jdbcType=
"VARCHAR"
property=
"testPlanReportId"
/>
</resultMap>
<resultMap
extends=
"BaseResultMap"
id=
"ResultMapWithBLOBs"
type=
"io.metersphere.base.domain.TestPlanReportDataWithBLOBs"
>
<result
column=
"execute_result"
jdbcType=
"LONGVARCHAR"
property=
"executeResult"
/>
<result
column=
"failur_test_cases"
jdbcType=
"LONGVARCHAR"
property=
"failurTestCases"
/>
<result
column=
"module_execute_result"
jdbcType=
"LONGVARCHAR"
property=
"moduleExecuteResult"
/>
<result
column=
"api_case_info"
jdbcType=
"LONGVARCHAR"
property=
"apiCaseInfo"
/>
<result
column=
"scenario_info"
jdbcType=
"LONGVARCHAR"
property=
"scenarioInfo"
/>
<result
column=
"performance_info"
jdbcType=
"LONGVARCHAR"
property=
"performanceInfo"
/>
<result
column=
"issues_info"
jdbcType=
"LONGVARCHAR"
property=
"issuesInfo"
/>
</resultMap>
<sql
id=
"Example_Where_Clause"
>
<where>
<foreach
collection=
"oredCriteria"
item=
"criteria"
separator=
"or"
>
<if
test=
"criteria.valid"
>
<trim
prefix=
"("
prefixOverrides=
"and"
suffix=
")"
>
<foreach
collection=
"criteria.criteria"
item=
"criterion"
>
<choose>
<when
test=
"criterion.noValue"
>
and ${criterion.condition}
</when>
<when
test=
"criterion.singleValue"
>
and ${criterion.condition} #{criterion.value}
</when>
<when
test=
"criterion.betweenValue"
>
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when
test=
"criterion.listValue"
>
and ${criterion.condition}
<foreach
close=
")"
collection=
"criterion.value"
item=
"listItem"
open=
"("
separator=
","
>
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql
id=
"Update_By_Example_Where_Clause"
>
<where>
<foreach
collection=
"example.oredCriteria"
item=
"criteria"
separator=
"or"
>
<if
test=
"criteria.valid"
>
<trim
prefix=
"("
prefixOverrides=
"and"
suffix=
")"
>
<foreach
collection=
"criteria.criteria"
item=
"criterion"
>
<choose>
<when
test=
"criterion.noValue"
>
and ${criterion.condition}
</when>
<when
test=
"criterion.singleValue"
>
and ${criterion.condition} #{criterion.value}
</when>
<when
test=
"criterion.betweenValue"
>
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when
test=
"criterion.listValue"
>
and ${criterion.condition}
<foreach
close=
")"
collection=
"criterion.value"
item=
"listItem"
open=
"("
separator=
","
>
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql
id=
"Base_Column_List"
>
id, test_plan_report_id
</sql>
<sql
id=
"Blob_Column_List"
>
execute_result, failur_test_cases, module_execute_result, api_case_info, scenario_info,
performance_info, issues_info
</sql>
<select
id=
"selectByExampleWithBLOBs"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataExample"
resultMap=
"ResultMapWithBLOBs"
>
select
<if
test=
"distinct"
>
distinct
</if>
<include
refid=
"Base_Column_List"
/>
,
<include
refid=
"Blob_Column_List"
/>
from test_plan_report_data
<if
test=
"_parameter != null"
>
<include
refid=
"Example_Where_Clause"
/>
</if>
<if
test=
"orderByClause != null"
>
order by ${orderByClause}
</if>
</select>
<select
id=
"selectByExample"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataExample"
resultMap=
"BaseResultMap"
>
select
<if
test=
"distinct"
>
distinct
</if>
<include
refid=
"Base_Column_List"
/>
from test_plan_report_data
<if
test=
"_parameter != null"
>
<include
refid=
"Example_Where_Clause"
/>
</if>
<if
test=
"orderByClause != null"
>
order by ${orderByClause}
</if>
</select>
<select
id=
"selectByPrimaryKey"
parameterType=
"java.lang.String"
resultMap=
"ResultMapWithBLOBs"
>
select
<include
refid=
"Base_Column_List"
/>
,
<include
refid=
"Blob_Column_List"
/>
from test_plan_report_data
where id = #{id,jdbcType=VARCHAR}
</select>
<delete
id=
"deleteByPrimaryKey"
parameterType=
"java.lang.String"
>
delete from test_plan_report_data
where id = #{id,jdbcType=VARCHAR}
</delete>
<delete
id=
"deleteByExample"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataExample"
>
delete from test_plan_report_data
<if
test=
"_parameter != null"
>
<include
refid=
"Example_Where_Clause"
/>
</if>
</delete>
<insert
id=
"insert"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataWithBLOBs"
>
insert into test_plan_report_data (id, test_plan_report_id, execute_result,
failur_test_cases, module_execute_result,
api_case_info, scenario_info, performance_info,
issues_info)
values (#{id,jdbcType=VARCHAR}, #{testPlanReportId,jdbcType=VARCHAR}, #{executeResult,jdbcType=LONGVARCHAR},
#{failurTestCases,jdbcType=LONGVARCHAR}, #{moduleExecuteResult,jdbcType=LONGVARCHAR},
#{apiCaseInfo,jdbcType=LONGVARCHAR}, #{scenarioInfo,jdbcType=LONGVARCHAR}, #{performanceInfo,jdbcType=LONGVARCHAR},
#{issuesInfo,jdbcType=LONGVARCHAR})
</insert>
<insert
id=
"insertSelective"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataWithBLOBs"
>
insert into test_plan_report_data
<trim
prefix=
"("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
id,
</if>
<if
test=
"testPlanReportId != null"
>
test_plan_report_id,
</if>
<if
test=
"executeResult != null"
>
execute_result,
</if>
<if
test=
"failurTestCases != null"
>
failur_test_cases,
</if>
<if
test=
"moduleExecuteResult != null"
>
module_execute_result,
</if>
<if
test=
"apiCaseInfo != null"
>
api_case_info,
</if>
<if
test=
"scenarioInfo != null"
>
scenario_info,
</if>
<if
test=
"performanceInfo != null"
>
performance_info,
</if>
<if
test=
"issuesInfo != null"
>
issues_info,
</if>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
#{id,jdbcType=VARCHAR},
</if>
<if
test=
"testPlanReportId != null"
>
#{testPlanReportId,jdbcType=VARCHAR},
</if>
<if
test=
"executeResult != null"
>
#{executeResult,jdbcType=LONGVARCHAR},
</if>
<if
test=
"failurTestCases != null"
>
#{failurTestCases,jdbcType=LONGVARCHAR},
</if>
<if
test=
"moduleExecuteResult != null"
>
#{moduleExecuteResult,jdbcType=LONGVARCHAR},
</if>
<if
test=
"apiCaseInfo != null"
>
#{apiCaseInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"scenarioInfo != null"
>
#{scenarioInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"performanceInfo != null"
>
#{performanceInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"issuesInfo != null"
>
#{issuesInfo,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
<select
id=
"countByExample"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataExample"
resultType=
"java.lang.Long"
>
select count(*) from test_plan_report_data
<if
test=
"_parameter != null"
>
<include
refid=
"Example_Where_Clause"
/>
</if>
</select>
<update
id=
"updateByExampleSelective"
parameterType=
"map"
>
update test_plan_report_data
<set>
<if
test=
"record.id != null"
>
id = #{record.id,jdbcType=VARCHAR},
</if>
<if
test=
"record.testPlanReportId != null"
>
test_plan_report_id = #{record.testPlanReportId,jdbcType=VARCHAR},
</if>
<if
test=
"record.executeResult != null"
>
execute_result = #{record.executeResult,jdbcType=LONGVARCHAR},
</if>
<if
test=
"record.failurTestCases != null"
>
failur_test_cases = #{record.failurTestCases,jdbcType=LONGVARCHAR},
</if>
<if
test=
"record.moduleExecuteResult != null"
>
module_execute_result = #{record.moduleExecuteResult,jdbcType=LONGVARCHAR},
</if>
<if
test=
"record.apiCaseInfo != null"
>
api_case_info = #{record.apiCaseInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"record.scenarioInfo != null"
>
scenario_info = #{record.scenarioInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"record.performanceInfo != null"
>
performance_info = #{record.performanceInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"record.issuesInfo != null"
>
issues_info = #{record.issuesInfo,jdbcType=LONGVARCHAR},
</if>
</set>
<if
test=
"_parameter != null"
>
<include
refid=
"Update_By_Example_Where_Clause"
/>
</if>
</update>
<update
id=
"updateByExampleWithBLOBs"
parameterType=
"map"
>
update test_plan_report_data
set id = #{record.id,jdbcType=VARCHAR},
test_plan_report_id = #{record.testPlanReportId,jdbcType=VARCHAR},
execute_result = #{record.executeResult,jdbcType=LONGVARCHAR},
failur_test_cases = #{record.failurTestCases,jdbcType=LONGVARCHAR},
module_execute_result = #{record.moduleExecuteResult,jdbcType=LONGVARCHAR},
api_case_info = #{record.apiCaseInfo,jdbcType=LONGVARCHAR},
scenario_info = #{record.scenarioInfo,jdbcType=LONGVARCHAR},
performance_info = #{record.performanceInfo,jdbcType=LONGVARCHAR},
issues_info = #{record.issuesInfo,jdbcType=LONGVARCHAR}
<if
test=
"_parameter != null"
>
<include
refid=
"Update_By_Example_Where_Clause"
/>
</if>
</update>
<update
id=
"updateByExample"
parameterType=
"map"
>
update test_plan_report_data
set id = #{record.id,jdbcType=VARCHAR},
test_plan_report_id = #{record.testPlanReportId,jdbcType=VARCHAR}
<if
test=
"_parameter != null"
>
<include
refid=
"Update_By_Example_Where_Clause"
/>
</if>
</update>
<update
id=
"updateByPrimaryKeySelective"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataWithBLOBs"
>
update test_plan_report_data
<set>
<if
test=
"testPlanReportId != null"
>
test_plan_report_id = #{testPlanReportId,jdbcType=VARCHAR},
</if>
<if
test=
"executeResult != null"
>
execute_result = #{executeResult,jdbcType=LONGVARCHAR},
</if>
<if
test=
"failurTestCases != null"
>
failur_test_cases = #{failurTestCases,jdbcType=LONGVARCHAR},
</if>
<if
test=
"moduleExecuteResult != null"
>
module_execute_result = #{moduleExecuteResult,jdbcType=LONGVARCHAR},
</if>
<if
test=
"apiCaseInfo != null"
>
api_case_info = #{apiCaseInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"scenarioInfo != null"
>
scenario_info = #{scenarioInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"performanceInfo != null"
>
performance_info = #{performanceInfo,jdbcType=LONGVARCHAR},
</if>
<if
test=
"issuesInfo != null"
>
issues_info = #{issuesInfo,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update
id=
"updateByPrimaryKeyWithBLOBs"
parameterType=
"io.metersphere.base.domain.TestPlanReportDataWithBLOBs"
>
update test_plan_report_data
set test_plan_report_id = #{testPlanReportId,jdbcType=VARCHAR},
execute_result = #{executeResult,jdbcType=LONGVARCHAR},
failur_test_cases = #{failurTestCases,jdbcType=LONGVARCHAR},
module_execute_result = #{moduleExecuteResult,jdbcType=LONGVARCHAR},
api_case_info = #{apiCaseInfo,jdbcType=LONGVARCHAR},
scenario_info = #{scenarioInfo,jdbcType=LONGVARCHAR},
performance_info = #{performanceInfo,jdbcType=LONGVARCHAR},
issues_info = #{issuesInfo,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
<update
id=
"updateByPrimaryKey"
parameterType=
"io.metersphere.base.domain.TestPlanReportData"
>
update test_plan_report_data
set test_plan_report_id = #{testPlanReportId,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>
\ No newline at end of file
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.base.mapper
;
import
io.metersphere.base.domain.TestPlanReport
;
import
io.metersphere.base.domain.TestPlanReportExample
;
import
java.util.List
;
import
org.apache.ibatis.annotations.Param
;
public
interface
TestPlanReportMapper
{
long
countByExample
(
TestPlanReportExample
example
);
int
deleteByExample
(
TestPlanReportExample
example
);
int
deleteByPrimaryKey
(
String
id
);
int
insert
(
TestPlanReport
record
);
int
insertSelective
(
TestPlanReport
record
);
List
<
TestPlanReport
>
selectByExample
(
TestPlanReportExample
example
);
TestPlanReport
selectByPrimaryKey
(
String
id
);
int
updateByExampleSelective
(
@Param
(
"record"
)
TestPlanReport
record
,
@Param
(
"example"
)
TestPlanReportExample
example
);
int
updateByExample
(
@Param
(
"record"
)
TestPlanReport
record
,
@Param
(
"example"
)
TestPlanReportExample
example
);
int
updateByPrimaryKeySelective
(
TestPlanReport
record
);
int
updateByPrimaryKey
(
TestPlanReport
record
);
}
\ No newline at end of file
backend/src/main/java/io/metersphere/base/mapper/TestPlanReportMapper.xml
0 → 100644
浏览文件 @
8d152a07
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"io.metersphere.base.mapper.TestPlanReportMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"io.metersphere.base.domain.TestPlanReport"
>
<id
column=
"id"
jdbcType=
"VARCHAR"
property=
"id"
/>
<result
column=
"test_plan_id"
jdbcType=
"VARCHAR"
property=
"testPlanId"
/>
<result
column=
"create_time"
jdbcType=
"BIGINT"
property=
"createTime"
/>
<result
column=
"update_time"
jdbcType=
"BIGINT"
property=
"updateTime"
/>
<result
column=
"name"
jdbcType=
"VARCHAR"
property=
"name"
/>
<result
column=
"status"
jdbcType=
"VARCHAR"
property=
"status"
/>
<result
column=
"trigger_mode"
jdbcType=
"VARCHAR"
property=
"triggerMode"
/>
<result
column=
"creator"
jdbcType=
"VARCHAR"
property=
"creator"
/>
<result
column=
"start_time"
jdbcType=
"BIGINT"
property=
"startTime"
/>
<result
column=
"end_time"
jdbcType=
"BIGINT"
property=
"endTime"
/>
<result
column=
"is_api_case_executing"
jdbcType=
"BIT"
property=
"isApiCaseExecuting"
/>
<result
column=
"is_scenario_executing"
jdbcType=
"BIT"
property=
"isScenarioExecuting"
/>
<result
column=
"is_performance_executing"
jdbcType=
"BIT"
property=
"isPerformanceExecuting"
/>
<result
column=
"principal"
jdbcType=
"VARCHAR"
property=
"principal"
/>
</resultMap>
<sql
id=
"Example_Where_Clause"
>
<where>
<foreach
collection=
"oredCriteria"
item=
"criteria"
separator=
"or"
>
<if
test=
"criteria.valid"
>
<trim
prefix=
"("
prefixOverrides=
"and"
suffix=
")"
>
<foreach
collection=
"criteria.criteria"
item=
"criterion"
>
<choose>
<when
test=
"criterion.noValue"
>
and ${criterion.condition}
</when>
<when
test=
"criterion.singleValue"
>
and ${criterion.condition} #{criterion.value}
</when>
<when
test=
"criterion.betweenValue"
>
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when
test=
"criterion.listValue"
>
and ${criterion.condition}
<foreach
close=
")"
collection=
"criterion.value"
item=
"listItem"
open=
"("
separator=
","
>
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql
id=
"Update_By_Example_Where_Clause"
>
<where>
<foreach
collection=
"example.oredCriteria"
item=
"criteria"
separator=
"or"
>
<if
test=
"criteria.valid"
>
<trim
prefix=
"("
prefixOverrides=
"and"
suffix=
")"
>
<foreach
collection=
"criteria.criteria"
item=
"criterion"
>
<choose>
<when
test=
"criterion.noValue"
>
and ${criterion.condition}
</when>
<when
test=
"criterion.singleValue"
>
and ${criterion.condition} #{criterion.value}
</when>
<when
test=
"criterion.betweenValue"
>
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when
test=
"criterion.listValue"
>
and ${criterion.condition}
<foreach
close=
")"
collection=
"criterion.value"
item=
"listItem"
open=
"("
separator=
","
>
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql
id=
"Base_Column_List"
>
id, test_plan_id, create_time, update_time, `name`, `status`, trigger_mode, creator,
start_time, end_time, is_api_case_executing, is_scenario_executing, is_performance_executing,
principal
</sql>
<select
id=
"selectByExample"
parameterType=
"io.metersphere.base.domain.TestPlanReportExample"
resultMap=
"BaseResultMap"
>
select
<if
test=
"distinct"
>
distinct
</if>
<include
refid=
"Base_Column_List"
/>
from test_plan_report
<if
test=
"_parameter != null"
>
<include
refid=
"Example_Where_Clause"
/>
</if>
<if
test=
"orderByClause != null"
>
order by ${orderByClause}
</if>
</select>
<select
id=
"selectByPrimaryKey"
parameterType=
"java.lang.String"
resultMap=
"BaseResultMap"
>
select
<include
refid=
"Base_Column_List"
/>
from test_plan_report
where id = #{id,jdbcType=VARCHAR}
</select>
<delete
id=
"deleteByPrimaryKey"
parameterType=
"java.lang.String"
>
delete from test_plan_report
where id = #{id,jdbcType=VARCHAR}
</delete>
<delete
id=
"deleteByExample"
parameterType=
"io.metersphere.base.domain.TestPlanReportExample"
>
delete from test_plan_report
<if
test=
"_parameter != null"
>
<include
refid=
"Example_Where_Clause"
/>
</if>
</delete>
<insert
id=
"insert"
parameterType=
"io.metersphere.base.domain.TestPlanReport"
>
insert into test_plan_report (id, test_plan_id, create_time,
update_time, `name`, `status`,
trigger_mode, creator, start_time,
end_time, is_api_case_executing, is_scenario_executing,
is_performance_executing, principal)
values (#{id,jdbcType=VARCHAR}, #{testPlanId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
#{updateTime,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
#{triggerMode,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR}, #{startTime,jdbcType=BIGINT},
#{endTime,jdbcType=BIGINT}, #{isApiCaseExecuting,jdbcType=BIT}, #{isScenarioExecuting,jdbcType=BIT},
#{isPerformanceExecuting,jdbcType=BIT}, #{principal,jdbcType=VARCHAR})
</insert>
<insert
id=
"insertSelective"
parameterType=
"io.metersphere.base.domain.TestPlanReport"
>
insert into test_plan_report
<trim
prefix=
"("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
id,
</if>
<if
test=
"testPlanId != null"
>
test_plan_id,
</if>
<if
test=
"createTime != null"
>
create_time,
</if>
<if
test=
"updateTime != null"
>
update_time,
</if>
<if
test=
"name != null"
>
`name`,
</if>
<if
test=
"status != null"
>
`status`,
</if>
<if
test=
"triggerMode != null"
>
trigger_mode,
</if>
<if
test=
"creator != null"
>
creator,
</if>
<if
test=
"startTime != null"
>
start_time,
</if>
<if
test=
"endTime != null"
>
end_time,
</if>
<if
test=
"isApiCaseExecuting != null"
>
is_api_case_executing,
</if>
<if
test=
"isScenarioExecuting != null"
>
is_scenario_executing,
</if>
<if
test=
"isPerformanceExecuting != null"
>
is_performance_executing,
</if>
<if
test=
"principal != null"
>
principal,
</if>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"id != null"
>
#{id,jdbcType=VARCHAR},
</if>
<if
test=
"testPlanId != null"
>
#{testPlanId,jdbcType=VARCHAR},
</if>
<if
test=
"createTime != null"
>
#{createTime,jdbcType=BIGINT},
</if>
<if
test=
"updateTime != null"
>
#{updateTime,jdbcType=BIGINT},
</if>
<if
test=
"name != null"
>
#{name,jdbcType=VARCHAR},
</if>
<if
test=
"status != null"
>
#{status,jdbcType=VARCHAR},
</if>
<if
test=
"triggerMode != null"
>
#{triggerMode,jdbcType=VARCHAR},
</if>
<if
test=
"creator != null"
>
#{creator,jdbcType=VARCHAR},
</if>
<if
test=
"startTime != null"
>
#{startTime,jdbcType=BIGINT},
</if>
<if
test=
"endTime != null"
>
#{endTime,jdbcType=BIGINT},
</if>
<if
test=
"isApiCaseExecuting != null"
>
#{isApiCaseExecuting,jdbcType=BIT},
</if>
<if
test=
"isScenarioExecuting != null"
>
#{isScenarioExecuting,jdbcType=BIT},
</if>
<if
test=
"isPerformanceExecuting != null"
>
#{isPerformanceExecuting,jdbcType=BIT},
</if>
<if
test=
"principal != null"
>
#{principal,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select
id=
"countByExample"
parameterType=
"io.metersphere.base.domain.TestPlanReportExample"
resultType=
"java.lang.Long"
>
select count(*) from test_plan_report
<if
test=
"_parameter != null"
>
<include
refid=
"Example_Where_Clause"
/>
</if>
</select>
<update
id=
"updateByExampleSelective"
parameterType=
"map"
>
update test_plan_report
<set>
<if
test=
"record.id != null"
>
id = #{record.id,jdbcType=VARCHAR},
</if>
<if
test=
"record.testPlanId != null"
>
test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
</if>
<if
test=
"record.createTime != null"
>
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
<if
test=
"record.updateTime != null"
>
update_time = #{record.updateTime,jdbcType=BIGINT},
</if>
<if
test=
"record.name != null"
>
`name` = #{record.name,jdbcType=VARCHAR},
</if>
<if
test=
"record.status != null"
>
`status` = #{record.status,jdbcType=VARCHAR},
</if>
<if
test=
"record.triggerMode != null"
>
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
</if>
<if
test=
"record.creator != null"
>
creator = #{record.creator,jdbcType=VARCHAR},
</if>
<if
test=
"record.startTime != null"
>
start_time = #{record.startTime,jdbcType=BIGINT},
</if>
<if
test=
"record.endTime != null"
>
end_time = #{record.endTime,jdbcType=BIGINT},
</if>
<if
test=
"record.isApiCaseExecuting != null"
>
is_api_case_executing = #{record.isApiCaseExecuting,jdbcType=BIT},
</if>
<if
test=
"record.isScenarioExecuting != null"
>
is_scenario_executing = #{record.isScenarioExecuting,jdbcType=BIT},
</if>
<if
test=
"record.isPerformanceExecuting != null"
>
is_performance_executing = #{record.isPerformanceExecuting,jdbcType=BIT},
</if>
<if
test=
"record.principal != null"
>
principal = #{record.principal,jdbcType=VARCHAR},
</if>
</set>
<if
test=
"_parameter != null"
>
<include
refid=
"Update_By_Example_Where_Clause"
/>
</if>
</update>
<update
id=
"updateByExample"
parameterType=
"map"
>
update test_plan_report
set id = #{record.id,jdbcType=VARCHAR},
test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
`name` = #{record.name,jdbcType=VARCHAR},
`status` = #{record.status,jdbcType=VARCHAR},
trigger_mode = #{record.triggerMode,jdbcType=VARCHAR},
creator = #{record.creator,jdbcType=VARCHAR},
start_time = #{record.startTime,jdbcType=BIGINT},
end_time = #{record.endTime,jdbcType=BIGINT},
is_api_case_executing = #{record.isApiCaseExecuting,jdbcType=BIT},
is_scenario_executing = #{record.isScenarioExecuting,jdbcType=BIT},
is_performance_executing = #{record.isPerformanceExecuting,jdbcType=BIT},
principal = #{record.principal,jdbcType=VARCHAR}
<if
test=
"_parameter != null"
>
<include
refid=
"Update_By_Example_Where_Clause"
/>
</if>
</update>
<update
id=
"updateByPrimaryKeySelective"
parameterType=
"io.metersphere.base.domain.TestPlanReport"
>
update test_plan_report
<set>
<if
test=
"testPlanId != null"
>
test_plan_id = #{testPlanId,jdbcType=VARCHAR},
</if>
<if
test=
"createTime != null"
>
create_time = #{createTime,jdbcType=BIGINT},
</if>
<if
test=
"updateTime != null"
>
update_time = #{updateTime,jdbcType=BIGINT},
</if>
<if
test=
"name != null"
>
`name` = #{name,jdbcType=VARCHAR},
</if>
<if
test=
"status != null"
>
`status` = #{status,jdbcType=VARCHAR},
</if>
<if
test=
"triggerMode != null"
>
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
</if>
<if
test=
"creator != null"
>
creator = #{creator,jdbcType=VARCHAR},
</if>
<if
test=
"startTime != null"
>
start_time = #{startTime,jdbcType=BIGINT},
</if>
<if
test=
"endTime != null"
>
end_time = #{endTime,jdbcType=BIGINT},
</if>
<if
test=
"isApiCaseExecuting != null"
>
is_api_case_executing = #{isApiCaseExecuting,jdbcType=BIT},
</if>
<if
test=
"isScenarioExecuting != null"
>
is_scenario_executing = #{isScenarioExecuting,jdbcType=BIT},
</if>
<if
test=
"isPerformanceExecuting != null"
>
is_performance_executing = #{isPerformanceExecuting,jdbcType=BIT},
</if>
<if
test=
"principal != null"
>
principal = #{principal,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update
id=
"updateByPrimaryKey"
parameterType=
"io.metersphere.base.domain.TestPlanReport"
>
update test_plan_report
set test_plan_id = #{testPlanId,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
`name` = #{name,jdbcType=VARCHAR},
`status` = #{status,jdbcType=VARCHAR},
trigger_mode = #{triggerMode,jdbcType=VARCHAR},
creator = #{creator,jdbcType=VARCHAR},
start_time = #{startTime,jdbcType=BIGINT},
end_time = #{endTime,jdbcType=BIGINT},
is_api_case_executing = #{isApiCaseExecuting,jdbcType=BIT},
is_scenario_executing = #{isScenarioExecuting,jdbcType=BIT},
is_performance_executing = #{isPerformanceExecuting,jdbcType=BIT},
principal = #{principal,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>
\ No newline at end of file
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.java
浏览文件 @
8d152a07
...
...
@@ -17,4 +17,6 @@ public interface ExtTestPlanApiCaseMapper {
List
<
String
>
getIdsByPlanId
(
String
planId
);
List
<
String
>
getNotRelevanceCaseIds
(
@Param
(
"planId"
)
String
planId
,
@Param
(
"relevanceProjectIds"
)
List
<
String
>
relevanceProjectIds
);
List
<
String
>
getStatusByTestPlanId
(
String
id
);
}
\ No newline at end of file
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanApiCaseMapper.xml
浏览文件 @
8d152a07
...
...
@@ -125,5 +125,8 @@
</if>
where t.test_plan_id = #{planId}
</select>
<select
id=
"getStatusByTestPlanId"
resultType=
"java.lang.String"
>
SELECT `status` FROM test_plan_api_case WHERE test_plan_id = #{0}
</select>
</mapper>
\ No newline at end of file
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.java
浏览文件 @
8d152a07
...
...
@@ -26,4 +26,10 @@ public interface ExtTestPlanMapper {
List
<
TestPlanDTO
>
selectTestPlanByRelevancy
(
@Param
(
"request"
)
QueryTestPlanRequest
params
);
int
checkIsHave
(
@Param
(
"planId"
)
String
planId
,
@Param
(
"workspaceIds"
)
Set
<
String
>
workspaceIds
);
String
findTestProjectNameByTestPlanID
(
String
testPlanId
);
String
findScheduleCreateUserById
(
String
testPlanId
);
List
<
String
>
findIdByPerformanceReportId
(
String
reportId
);
}
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanMapper.xml
浏览文件 @
8d152a07
...
...
@@ -222,4 +222,19 @@
</if>
</where>
</select>
<select
id=
"findTestProjectNameByTestPlanID"
resultType=
"java.lang.String"
>
SELECT p.name FROM TEST_PLAN tp INNER JOIN project p ON p.id =tp.project_id
WHERE tp.id = #{0} limit 1;
</select>
<select
id=
"findScheduleCreateUserById"
resultType=
"java.lang.String"
>
SELECT user_id FROM `schedule`
WHERE resource_id = #{0}
limit 1;
</select>
<select
id=
"findIdByPerformanceReportId"
resultType=
"java.lang.String"
>
SELECT report.id FROM test_plan_report report INNER JOIN test_plan_report_data reportData ON report.id = reportData.test_plan_report_id
WHERE reportData.performance_info like CONCAT('%', #{0}'%')
</select>
</mapper>
\ No newline at end of file
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.base.mapper.ext
;
import
io.metersphere.track.dto.TestPlanReportDTO
;
import
io.metersphere.track.request.report.QueryTestPlanReportRequest
;
import
org.springframework.data.repository.query.Param
;
import
java.util.List
;
/**
* @author song.tianyang
* @Date 2021/1/8 4:58 下午
* @Description
*/
public
interface
ExtTestPlanReportMapper
{
public
List
<
TestPlanReportDTO
>
list
(
@Param
(
"request"
)
QueryTestPlanReportRequest
request
);
}
backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml
0 → 100644
浏览文件 @
8d152a07
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper
namespace=
"io.metersphere.base.mapper.ext.ExtTestPlanReportMapper"
>
<select
id=
"list"
resultType=
"io.metersphere.track.dto.TestPlanReportDTO"
parameterType=
"io.metersphere.track.request.report.QueryTestPlanReportRequest"
>
SELECT tpr.id AS id, tpr.`name` AS `name`, tp.`name` AS testPlanName, tpr.creator AS creator, tpr.create_time AS createTime,tpr.trigger_Mode AS triggerMode
FROM test_plan tp
INNER JOIN test_plan_report tpr on tp.id = tpr.test_plan_id
-- INNER JOIN
<where>
<if
test=
"name != null"
>
and tpr.name like CONCAT('%', #{name},'%')
</if>
<if
test=
"projectId != null"
>
AND tp.project_id = #{projectId}
</if>
<if
test=
"testPlanName != null"
>
AND tp.name like CONCAT('%', #{testPlanName},'%')
</if>
<if
test=
"creator != null"
>
AND tpr.creator = #{creator}
</if>
</where>
<if
test=
"orders != null and orders.size() > 0"
>
order by
<foreach
collection=
"orders"
separator=
","
item=
"order"
>
tpr.${order.name} ${order.type}
</foreach>
</if>
</select>
</mapper>
\ No newline at end of file
backend/src/main/java/io/metersphere/commons/constants/ApiRunMode.java
浏览文件 @
8d152a07
package
io.metersphere.commons.constants
;
public
enum
ApiRunMode
{
RUN
,
DEBUG
,
DELIMIT
,
SCENARIO
,
API_PLAN
,
SCENARIO_PLAN
,
API
RUN
,
DEBUG
,
DELIMIT
,
SCENARIO
,
API_PLAN
,
SCENARIO_PLAN
,
API
,
SCHEDULE_API_PLAN
,
SCHEDULE_SCENARIO_PLAN
,
SCHEDULE_PERFORMANCE_TEST
}
backend/src/main/java/io/metersphere/job/sechedule/TestPlanTestJob.java
浏览文件 @
8d152a07
...
...
@@ -2,46 +2,51 @@ package io.metersphere.job.sechedule;
import
io.metersphere.api.dto.automation.ExecuteType
;
import
io.metersphere.api.dto.automation.RunScenarioRequest
;
import
io.metersphere.api.dto.automation.SchedulePlanScenarioExecuteRequest
;
import
io.metersphere.api.dto.definition.RunCaseRequest
;
import
io.metersphere.api.dto.definition.RunDefinitionRequest
;
import
io.metersphere.api.service.ApiAutomationService
;
import
io.metersphere.api.service.ApiDefinitionService
;
import
io.metersphere.api.service.ApiTestCaseService
;
import
io.metersphere.base.domain.ApiTestCaseWithBLOBs
;
import
io.metersphere.base.domain.TestPlanApiCase
;
import
io.metersphere.base.domain.TestPlanApiScenario
;
import
io.metersphere.base.domain.*
;
import
io.metersphere.commons.constants.ApiRunMode
;
import
io.metersphere.commons.constants.ReportTriggerMode
;
import
io.metersphere.commons.constants.ScheduleGroup
;
import
io.metersphere.commons.consumer.LoadTestFinishEvent
;
import
io.metersphere.commons.utils.CommonBeanFactory
;
import
io.metersphere.commons.utils.LogUtil
;
import
io.metersphere.performance.service.PerformanceTestService
;
import
io.metersphere.track.dto.TestPlanLoadCaseDTO
;
import
io.metersphere.track.request.testplan.LoadCaseRequest
;
import
io.metersphere.track.request.testplan.RunTestPlanRequest
;
import
io.metersphere.track.service.
TestPlanApiCaseService
;
import
io.metersphere.track.service.TestPlanScenarioCaseService
;
import
io.metersphere.track.service.
*
;
import
org.python.antlr.ast.Str
;
import
org.quartz.*
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.UUID
;
import
javax.annotation.Resource
;
import
java.util.*
;
/**
* 情景测试Job
*
* @author song.tianyang
* @Date 2020/12/22 2:59 下午
* @Description
*/
public
class
TestPlanTestJob
extends
MsScheduleJob
{
private
String
projectID
;
private
List
<
String
>
scenarioIds
;
private
List
<
String
>
apiTestCaseIds
;
private
List
<
String
>
performanceIds
;
public
class
TestPlanTestJob
extends
MsScheduleJob
{
private
String
projectID
;
private
Map
<
String
,
String
>
planScenarioIdMap
;
private
Map
<
String
,
String
>
apiTestCaseIdMap
;
private
Map
<
String
,
String
>
performanceIdMap
;
private
ApiAutomationService
apiAutomationService
;
private
PerformanceTestService
performanceTestService
;
private
TestPlanScenarioCaseService
testPlanScenarioCaseService
;
private
TestPlanApiCaseService
testPlanApiCaseService
;
private
ApiTestCaseService
apiTestCaseService
;
private
ApiDefinitionService
apiDefinitionService
;
private
TestPlanReportService
testPlanReportService
;
private
TestPlanLoadCaseService
testPlanLoadCaseService
;
private
LoadReportStatusTask
loadReportStatusTask
;
public
TestPlanTestJob
()
{
this
.
apiAutomationService
=
CommonBeanFactory
.
getBean
(
ApiAutomationService
.
class
);
...
...
@@ -49,11 +54,14 @@ public class TestPlanTestJob extends MsScheduleJob {
this
.
testPlanScenarioCaseService
=
CommonBeanFactory
.
getBean
(
TestPlanScenarioCaseService
.
class
);
this
.
testPlanApiCaseService
=
CommonBeanFactory
.
getBean
(
TestPlanApiCaseService
.
class
);
this
.
apiTestCaseService
=
CommonBeanFactory
.
getBean
(
ApiTestCaseService
.
class
);
apiDefinitionService
=
CommonBeanFactory
.
getBean
(
ApiDefinitionService
.
class
);
this
.
testPlanReportService
=
CommonBeanFactory
.
getBean
(
TestPlanReportService
.
class
);
this
.
testPlanLoadCaseService
=
CommonBeanFactory
.
getBean
(
TestPlanLoadCaseService
.
class
);
this
.
loadReportStatusTask
=
CommonBeanFactory
.
getBean
(
LoadReportStatusTask
.
class
);
}
/**
* 情景部分的准备工作
*
* @param context
* @throws JobExecutionException
*/
...
...
@@ -62,21 +70,31 @@ public class TestPlanTestJob extends MsScheduleJob {
JobKey
jobKey
=
context
.
getTrigger
().
getJobKey
();
JobDataMap
jobDataMap
=
context
.
getJobDetail
().
getJobDataMap
();
this
.
resourceId
=
jobDataMap
.
getString
(
"resourceId"
);
this
.
userId
=
jobDataMap
.
getString
(
"userId"
);
this
.
expression
=
jobDataMap
.
getString
(
"expression"
);
this
.
projectID
=
jobDataMap
.
getString
(
"projectId"
);
scenarioIds
=
new
ArrayList
<>();
String
testPlanID
=
jobDataMap
.
getString
(
"resourceId"
);
List
<
TestPlanApiScenario
>
testPlanApiScenarioList
=
testPlanScenarioCaseService
.
getCasesByPlanId
(
testPlanID
);
for
(
TestPlanApiScenario
model:
testPlanApiScenarioList
)
{
scenarioIds
.
add
(
model
.
getApiScenarioId
());
planScenarioIdMap
=
new
LinkedHashMap
<>();
apiTestCaseIdMap
=
new
LinkedHashMap
<>();
performanceIdMap
=
new
LinkedHashMap
<>();
List
<
TestPlanApiScenario
>
testPlanApiScenarioList
=
testPlanScenarioCaseService
.
getCasesByPlanId
(
this
.
resourceId
);
for
(
TestPlanApiScenario
model
:
testPlanApiScenarioList
)
{
planScenarioIdMap
.
put
(
model
.
getApiScenarioId
(),
model
.
getId
());
}
List
<
TestPlanApiCase
>
testPlanApiCaseList
=
testPlanApiCaseService
.
getCasesByPlanId
(
t
estPlanID
);
List
<
TestPlanApiCase
>
testPlanApiCaseList
=
testPlanApiCaseService
.
getCasesByPlanId
(
t
his
.
resourceId
);
for
(
TestPlanApiCase
model
:
testPlanApiCaseList
)
{
apiTestCaseIds
.
add
(
model
.
getApiCaseId
());
apiTestCaseIdMap
.
put
(
model
.
getApiCaseId
(),
model
.
getId
());
}
LoadCaseRequest
loadCaseRequest
=
new
LoadCaseRequest
();
loadCaseRequest
.
setTestPlanId
(
this
.
resourceId
);
loadCaseRequest
.
setProjectId
(
this
.
projectID
);
List
<
TestPlanLoadCaseDTO
>
testPlanLoadCaseDTOList
=
testPlanLoadCaseService
.
list
(
loadCaseRequest
);
for
(
TestPlanLoadCaseDTO
dto
:
testPlanLoadCaseDTOList
)
{
performanceIdMap
.
put
(
dto
.
getId
(),
dto
.
getLoadCaseId
());
}
businessExecute
(
context
);
...
...
@@ -85,39 +103,67 @@ public class TestPlanTestJob extends MsScheduleJob {
@Override
void
businessExecute
(
JobExecutionContext
context
)
{
LogUtil
.
info
(
"-------------- start testplan schedule ----------"
);
//首先创建testPlanReport,然后返回的ID重新赋值为resourceID,作为后续的参数
TestPlanReport
testPlanReport
=
testPlanReportService
.
genTestPlanReport
(
this
.
resourceId
,
this
.
userId
);
//执行接口案例任务
for
(
String
apiCaseID:
apiTestCaseIds
)
{
for
(
Map
.
Entry
<
String
,
String
>
entry:
this
.
apiTestCaseIdMap
.
entrySet
())
{
String
apiCaseID
=
entry
.
getKey
();
String
planCaseID
=
entry
.
getValue
();
ApiTestCaseWithBLOBs
blobs
=
apiTestCaseService
.
get
(
apiCaseID
);
String
caseReportID
=
UUID
.
randomUUID
().
toString
();
RunDefinitionRequest
apiCaseReqeust
=
new
RunDefinitionRequest
();
apiCaseReqeust
.
setId
(
apiCaseID
);
apiCaseReqeust
.
setReportId
(
caseReportID
);
apiCaseReqeust
.
setProjectId
(
projectID
);
apiCaseReqeust
.
setExecuteType
(
ExecuteType
.
Saved
.
name
());
apiCaseReqeust
.
setType
(
ApiRunMode
.
API_PLAN
.
name
());
apiDefinitionService
.
run
(
apiCaseReqeust
,
blobs
);
//需要更新这里来保证PlanCase的状态能正常更改
apiTestCaseService
.
run
(
blobs
,
UUID
.
randomUUID
().
toString
(),
testPlanReport
.
getId
(),
this
.
resourceId
,
ApiRunMode
.
SCHEDULE_API_PLAN
.
name
());
}
LogUtil
.
info
(
"-------------- testplan schedule ---------- api case over -----------------"
);
//执行场景执行任务
RunScenarioRequest
scenarioRequest
=
new
RunScenario
Request
();
SchedulePlanScenarioExecuteRequest
scenarioRequest
=
new
SchedulePlanScenarioExecute
Request
();
String
senarionReportID
=
UUID
.
randomUUID
().
toString
();
scenarioRequest
.
setId
(
senarionReportID
);
scenarioRequest
.
setReportId
(
senarionReportID
);
scenarioRequest
.
setProjectId
(
projectID
);
scenarioRequest
.
setTriggerMode
(
ReportTriggerMode
.
SCHEDULE
.
name
());
scenarioRequest
.
setExecuteType
(
ExecuteType
.
Saved
.
name
());
scenarioRequest
.
setScenarioIds
(
this
.
scenarioIds
);
Map
<
String
,
Map
<
String
,
String
>>
testPlanScenarioIdMap
=
new
HashMap
<>();
testPlanScenarioIdMap
.
put
(
resourceId
,
this
.
planScenarioIdMap
);
scenarioRequest
.
setTestPlanScenarioIDMap
(
testPlanScenarioIdMap
);
scenarioRequest
.
setReportUserID
(
this
.
userId
);
scenarioRequest
.
setRunMode
(
ApiRunMode
.
SCENARIO_PLAN
.
name
());
scenarioRequest
.
setTestPlanID
(
this
.
resourceId
);
scenarioRequest
.
setRunMode
(
ApiRunMode
.
SCHEDULE_SCENARIO_PLAN
.
name
());
scenarioRequest
.
setTestPlanReportId
(
testPlanReport
.
getId
());
String
reportID
=
apiAutomationService
.
run
(
scenarioRequest
);
LogUtil
.
info
(
"-------------- testplan schedule ---------- scenario case over -----------------"
);
//执行性能测试任务 --- 保留,待功能实现后再继续
// RunTestPlanRequest performanceRequest = new RunTestPlanRequest();
// performanceRequest.setId(resourceId);
// performanceRequest.setUserId(userId);
// performanceRequest.setTriggerMode(ReportTriggerMode.SCHEDULE.name());
// performanceTestService.run(performanceRequest);
//执行性能测试任务
boolean
havePerformanceTask
=
false
;
List
<
String
>
performaneReportIDList
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
String
,
String
>
entry:
this
.
performanceIdMap
.
entrySet
())
{
String
id
=
entry
.
getKey
();
String
caseID
=
entry
.
getValue
();
RunTestPlanRequest
performanceRequest
=
new
RunTestPlanRequest
();
performanceRequest
.
setId
(
id
);
performanceRequest
.
setTestPlanLoadId
(
caseID
);
performanceRequest
.
setTriggerMode
(
ReportTriggerMode
.
SCHEDULE
.
name
());
String
reportId
=
null
;
havePerformanceTask
=
true
;
try
{
reportId
=
performanceTestService
.
run
(
performanceRequest
);
}
catch
(
Exception
e
){
}
if
(
reportID
!=
null
){
TestPlanLoadCase
testPlanLoadCase
=
new
TestPlanLoadCase
();
testPlanLoadCase
.
setId
(
performanceRequest
.
getTestPlanLoadId
());
testPlanLoadCase
.
setLoadReportId
(
reportId
);
testPlanLoadCaseService
.
update
(
testPlanLoadCase
);
performaneReportIDList
.
add
(
reportID
);
}
}
if
(!
performaneReportIDList
.
isEmpty
()){
//性能测试时保存性能测试报告ID,在结果返回时用于捕捉并进行
testPlanReportService
.
updatePerformanceInfo
(
testPlanReport
,
performaneReportIDList
);
}
}
public
static
JobKey
getJobKey
(
String
testId
)
{
...
...
backend/src/main/java/io/metersphere/track/controller/TestPlanReportController.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.track.controller
;
import
com.github.pagehelper.Page
;
import
com.github.pagehelper.PageHelper
;
import
io.metersphere.base.domain.TestCaseReport
;
import
io.metersphere.base.domain.TestPlanReport
;
import
io.metersphere.commons.utils.PageUtils
;
import
io.metersphere.commons.utils.Pager
;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.track.dto.TestCaseReportMetricDTO
;
import
io.metersphere.track.dto.TestPlanDTOWithMetric
;
import
io.metersphere.track.dto.TestPlanReportDTO
;
import
io.metersphere.track.request.report.QueryTestPlanReportRequest
;
import
io.metersphere.track.request.testcase.QueryTestPlanRequest
;
import
io.metersphere.track.service.TestPlanReportService
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* @author song.tianyang
* @Date 2021/1/8 2:38 下午
* @Description
*/
@RequestMapping
(
"/test/plan/report"
)
@RestController
public
class
TestPlanReportController
{
@Resource
private
TestPlanReportService
testPlanReportService
;
@PostMapping
(
"/list/{goPage}/{pageSize}"
)
public
Pager
<
List
<
TestPlanReportDTO
>>
list
(
@PathVariable
int
goPage
,
@PathVariable
int
pageSize
,
@RequestBody
QueryTestPlanReportRequest
request
)
{
String
currentWorkspaceId
=
SessionUtils
.
getCurrentWorkspaceId
();
request
.
setWorkspaceId
(
currentWorkspaceId
);
Page
<
Object
>
page
=
PageHelper
.
startPage
(
goPage
,
pageSize
,
true
);
return
PageUtils
.
setPageInfo
(
page
,
testPlanReportService
.
list
(
request
));
}
@GetMapping
(
"/getMetric/{planId}"
)
public
TestPlanReportDTO
getMetric
(
@PathVariable
String
planId
)
{
return
testPlanReportService
.
getMetric
(
planId
);
}
@GetMapping
(
"/sendTask/{planId}"
)
public
String
sendTask
(
@PathVariable
String
planId
)
{
TestPlanReport
report
=
testPlanReportService
.
getTestPlanReport
(
planId
);
testPlanReportService
.
update
(
report
);
return
"sucess"
;
}
@PostMapping
(
"/delete"
)
public
void
delete
(
@RequestBody
List
<
String
>
testPlanReportIdList
)
{
testPlanReportService
.
delete
(
testPlanReportIdList
);
}
}
backend/src/main/java/io/metersphere/track/dto/TestPlanReportDTO.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.track.dto
;
import
io.metersphere.base.domain.Issues
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.util.List
;
/**
* @author song.tianyang
* @Date 2021/1/8 2:39 下午
* @Description
*/
@Getter
@Setter
public
class
TestPlanReportDTO
{
private
String
id
;
private
String
name
;
private
String
testPlanName
;
private
String
creator
;
private
String
createTime
;
private
String
triggerMode
;
private
TestCaseReportAdvanceStatusResultDTO
executeResult
;
private
List
<
TestCaseReportModuleResultDTO
>
moduleExecuteResult
;
private
FailureTestCasesAdvanceDTO
failureTestCases
;
private
List
<
Issues
>
Issues
;
private
List
<
String
>
executors
;
private
String
principal
;
private
Long
startTime
;
private
Long
endTime
;
private
String
projectName
;
}
\ No newline at end of file
backend/src/main/java/io/metersphere/track/request/report/QueryTestPlanReportRequest.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.track.request.report
;
import
io.metersphere.controller.request.OrderRequest
;
import
lombok.Data
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author song.tianyang
* @Date 2021/1/8 4:36 下午
* @Description
*/
@Getter
@Setter
@Data
public
class
QueryTestPlanReportRequest
{
private
String
name
;
private
String
testPlanName
;
private
String
creator
;
private
String
workspaceId
;
private
String
projectId
;
private
List
<
OrderRequest
>
orders
;
private
Map
<
String
,
List
<
String
>>
filters
;
// private Map<String, Object> combine;
}
backend/src/main/java/io/metersphere/track/service/TestPlanApiCaseService.java
浏览文件 @
8d152a07
...
...
@@ -107,6 +107,10 @@ public class TestPlanApiCaseService {
return
testPlanApiCaseMapper
.
selectByExample
(
example
);
}
public
TestPlanApiCase
getById
(
String
id
)
{
return
testPlanApiCaseMapper
.
selectByPrimaryKey
(
id
);
}
public
void
setExecResult
(
String
id
,
String
status
)
{
TestPlanApiCase
apiCase
=
new
TestPlanApiCase
();
apiCase
.
setId
(
id
);
...
...
@@ -114,6 +118,10 @@ public class TestPlanApiCaseService {
testPlanApiCaseMapper
.
updateByPrimaryKeySelective
(
apiCase
);
}
public
void
updateByPrimaryKeySelective
(
TestPlanApiCase
apiCase
)
{
testPlanApiCaseMapper
.
updateByPrimaryKeySelective
(
apiCase
);
}
public
void
deleteByRelevanceProjectIds
(
String
planId
,
List
<
String
>
relevanceProjectIds
)
{
TestPlanApiCaseBatchRequest
request
=
new
TestPlanApiCaseBatchRequest
();
request
.
setPlanId
(
planId
);
...
...
backend/src/main/java/io/metersphere/track/service/TestPlanLoadCaseEvent.java
0 → 100644
浏览文件 @
8d152a07
package
io.metersphere.track.service
;
import
io.metersphere.base.domain.LoadTestReport
;
import
io.metersphere.base.domain.TestPlanReport
;
import
io.metersphere.commons.constants.NoticeConstants
;
import
io.metersphere.commons.constants.PerformanceTestStatus
;
import
io.metersphere.commons.consumer.LoadTestFinishEvent
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
/**
* @author song.tianyang
* @Date 2021/1/13 2:53 下午
* @Description
*/
@Service
public
class
TestPlanLoadCaseEvent
implements
LoadTestFinishEvent
{
@Resource
TestPlanReportService
testPlanReportService
;
@Override
public
void
execute
(
LoadTestReport
loadTestReport
)
{
if
(
StringUtils
.
equals
(
NoticeConstants
.
Mode
.
SCHEDULE
,
loadTestReport
.
getTriggerMode
())
)
{
if
(
StringUtils
.
equalsAny
(
loadTestReport
.
getStatus
(),
PerformanceTestStatus
.
Completed
.
name
(),
PerformanceTestStatus
.
Error
.
name
()))
{
testPlanReportService
.
updatePerformanceTestStatus
(
loadTestReport
.
getId
());
}
}
}
}
backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java
0 → 100644
浏览文件 @
8d152a07
此差异已折叠。
点击以展开。
backend/src/main/java/io/metersphere/track/service/TestPlanService.java
浏览文件 @
8d152a07
...
...
@@ -720,4 +720,12 @@ public class TestPlanService {
public
List
<
TestPlanDTO
>
selectTestPlanByRelevancy
(
QueryTestPlanRequest
params
){
return
extTestPlanMapper
.
selectTestPlanByRelevancy
(
params
);
}
public
String
findTestProjectNameByTestPlanID
(
String
testPlanId
)
{
return
extTestPlanMapper
.
findTestProjectNameByTestPlanID
(
testPlanId
);
}
public
String
findScheduleCreateUserById
(
String
testPlanId
)
{
return
extTestPlanMapper
.
findScheduleCreateUserById
(
testPlanId
);
}
}
backend/src/main/resources/db/migration/V66__init_test_plan_report.sql
0 → 100644
浏览文件 @
8d152a07
CREATE
TABLE
IF
NOT
EXISTS
`test_plan_report`
(
`id`
VARCHAR
(
50
)
NOT
NULL
COMMENT
'ID'
,
`test_plan_id`
VARCHAR
(
50
)
NOT
NULL
COMMENT
'Test plan ID'
,
`create_time`
BIGINT
(
13
)
NOT
NULL
COMMENT
'Create timestamp'
,
`update_time`
BIGINT
(
13
)
NOT
NULL
COMMENT
'Update timestamp'
,
`name`
VARCHAR
(
64
)
DEFAULT
NULL
COMMENT
'name'
,
`status`
VARCHAR
(
50
)
DEFAULT
NULL
COMMENT
'report status'
,
`trigger_mode`
VARCHAR
(
50
)
DEFAULT
NULL
COMMENT
'test plan execute triggerMode'
,
`creator`
VARCHAR
(
50
)
DEFAULT
NULL
COMMENT
'report creator'
,
`start_time`
BIGINT
(
13
)
DEFAULT
NULL
COMMENT
'report startTime'
,
`end_time`
BIGINT
(
13
)
DEFAULT
NULL
COMMENT
'report timestamp'
,
`is_api_case_executing`
TINYINT
NOT
NULL
COMMENT
'is Api Case executing'
,
`is_scenario_executing`
TINYINT
NOT
NULL
COMMENT
'is scenario Case executing'
,
`is_performance_executing`
TINYINT
NOT
NULL
COMMENT
'is performance executing'
,
`principal`
VARCHAR
(
50
)
DEFAULT
NULL
COMMENT
'principal'
,
PRIMARY
KEY
(
`id`
),
UNIQUE
KEY
`executeInfoID`
(
`test_plan_id`
,
`create_time`
)
)
ENGINE
=
INNODB
DEFAULT
CHARSET
=
utf8mb4
;
CREATE
TABLE
IF
NOT
EXISTS
`test_plan_report_data`
(
`id`
VARCHAR
(
50
)
NOT
NULL
COMMENT
'ID'
,
`test_plan_report_id`
VARCHAR
(
50
)
NOT
NULL
COMMENT
'Test plan ID'
,
`execute_result`
LONGTEXT
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
COMMENT
'executeResult (JSON format)'
,
`failur_test_cases`
LONGTEXT
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
COMMENT
'failurTestCases (JSON format)'
,
`module_execute_result`
LONGTEXT
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
COMMENT
'moduleExecuteResult (JSON format)'
,
`api_case_info`
LONGTEXT
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
COMMENT
'apiCaseID list (JSON format)'
,
`scenario_info`
LONGTEXT
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
COMMENT
'scenarioID list (JSON format)'
,
`performance_info`
LONGTEXT
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
COMMENT
'performanceID list (JSON format)'
,
`issues_info`
LONGTEXT
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
COMMENT
'issues (JSON format)'
,
PRIMARY
KEY
(
`id`
),
UNIQUE
KEY
`test_plan_report_id`
(
`test_plan_report_id`
)
)
ENGINE
=
INNODB
DEFAULT
CHARSET
=
utf8mb4
;
\ No newline at end of file
frontend/package.json
浏览文件 @
8d152a07
...
...
@@ -15,7 +15,7 @@
"@fortawesome/free-regular-svg-icons"
:
"^5.12.0"
,
"@fortawesome/free-solid-svg-icons"
:
"^5.12.0"
,
"@fortawesome/vue-fontawesome"
:
"^0.1.9"
,
"axios"
:
"^0.
19.0
"
,
"axios"
:
"^0.
21.1
"
,
"core-js"
:
"^3.4.3"
,
"diffable-html"
:
"^4.0.0"
,
"echarts"
:
"^4.6.0"
,
...
...
@@ -39,14 +39,14 @@
"vue-float-action-button"
:
"^0.6.6"
,
"vue-i18n"
:
"^8.15.3"
,
"vue-input-tag"
:
"^2.0.7"
,
"vue-jsonpath-picker"
:
"^1.1.5"
,
"vue-papa-parse"
:
"^2.0.0"
,
"vue-pdf"
:
"^4.2.0"
,
"vue-router"
:
"^3.1.3"
,
"vuedraggable"
:
"^2.23.2"
,
"vuex"
:
"^3.1.2"
,
"xml-js"
:
"^1.6.11"
,
"yan-progress"
:
"^1.0.3"
,
"vue-jsonpath-picker"
:
"^1.1.5"
"yan-progress"
:
"^1.0.3"
},
"devDependencies"
:
{
"@vue/cli-plugin-babel"
:
"^4.1.0"
,
...
...
frontend/src/business/components/common/components/search/search-components.js
浏览文件 @
8d152a07
...
...
@@ -88,6 +88,14 @@ export const TEST_NAME = {
options
:
[
OPERATORS
.
LIKE
,
OPERATORS
.
NOT_LIKE
]
},
}
export
const
TEST_PLAN_NAME
=
{
key
:
"
testPlanName
"
,
name
:
'
MsTableSearchInput
'
,
label
:
'
test_track.report.list.test_plan
'
,
operator
:
{
options
:
[
OPERATORS
.
LIKE
,
OPERATORS
.
NOT_LIKE
]
},
}
export
const
CREATE_TIME
=
{
key
:
"
createTime
"
,
name
:
'
MsTableSearchDateTimePicker
'
,
...
...
@@ -406,6 +414,22 @@ export const TEST_PLAN_STATUS = {
}
};
export
const
TEST_PLAN_TRIGGER_MODE
=
{
key
:
"
triggerMode
"
,
name
:
'
MsTableSearchSelect
'
,
label
:
"
test_track.report.list.trigger_mode
"
,
operator
:
{
options
:
[
OPERATORS
.
IN
,
OPERATORS
.
NOT_IN
]
},
options
:
[
{
label
:
'
test_track.report.trigger_mode.manual
'
,
value
:
'
manual
'
},
{
label
:
'
test_track.report.trigger_mode.automation
'
,
value
:
'
automation
'
},
],
props
:
{
multiple
:
true
}
};
export
const
TEST_CONFIGS
=
[
NAME
,
UPDATE_TIME
,
CREATE_TIME
,
STATUS
,
CREATOR
];
export
const
REPORT_CONFIGS
=
[
NAME
,
TEST_NAME
,
CREATE_TIME
,
STATUS
,
CREATOR
,
TRIGGER_MODE
];
...
...
@@ -417,3 +441,5 @@ export const TEST_PLAN_CONFIGS = [NAME, UPDATE_TIME, CREATE_TIME, PRINCIPAL, TES
export
const
API_DEFINITION_CONFIGS
=
[
NAME
,
API_METHOD
,
API_PATH
,
API_STATUS
,
API_TAGS
,
UPDATE_TIME
,
CREATE_TIME
,
CREATOR
];
export
const
API_CASE_CONFIGS
=
[
NAME
,
API_CASE_PRIORITY
,
API_TAGS
,
API_CASE_RESULT
,
UPDATE_TIME
,
CREATE_TIME
,
CREATOR
];
export
const
TEST_PLAN_REPORT_CONFIGS
=
[
NAME
,
TEST_PLAN_NAME
,
CREATOR
,
CREATE_TIME
,
TEST_PLAN_TRIGGER_MODE
,
TEST_PLAN_STATUS
];
frontend/src/business/components/track/head/TrackHeaderMenus.vue
浏览文件 @
8d152a07
...
...
@@ -41,6 +41,10 @@
<ms-create-button
v-permission=
"['test_manager','test_user']"
:index=
"'/track/plan/create'"
:title=
"$t('test_track.plan.create_plan')"
/>
</el-submenu>
<el-menu-item
:index=
"'/track/testPlan/reportList'"
>
{{ $t("commons.report") }}
</el-menu-item>
</el-menu>
</el-col>
<el-col
:span=
"8"
/>
...
...
frontend/src/business/components/track/plan/components/TestPlanList.vue
浏览文件 @
8d152a07
...
...
@@ -129,7 +129,7 @@
</
template
>
</ms-table-operator>
<ms-table-operator-button
style=
"margin-left: 10px;color:#6C317C"
type=
""
:tip=
"$t('
test_track.plan_view.view_report
')"
icon=
"el-icon-time"
:tip=
"$t('
commons.trigger_mode.schedule
')"
icon=
"el-icon-time"
@
exec=
"scheduleTask(scope.row)"
/>
</template>
</el-table-column>
...
...
frontend/src/business/components/track/plan/view/comonents/api/TestPlanApiScenarioList.vue
浏览文件 @
8d152a07
...
...
@@ -180,7 +180,9 @@
},
buildExecuteParam
(
row
)
{
let
param
=
{};
param
.
id
=
row
.
id
;
// param.id = row.id;
param
.
id
=
getUUID
();
param
.
planScenarioId
=
row
.
id
;
param
.
projectId
=
row
.
projectId
;
param
.
planCaseIds
=
[];
param
.
planCaseIds
.
push
(
row
.
id
);
...
...
frontend/src/business/components/track/report/TestPlanReport.vue
0 → 100644
浏览文件 @
8d152a07
<
template
>
<ms-container>
<ms-main-container>
<test-plan-report-list
ref=
"testPlanReportList"
/>
</ms-main-container>
</ms-container>
</
template
>
<
script
>
import
TestPlanReportList
from
'
./components/TestPlanReportList
'
;
import
MsContainer
from
"
../../common/components/MsContainer
"
;
import
MsMainContainer
from
"
../../common/components/MsMainContainer
"
;
import
{
getCurrentProjectID
}
from
"
../../../../common/js/utils
"
;
export
default
{
name
:
"
TestPlanReport
"
,
components
:
{
MsMainContainer
,
MsContainer
,
TestPlanReportList
},
data
()
{
return
{}
},
activated
()
{
// this.refreshTestPlanList();
},
mounted
()
{
this
.
refreshTestPlanList
();
},
watch
:
{
'
$route
'
(
to
,
from
)
{
}
},
methods
:
{
refreshTestPlanList
()
{
this
.
$refs
.
testPlanReportList
.
condition
=
{};
this
.
$refs
.
testPlanReportList
.
initTableData
();
}
}
}
</
script
>
<
style
scoped
>
</
style
>
frontend/src/business/components/track/report/components/TestPlanReportExport.vue
0 → 100644
浏览文件 @
8d152a07
<
template
>
<ms-report-export-template
:title=
"title"
:type=
"$t('report.test_plan_report')"
>
<div
v-for=
"(item, index) in previews"
:key=
"item.id"
>
<template-component
:isReportView=
"true"
:metric=
"metric"
:preview=
"item"
:index=
"index"
ref=
"templateComponent"
/>
</div>
</ms-report-export-template>
</
template
>
<
script
>
import
MsReportExportTemplate
from
"
@/business/components/common/components/report/MsReportExportTemplate
"
;
import
TemplateComponent
from
"
@/business/components/track/plan/view/comonents/report/TemplateComponent/TemplateComponent
"
;
import
MsReportTitle
from
"
@/business/components/common/components/report/MsReportTitle
"
;
export
default
{
name
:
"
MsTestPlanReportExport
"
,
components
:
{
MsReportTitle
,
TemplateComponent
,
MsReportExportTemplate
},
props
:
[
'
previews
'
,
'
title
'
,
'
metric
'
]
}
</
script
>
<
style
scoped
>
.report-export
>>>
.template-component
{
width
:
99%
;
margin-top
:
30px
;
margin-bottom
:
30px
;
}
.report-export
>>>
.report-title
{
margin-bottom
:
50px
;
}
</
style
>
frontend/src/business/components/track/report/components/TestPlanReportList.vue
0 → 100644
浏览文件 @
8d152a07
<
template
>
<el-card
class=
"table-card"
v-loading=
"result.loading"
>
<template
v-slot:header
>
<ms-table-header
:is-tester-permission=
"true"
:condition.sync=
"condition"
:show-create=
"false"
@
search=
"initTableData"
:title=
"$t('test_track.report.name')"
/>
</
template
>
<el-table
border
class=
"adjust-table"
:data=
"tableData"
@
filter-change=
"filter"
@
sort-change=
"sort"
>
<el-table-column
min-width=
"300"
prop=
"name"
:label=
"$t('test_track.report.list.name')"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"testPlanName"
:label=
"$t('test_track.report.list.test_plan')"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"creator"
:label=
"$t('test_track.report.list.creator')"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"createTime"
:label=
"$t('test_track.report.list.create_time' )"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"triggerMode"
:label=
"$t('test_track.report.list.trigger_mode')"
show-overflow-tooltip
></el-table-column>
<el-table-column
min-width=
"150"
:label=
"$t('commons.operating')"
>
<
template
v-slot:default=
"scope"
>
<ms-table-operator-button
type=
"success"
:tip=
"$t('test_track.plan_view.view_report')"
icon=
"el-icon-document"
@
exec=
"openReport(scope.row.id)"
/>
<ms-table-operator-button
type=
"danger"
:tip=
"$t('commons.delete')"
icon=
"el-icon-delete"
@
exec=
"handleDelete(scope.row)"
/>
</
template
>
</el-table-column>
</el-table>
<ms-table-pagination
:change=
"initTableData"
:current-page.sync=
"currentPage"
:page-size.sync=
"pageSize"
:total=
"total"
/>
<test-plan-report-view
@
refresh=
"initTableData"
ref=
"testPlanReportView"
/>
<!-- <ms-delete-confirm :title="$t('test_track.plan.plan_delete')" @delete="_handleDelete" ref="deleteConfirm"-->
<!-- :with-tip="enableDeleteTip">-->
<!-- {{ $t('test_track.plan.plan_delete_tip') }}-->
<!-- </ms-delete-confirm>-->
</el-card>
</template>
<
script
>
import
MsTablePagination
from
'
../../../../components/common/pagination/TablePagination
'
;
import
MsTableHeader
from
"
@/business/components/common/components/MsTableHeader
"
;
import
MsTableOperatorButton
from
"
../../../common/components/MsTableOperatorButton
"
;
import
MsTableOperator
from
"
../../../common/components/MsTableOperator
"
;
import
{
_filter
,
_sort
,
checkoutTestManagerOrTestUser
}
from
"
@/common/js/utils
"
;
import
{
TEST_PLAN_REPORT_CONFIGS
}
from
"
../../../common/components/search/search-components
"
;
import
{
getCurrentProjectID
}
from
"
../../../../../common/js/utils
"
;
import
TestPlanReportView
from
"
@/business/components/track/report/components/TestPlanReportView
"
;
export
default
{
name
:
"
TestPlanReportList
"
,
components
:
{
TestPlanReportView
,
MsTableOperator
,
MsTableOperatorButton
,
MsTableHeader
,
MsTablePagination
},
data
()
{
return
{
result
:
{},
enableDeleteTip
:
false
,
queryPath
:
"
/test/plan/report/list
"
,
condition
:
{
components
:
TEST_PLAN_REPORT_CONFIGS
},
currentPage
:
1
,
pageSize
:
10
,
isTestManagerOrTestUser
:
false
,
total
:
0
,
tableData
:
[],
statusFilters
:
[
{
text
:
this
.
$t
(
'
test_track.plan.plan_status_prepare
'
),
value
:
'
Prepare
'
},
{
text
:
this
.
$t
(
'
test_track.plan.plan_status_running
'
),
value
:
'
Underway
'
},
{
text
:
this
.
$t
(
'
test_track.plan.plan_status_completed
'
),
value
:
'
Completed
'
}
],
stageFilters
:
[
{
text
:
this
.
$t
(
'
test_track.plan.smoke_test
'
),
value
:
'
smoke
'
},
{
text
:
this
.
$t
(
'
test_track.plan.system_test
'
),
value
:
'
system
'
},
{
text
:
this
.
$t
(
'
test_track.plan.regression_test
'
),
value
:
'
regression
'
},
],
}
},
watch
:
{
'
$route
'
(
to
,
from
)
{
// if (to.path.indexOf("/track/plan/all") >= 0) {
// this.initTableData();
// }
}
},
activated
()
{
this
.
components
=
TEST_PLAN_REPORT_CONFIGS
;
},
created
()
{
this
.
projectId
=
this
.
$route
.
params
.
projectId
;
this
.
isTestManagerOrTestUser
=
checkoutTestManagerOrTestUser
();
this
.
initTableData
();
},
methods
:
{
initTableData
()
{
if
(
this
.
planId
)
{
this
.
condition
.
planId
=
this
.
planId
;
}
if
(
this
.
selectNodeIds
&&
this
.
selectNodeIds
.
length
>
0
)
{
this
.
condition
.
nodeIds
=
this
.
selectNodeIds
;
}
if
(
!
getCurrentProjectID
())
{
return
;
}
this
.
result
=
this
.
$post
(
this
.
buildPagePath
(
this
.
queryPath
),
this
.
condition
,
response
=>
{
let
data
=
response
.
data
;
this
.
total
=
data
.
itemCount
;
this
.
tableData
=
data
.
listObject
;
// for (let i = 0; i
<
this
.
tableData
.
length
;
i
++
)
{
// let path = "/test/plan/project";
// this.$post(path, {planId: this.tableData[i].id}, res => {
// let arr = res.data;
// let projectIds = arr.filter(d => d.id !== this.tableData[i].projectId).map(data => data.id);
// this.$set(this.tableData[i], "projectIds", projectIds);
// })
// }
});
},
buildPagePath
(
path
)
{
return
path
+
"
/
"
+
this
.
currentPage
+
"
/
"
+
this
.
pageSize
;
},
handleDelete
(
testPlanReport
)
{
this
.
$alert
(
this
.
$t
(
'
report.delete_confirm
'
)
+
'
'
+
testPlanReport
.
name
+
"
?
"
,
''
,
{
confirmButtonText
:
this
.
$t
(
'
commons.confirm
'
),
callback
:
(
action
)
=>
{
if
(
action
===
'
confirm
'
)
{
let
testPlanReportIdList
=
[
testPlanReport
.
id
];
this
.
$post
(
'
/test/plan/report/delete/
'
,
testPlanReportIdList
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
commons.delete_success
'
));
this
.
initTableData
();
});
}
}
});
},
filter
(
filters
)
{
_filter
(
filters
,
this
.
condition
);
this
.
initTableData
();
},
sort
(
column
)
{
_sort
(
column
,
this
.
condition
);
this
.
initTableData
();
},
openReport
(
planId
)
{
if
(
planId
)
{
this
.
$refs
.
testPlanReportView
.
open
(
planId
);
}
},
}
}
</
script
>
<
style
scoped
>
.table-page
{
padding-top
:
20px
;
margin-right
:
-9px
;
float
:
right
;
}
.el-table
{
cursor
:
pointer
;
}
</
style
>
frontend/src/business/components/track/report/components/TestPlanReportView.vue
0 → 100644
浏览文件 @
8d152a07
<
template
>
<div>
<el-drawer
:visible.sync=
"showDialog"
:with-header=
"false"
:modal-append-to-body=
"false"
size=
"100%"
ref=
"drawer"
v-loading=
"result.loading"
>
<template
v-slot:default=
"scope"
>
<el-row
type=
"flex"
class=
"head-bar"
>
<el-col
:span=
"12"
>
<div
class=
"name-edit"
>
<el-button
plain
size=
"mini"
icon=
"el-icon-back"
@
click=
"handleClose"
>
{{
$t
(
'
test_track.return
'
)
}}
</el-button>
<span
class=
"title"
>
{{
report
.
name
}}
</span>
</div>
</el-col>
<el-col
:span=
"12"
class=
"head-right"
>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleSave"
>
{{
$t
(
'
commons.save
'
)
}}
</el-button>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleEdit"
>
{{
$t
(
'
test_track.plan_view.edit_component
'
)
}}
</el-button>
<el-button
:disabled=
"!isTestManagerOrTestUser"
plain
size=
"mini"
@
click=
"handleExport(report.name)"
>
{{
$t
(
'
test_track.plan_view.export_report
'
)
}}
</el-button>
</el-col>
</el-row>
<div
class=
"container"
ref=
"resume"
id=
"app"
>
<el-main>
<div
v-for=
"(item, index) in previews"
:key=
"item.id"
>
<template-component
:isReportView=
"true"
:metric=
"metric"
:preview=
"item"
:index=
"index"
ref=
"templateComponent"
/>
</div>
</el-main>
</div>
</
template
>
</el-drawer>
<ms-test-plan-report-export
v-if=
"reportExportVisible"
id=
"testCaseReportExport"
:title=
"report.name"
:metric=
"metric"
:previews=
"previews"
/>
<test-case-report-template-edit
:metric=
"metric"
ref=
"templateEdit"
@
refresh=
"getReport"
/>
</div>
</template>
<
script
>
import
{
checkoutTestManagerOrTestUser
,
exportPdf
,
jsonToMap
,
mapToJson
}
from
"
@/common/js/utils
"
;
import
BaseInfoComponent
from
"
@/business/components/track/plan/view/comonents/report/TemplateComponent/BaseInfoComponent
"
;
import
TestResultChartComponent
from
"
@/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultChartComponent
"
;
import
TestResultComponent
from
"
@/business/components/track/plan/view/comonents/report/TemplateComponent/TestResultComponent
"
;
import
RichTextComponent
from
"
@/business/components/track/plan/view/comonents/report/TemplateComponent/RichTextComponent
"
;
import
TestCaseReportTemplateEdit
from
"
@/business/components/track/plan/view/comonents/report/TestCaseReportTemplateEdit
"
;
import
TemplateComponent
from
"
@/business/components/track/plan/view/comonents/report/TemplateComponent/TemplateComponent
"
;
import
html2canvas
from
"
html2canvas
"
;
import
MsTestPlanReportExport
from
"
./TestPlanReportExport
"
;
export
default
{
name
:
"
TestPlanReportView
"
,
components
:
{
MsTestPlanReportExport
,
TemplateComponent
,
TestCaseReportTemplateEdit
,
RichTextComponent
,
TestResultComponent
,
TestResultChartComponent
,
BaseInfoComponent
},
data
()
{
return
{
result
:
{},
imgUrl
:
""
,
showDialog
:
false
,
previews
:
[],
report
:
{},
reportId
:
''
,
reportComponents
:[
1
,
3
,
4
],
metric
:
{},
planId
:
''
,
reportExportVisible
:
false
,
componentMap
:
new
Map
(
[
[
1
,
{
name
:
this
.
$t
(
'
test_track.plan_view.base_info
'
),
id
:
1
,
type
:
'
system
'
}],
[
2
,
{
name
:
this
.
$t
(
'
test_track.plan_view.test_result
'
),
id
:
2
,
type
:
'
system
'
}],
[
3
,
{
name
:
this
.
$t
(
'
test_track.plan_view.result_distribution
'
),
id
:
3
,
type
:
'
system
'
}],
[
4
,
{
name
:
this
.
$t
(
'
test_track.plan_view.failure_case
'
),
id
:
4
,
type
:
'
system
'
}],
[
5
,
{
name
:
this
.
$t
(
'
test_track.plan_view.defect_list
'
),
id
:
5
,
type
:
'
system
'
}],
[
6
,
{
name
:
this
.
$t
(
'
test_track.plan_view.custom_component
'
),
id
:
6
,
type
:
'
custom
'
}]
]
),
isTestManagerOrTestUser
:
false
}
},
mounted
()
{
this
.
isTestManagerOrTestUser
=
checkoutTestManagerOrTestUser
();
},
methods
:
{
listenGoBack
()
{
//监听浏览器返回操作,关闭该对话框
if
(
window
.
history
&&
window
.
history
.
pushState
)
{
history
.
pushState
(
null
,
null
,
document
.
URL
);
window
.
addEventListener
(
'
popstate
'
,
this
.
goBack
,
false
);
}
},
goBack
()
{
this
.
handleClose
();
},
open
(
reportId
)
{
this
.
reportId
=
reportId
;
this
.
getReport
();
this
.
showDialog
=
true
;
this
.
listenGoBack
();
},
getReport
()
{
// this.result = this.$get('/case/report/get/' + this.reportId, response => {
// this.report = response.data;
// this.report.content = JSON.parse(response.data.content);
// if (this.report.content.customComponent) {
// this.report.content.customComponent = jsonToMap(this.report.content.customComponent);
// }
// });
this
.
getMetric
();
this
.
initPreviews
();
},
initPreviews
()
{
this
.
previews
=
[];
this
.
reportComponents
.
forEach
(
item
=>
{
let
preview
=
this
.
componentMap
.
get
(
item
);
if
(
preview
&&
preview
.
type
!=
'
custom
'
)
{
this
.
previews
.
push
(
preview
);
}
else
{
if
(
this
.
report
.
content
.
customComponent
)
{
let
customComponent
=
this
.
report
.
content
.
customComponent
.
get
(
item
.
toString
());
if
(
customComponent
)
{
this
.
previews
.
push
({
id
:
item
,
title
:
customComponent
.
title
,
content
:
customComponent
.
content
});
}
}
}
});
},
handleClose
()
{
window
.
removeEventListener
(
'
popstate
'
,
this
.
goBack
,
false
);
this
.
$emit
(
'
refresh
'
);
this
.
showDialog
=
false
;
},
handleEdit
()
{
this
.
$refs
.
templateEdit
.
open
(
this
.
reportId
,
true
);
},
handleSave
()
{
let
param
=
{};
this
.
buildParam
(
param
);
this
.
result
=
this
.
$post
(
'
/case/report/edit
'
,
param
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
commons.save_success
'
));
});
},
buildParam
(
param
)
{
let
content
=
{};
content
.
components
=
[];
this
.
previews
.
forEach
(
item
=>
{
content
.
components
.
push
(
item
.
id
);
if
(
!
this
.
componentMap
.
get
(
item
.
id
))
{
content
.
customComponent
=
new
Map
();
content
.
customComponent
.
set
(
item
.
id
,
{
title
:
item
.
title
,
content
:
item
.
content
})
}
});
param
.
name
=
this
.
report
.
name
;
if
(
content
.
customComponent
)
{
content
.
customComponent
=
mapToJson
(
content
.
customComponent
);
}
param
.
content
=
JSON
.
stringify
(
content
);
param
.
id
=
this
.
report
.
id
;
if
(
this
.
metric
.
startTime
)
{
param
.
startTime
=
this
.
metric
.
startTime
.
getTime
();
}
if
(
this
.
metric
.
endTime
)
{
param
.
endTime
=
this
.
metric
.
endTime
.
getTime
();
}
},
getMetric
()
{
this
.
result
=
this
.
$get
(
'
/test/plan/report/getMetric/
'
+
this
.
reportId
,
response
=>
{
this
.
metric
=
response
.
data
;
if
(
!
this
.
metric
.
failureTestCases
)
{
this
.
metric
.
failureTestCases
=
[];
}
if
(
!
this
.
metric
.
executeResult
)
{
this
.
metric
.
executeResult
=
[];
}
if
(
!
this
.
metric
.
moduleExecuteResult
)
{
this
.
metric
.
moduleExecuteResult
=
[];
}
/*缺陷列表*/
if
(
!
this
.
metric
.
issues
)
{
this
.
metric
.
issues
=
[];
}
if
(
this
.
report
.
startTime
)
{
this
.
metric
.
startTime
=
new
Date
(
this
.
report
.
startTime
);
}
if
(
this
.
report
.
endTime
)
{
this
.
metric
.
endTime
=
new
Date
(
this
.
report
.
endTime
);
}
});
},
handleExport
(
name
)
{
this
.
result
.
loading
=
true
;
this
.
reportExportVisible
=
true
;
let
reset
=
this
.
exportReportReset
;
this
.
$nextTick
(
function
()
{
setTimeout
(()
=>
{
html2canvas
(
document
.
getElementById
(
'
testCaseReportExport
'
),
{
scale
:
2
}).
then
(
function
(
canvas
)
{
exportPdf
(
name
,
[
canvas
]);
reset
();
});
},
1000
);
});
},
exportReportReset
()
{
this
.
reportExportVisible
=
false
;
this
.
result
.
loading
=
false
;
},
}
}
</
script
>
cd
<
style
scoped
>
.el-main
{
height
:
calc
(
100vh
-
70px
);
width
:
100%
;
}
.head-bar
{
background
:
white
;
height
:
45px
;
line-height
:
45px
;
padding
:
0
10px
;
border
:
1px
solid
#EBEEF5
;
box-shadow
:
0
0
2px
0
rgba
(
31
,
31
,
31
,
0.15
),
0
1px
2px
0
rgba
(
31
,
31
,
31
,
0.15
);
}
.container
{
height
:
100vh
;
background
:
#F5F5F5
;
}
.el-card
{
width
:
70%
;
margin
:
5px
auto
;
}
.head-right
{
text-align
:
right
;
}
</
style
>
frontend/src/business/components/track/router.js
浏览文件 @
8d152a07
...
...
@@ -6,6 +6,8 @@ const TestPlan = () => import('@/business/components/track/plan/TestPlan')
const
TestCaseReview
=
()
=>
import
(
'
@/business/components/track/review/TestCaseReview
'
)
const
TestCaseReviewView
=
()
=>
import
(
'
@/business/components/track/review/view/TestCaseReviewView
'
)
const
TestPlanView
=
()
=>
import
(
'
@/business/components/track/plan/view/TestPlanView
'
)
const
reportListView
=
()
=>
import
(
'
@/business/components/track/report/TestPlanReport
'
)
// const reportListView = () => import('@/business/components/track/plan/TestPlan')
export
default
{
path
:
"
/track
"
,
...
...
@@ -35,6 +37,11 @@ export default {
name
:
'
testCaseEdit
'
,
component
:
TestCase
,
},
{
path
:
'
testPlan/reportList
'
,
name
:
'
testPlanReportList
'
,
component
:
reportListView
,
},
{
path
:
"
plan/:type
"
,
name
:
"
testPlan
"
,
...
...
frontend/src/i18n/en-US.js
浏览文件 @
8d152a07
...
...
@@ -1252,6 +1252,22 @@ export default {
tapd_current_owner
:
"
Tapd Current Owner:
"
,
zentao_bug_build
:
"
Zentao bug Impact version
"
,
zentao_bug_assigned
:
"
Zentao bug handler
"
,
},
report
:
{
name
:
"
Test Plan Report
"
,
list
:
{
name
:
"
name
"
,
test_plan
:
"
Test plan
"
,
creator
:
"
Creator
"
,
create_time
:
"
Create Time
"
,
trigger_mode
:
"
Trigger Mode
"
,
status
:
"
Status
"
,
operation
:
"
Operation
"
,
},
trigger_mode
:
{
manual
:
"
Manual
"
,
automation
:
"
Automation
"
,
},
}
},
test_resource_pool
:
{
...
...
frontend/src/i18n/zh-CN.js
浏览文件 @
8d152a07
...
...
@@ -1253,6 +1253,22 @@ export default {
tapd_current_owner
:
"
Tapd bug 处理人:
"
,
zentao_bug_build
:
"
禅道 bug 影响版本
"
,
zentao_bug_assigned
:
"
禅道 bug 处理人
"
,
},
report
:
{
name
:
"
测试计划报告
"
,
list
:
{
name
:
"
名称
"
,
test_plan
:
"
测试计划名称
"
,
creator
:
"
创建人
"
,
create_time
:
"
创建时间
"
,
trigger_mode
:
"
触发方式
"
,
status
:
"
状态
"
,
operation
:
"
操作
"
,
},
trigger_mode
:
{
manual
:
"
手动触发
"
,
automation
:
"
自动触发
"
,
},
}
},
test_resource_pool
:
{
...
...
frontend/src/i18n/zh-TW.js
浏览文件 @
8d152a07
...
...
@@ -1253,6 +1253,22 @@ export default {
tapd_current_owner
:
"
Tapd bug 處理人:
"
,
zentao_bug_build
:
"
禪道 bug 影響版本
"
,
zentao_bug_assigned
:
"
禪道 bug 處理人
"
,
},
report
:
{
name
:
"
測試計畫包括
"
,
list
:
{
name
:
"
名稱
"
,
test_plan
:
"
測試計畫名稱
"
,
creator
:
"
創建人
"
,
create_time
:
"
創建時間
"
,
trigger_mode
:
"
觸發方式
"
,
status
:
"
狀態
"
,
operation
:
"
操作
"
,
},
trigger_mode
:
{
manual
:
"
手動觸發
"
,
automation
:
"
自動觸發
"
,
},
}
},
test_resource_pool
:
{
...
...
package-lock.json
0 → 100644
浏览文件 @
8d152a07
{
"lockfileVersion"
:
1
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录