fix(接口自动化): 部分缺陷修复

This commit is contained in:
fit2-zhao 2021-04-15 20:42:51 +08:00 committed by fit2-zhao
parent c8143a0f1f
commit f9aece0463
13 changed files with 96 additions and 37 deletions

View File

@ -27,8 +27,10 @@ import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.service.ApiDefinitionService;
import io.metersphere.api.service.ApiTestCaseService;
import io.metersphere.api.service.ApiTestEnvironmentService;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
import io.metersphere.commons.constants.LoopConstants;
import io.metersphere.commons.constants.MsTestElementConstants;
@ -158,6 +160,16 @@ public abstract class MsTestElement {
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
if (StringUtils.equals(element.getRefType(), "CASE")) {
ApiTestCaseService apiTestCaseService = CommonBeanFactory.getBean(ApiTestCaseService.class);
ApiTestCaseWithBLOBs bloBs = apiTestCaseService.get(element.getId());
if (bloBs != null) {
element.setProjectId(bloBs.getProjectId());
element = mapper.readValue(bloBs.getRequest(), new TypeReference<MsTestElement>() {
});
hashTree.add(element);
}
} else {
ApiDefinitionWithBLOBs apiDefinition = apiDefinitionService.getBLOBs(element.getId());
if (apiDefinition != null) {
element.setProjectId(apiDefinition.getProjectId());
@ -165,6 +177,7 @@ public abstract class MsTestElement {
});
hashTree.add(element);
}
}
} catch (Exception ex) {
ex.printStackTrace();
LogUtil.error(ex.getMessage());

View File

@ -2,6 +2,9 @@ package io.metersphere.api.dto.definition.request.sampler;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.definition.request.MsTestElement;
import io.metersphere.api.dto.definition.request.ParameterConfig;
import io.metersphere.api.dto.definition.request.auth.MsAuthManager;
@ -11,10 +14,10 @@ import io.metersphere.api.dto.scenario.HttpConfig;
import io.metersphere.api.dto.scenario.HttpConfigCondition;
import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.service.ApiDefinitionService;
import io.metersphere.api.service.ApiModuleService;
import io.metersphere.api.service.ApiTestEnvironmentService;
import io.metersphere.api.service.ApiTestCaseService;
import io.metersphere.base.domain.ApiDefinition;
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
import io.metersphere.commons.constants.ConditionType;
import io.metersphere.commons.constants.MsTestElementConstants;
import io.metersphere.commons.exception.MSException;
@ -102,6 +105,35 @@ public class MsHTTPSamplerProxy extends MsTestElement {
@JSONField(ordinal = 36)
private MsAuthManager authManager;
public void setRefElement() {
try {
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
if (StringUtils.equals(this.getRefType(), "CASE")) {
ApiTestCaseService apiTestCaseService = CommonBeanFactory.getBean(ApiTestCaseService.class);
ApiTestCaseWithBLOBs bloBs = apiTestCaseService.get(this.getId());
if (bloBs != null) {
this.setProjectId(bloBs.getProjectId());
MsHTTPSamplerProxy proxy = mapper.readValue(bloBs.getRequest(), new TypeReference<MsHTTPSamplerProxy>() {
});
this.setHashTree(proxy.getHashTree());
}
} else {
ApiDefinitionWithBLOBs apiDefinition = apiDefinitionService.getBLOBs(this.getId());
if (apiDefinition != null) {
this.setProjectId(apiDefinition.getProjectId());
MsHTTPSamplerProxy proxy = mapper.readValue(apiDefinition.getRequest(), new TypeReference<MsHTTPSamplerProxy>() {
});
this.setHashTree(proxy.getHashTree());
}
}
} catch (Exception ex) {
ex.printStackTrace();
LogUtil.error(ex.getMessage());
}
}
@Override
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
// 非导出操作且不是启用状态则跳过执行
@ -109,7 +141,8 @@ public class MsHTTPSamplerProxy extends MsTestElement {
return;
}
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
this.getRefElement(this);
this.setRefElement();
hashTree = this.getHashTree();
}
HTTPSamplerProxy sampler = new HTTPSamplerProxy();
sampler.setEnabled(this.isEnable());

View File

@ -180,6 +180,9 @@
}
},
addTab(tab) {
if(tab.name==='default'){
this.$refs.apiScenarioList.search();
}
if (!this.projectId) {
this.$warning(this.$t('commons.check_project_tip'));
return;

View File

@ -12,7 +12,7 @@
<el-select v-model="pe['selectEnv']" placeholder="请选择环境" style="margin-left:10px; margin-top: 10px;"
size="small">
<el-option v-for="(environment, index) in pe.envs" :key="index"
:label="environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
:label="environment.name"
:value="environment.id"/>
<el-button class="ms-scenario-button" size="mini" type="primary" @click="openEnvironmentConfig(pe.id)">
{{ $t('api_test.environment.environment_config') }}

View File

@ -553,8 +553,6 @@ export default {
if (!(environment.config instanceof Object)) {
environment.config = JSON.parse(environment.config);
}
environment.name = environment.name + (environment.config.httpConfig.socket ?
(': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '');
});
});
},

View File

@ -3,7 +3,7 @@
<div v-for="pe in data" :key="pe.id" style="margin-left: 20px;">
<el-select v-model="pe['selectEnv']" placeholder="请选择环境" style="margin-top: 8px;width: 200px;" size="small">
<el-option v-for="(environment, index) in pe.envs" :key="index"
:label="environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
:label="environment.name"
:value="environment.id"/>
<el-button class="ms-scenario-button" size="mini" type="primary"
@click="openEnvironmentConfig(pe.id, pe['selectEnv'])">

View File

@ -19,7 +19,7 @@
<el-radio label="setReport">{{ $t("run_mode.set_report") }}</el-radio>
</el-radio-group>
</div>
<div class="ms-mode-div" v-if="runConfig.reportType === 'setReport'">
<div class="ms-mode-div" v-if="runConfig.reportType === 'setReport' && runConfig.mode==='serial'">
<span class="ms-mode-span">{{ $t("run_mode.report_name") }}</span>
<el-input
v-model="runConfig.reportName"

View File

@ -3,7 +3,7 @@
<el-select :disabled="isReadOnly" v-model="environmentId" size="small" class="environment-select"
:placeholder="$t('api_test.definition.request.run_env')" clearable>
<el-option v-for="(environment, key) in environments" :key="key"
:label="environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
:label="environment.name"
:value="environment.id"/>
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">
{{ $t('api_test.environment.environment_config') }}

View File

@ -79,8 +79,7 @@
return environment.name;
}
}
return environment.name + (environment.config.httpConfig.socket ?
(': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '');
return environment.name;
}
return "";
},

View File

@ -632,6 +632,9 @@ export default {
row.request = JSON.parse(row.request);
row.request.name = row.id;
row.request.useEnvironment = environment.id;
let map = new Map;
map.set(row.projectId,environment.id);
row.environmentMap = map;
runData.push(row.request);
/*触发执行操作*/
let testPlan = new TestPlan();

View File

@ -46,7 +46,7 @@
this.$warning(this.$t('api_test.automation.save_case_info'))
}
},
createPerformance(row){
createPerformance(row) {
/**
* 思路调用后台创建性能测试的方法把当前案例的hashTree在后台转化为jmx并文件创建性能测试
* 然后跳转到修改性能测试的页面
@ -61,7 +61,7 @@
this.runData = [];
this.singleLoading = true;
this.row.request.name = this.row.id;
this.row.request.useEnvironment = this.environment.id;
this.row.request.useEnvironment = this.environment;
this.runData.push(this.row.request);
/*触发执行操作*/
let testPlan = new TestPlan();
@ -71,18 +71,21 @@
this.runData.forEach(item => {
threadGroup.hashTree.push(item);
})
let reqObj = {id: this.row.id,
let reqObj = {
id: this.row.id,
testElement: testPlan,
type: this.type,
name:this.row.name,
projectId:getCurrentProjectID(),
name: this.row.name,
projectId: getCurrentProjectID(),
environmentMap: new Map([
[getCurrentProjectID(), this.environment.id]
]),
};
let bodyFiles = getBodyUploadFiles(reqObj, this.runData);
reqObj.reportId = "run";
// let url = "/api/genPerformanceTest";
let url = "/api/genPerformanceTestXml";
this.$fileUpload(url, null, bodyFiles, reqObj, response => {
let jmxObj = {};
jmxObj.name = response.data.name;
@ -97,12 +100,6 @@
this.$router.push({
path: "/performance/test/create"
})
// let performanceId = response.data;
// if(performanceId!=null){
// this.$router.push({
// path: "/performance/test/edit/"+performanceId,
// })
// }
}, erro => {
this.$emit('runRefresh', {});
});

View File

@ -22,7 +22,7 @@
<el-button type="primary" v-else style="float: right" size="mini" @click="update">{{$t('commons.update')}}</el-button>
<div v-if="condition.type === 'MODULE'">
<ms-select-tree size="small" :data="moduleOptions" :default-key="condition.ids" @getValue="setModule" :obj="moduleObj" clearable checkStrictly multiple/>
<ms-select-tree size="small" :data="moduleOptions" :default-key="condition.ids" @getValue="setModule" :obj="moduleObj" clearable checkStrictly multiple v-if="!loading"/>
</div>
<div v-if="condition.type === 'PATH'">
<el-input v-model="pathDetails.name" :placeholder="$t('api_test.value')" clearable size="small">
@ -36,7 +36,7 @@
</div>
</el-form-item>
<div class="ms-border">
<el-table :data="httpConfig.conditions" highlight-current-row @current-change="selectRow">
<el-table :data="httpConfig.conditions" highlight-current-row @current-change="selectRow" v-if="!loading">
<el-table-column prop="socket" :label="$t('load_test.domain')" width="180">
<template v-slot:default="{row}">
{{getUrl(row)}}
@ -110,6 +110,7 @@
id: "id",
label: "name",
},
loading: false,
pathDetails: new KeyValue({name: "", value: "contains"}),
condition: {type: "NONE", details: [new KeyValue({name: "", value: "contains"})], protocol: "http", socket: "", domain: "", port: 0},
};
@ -165,13 +166,14 @@
}
},
selectRow(row) {
this.condition = {};
if (row) {
this.httpConfig.socket = row.socket;
this.httpConfig.protocol = row.protocol;
this.httpConfig.port = row.port;
this.condition = row;
if (row.type === "PATH" && row.details.length > 0) {
this.pathDetails = row.details[0];
this.pathDetails = JSON.parse(JSON.stringify(row.details[0]));
} else if (row.type === "MODULE" && row.details.length > 0) {
this.condition.ids = [];
row.details.forEach((item) => {
@ -179,6 +181,7 @@
});
}
}
this.reload();
},
typeChange() {
switch (this.condition.type) {
@ -194,7 +197,7 @@
}
},
list() {
let url = "/api/automation/module/list/" + this.projectId;
let url = "/api/module/list/" + this.projectId + "/HTTP";
this.result = this.$get(url, (response) => {
if (response.data !== undefined && response.data !== null) {
this.moduleOptions = response.data;
@ -216,11 +219,21 @@
id: this.condition.id, type: this.condition.type, domain: this.condition.domain, socket: this.condition.socket,
protocol: this.condition.protocol, details: this.condition.details, port: this.condition.port, time: this.condition.time
};
if (obj.type === "PATH") {
this.httpConfig.conditions[index].details = [this.pathDetails];
}
if (index !== -1) {
Vue.set(this.httpConfig.conditions[index], obj, 1);
this.condition = {type: "NONE", details: [new KeyValue({name: "", value: "contains"})], protocol: "", socket: "", domain: ""};
this.reload();
}
},
reload() {
this.loading = true
this.$nextTick(() => {
this.loading = false
});
},
add() {
let obj = {
id: getUUID(), type: this.condition.type, socket: this.condition.socket, protocol: this.condition.protocol,
@ -243,9 +256,9 @@
},
copy(row) {
const index = this.httpConfig.conditions.findIndex((d) => d.id === row.id);
let obj = {id: getUUID(), type: row.type, socket: row.socket, details: row.details, protocol: row.protocol, domain: row.domain,};
let obj = {id: getUUID(), type: row.type, socket: row.socket, details: row.details, protocol: row.protocol, domain: row.domain, time: new Date().getTime()};
if (index != -1) {
this.httpConfig.conditions.splice(index + 1, 0, obj);
this.httpConfig.conditions.splice(index, 0, obj);
} else {
this.httpConfig.conditions.push(obj);
}

View File

@ -3,7 +3,7 @@
<div v-for="pe in data" :key="pe.id" style="margin-left: 20px;">
<el-select v-model="pe['selectEnv']" placeholder="请选择环境" style="margin-top: 8px;width: 200px;" size="small">
<el-option v-for="(environment, index) in pe.envs" :key="index"
:label="environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
:label="environment.name"
:value="environment.id"/>
<el-button class="ms-scenario-button" size="mini" type="primary" @click="openEnvironmentConfig(pe.id)">
{{ $t('api_test.environment.environment_config') }}