feat(接口测试): 场景变量支持启用自身场景变量优先策略
--story=1010745 --user=赵勇 场景嵌套引用的变量取值优化-接口场景 https://www.tapd.cn/55049933/s/1312907
This commit is contained in:
parent
00cb5c7343
commit
b5ca7416e9
|
@ -23,6 +23,7 @@ import io.metersphere.service.MsHashTreeService;
|
|||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
@ -49,6 +50,7 @@ public class MsScenario extends MsTestElement {
|
|||
private boolean environmentEnable;
|
||||
private Boolean variableEnable;
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
private Boolean mixEnable;
|
||||
|
||||
public MsScenario() {
|
||||
}
|
||||
|
@ -112,12 +114,20 @@ public class MsScenario extends MsTestElement {
|
|||
if (config != null && !config.getExcludeScenarioIds().contains(this.getId())) {
|
||||
scenarioTree = MsCriticalSectionController.createHashTree(tree, this.getName(), this.isEnable());
|
||||
}
|
||||
// 启用当前场景变量优先选择
|
||||
if ((mixEnable == null || BooleanUtils.isTrue(mixEnable))
|
||||
&& (this.variableEnable == null || BooleanUtils.isFalse(this.variableEnable))) {
|
||||
config.margeVariables(this.variables, config.getTransferVariables());
|
||||
}
|
||||
// 环境变量
|
||||
Arguments arguments = ElementUtil.getConfigArguments(this.isEnvironmentEnable() ? newConfig : config, this.getName(), this.getProjectId(), this.getVariables());
|
||||
if (arguments != null && (this.variableEnable == null || this.variableEnable)) {
|
||||
Arguments arguments = ElementUtil.getConfigArguments(this.isEnvironmentEnable() ?
|
||||
newConfig : config, this.getName(), this.getProjectId(), this.getVariables());
|
||||
if (arguments != null && ((this.variableEnable == null || this.variableEnable)
|
||||
|| (this.mixEnable == null || this.mixEnable))) {
|
||||
Arguments valueSupposeMock = ParameterConfig.valueSupposeMock(arguments);
|
||||
// 这里加入自定义变量解决ForEach循环控制器取值问题,循环控制器无法从vars中取值
|
||||
if (this.variableEnable != null && this.variableEnable) {
|
||||
if ((this.variableEnable == null || this.variableEnable)
|
||||
|| (this.mixEnable == null || this.mixEnable)) {
|
||||
scenarioTree.add(ElementUtil.argumentsToUserParameters(valueSupposeMock));
|
||||
} else {
|
||||
scenarioTree.add(valueSupposeMock);
|
||||
|
|
|
@ -22,10 +22,12 @@ import io.metersphere.service.definition.ApiTestCaseService;
|
|||
import io.metersphere.service.plan.TestPlanApiCaseService;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Data
|
||||
public class ParameterConfig extends MsParameter {
|
||||
|
@ -222,4 +224,45 @@ public class ParameterConfig extends MsParameter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void margeVariables(List<ScenarioVariable> variables, List<ScenarioVariable> transferVariables) {
|
||||
if (CollectionUtils.isNotEmpty(transferVariables)) {
|
||||
List<ScenarioVariable> constants = variables.stream().filter(ScenarioVariable::isConstantValid).collect(Collectors.toList());
|
||||
Map<String, List<ScenarioVariable>> transferVariableGroup =
|
||||
transferVariables.stream().collect(Collectors.groupingBy(ScenarioVariable::getName, LinkedHashMap::new, Collectors.toList()));
|
||||
Map<String, List<ScenarioVariable>> constantsGroup =
|
||||
constants.stream().collect(Collectors.groupingBy(ScenarioVariable::getName, LinkedHashMap::new, Collectors.toList()));
|
||||
// 更新相同名称的值
|
||||
for (ScenarioVariable constant : constants) {
|
||||
if (transferVariableGroup.containsKey(constant.getName())
|
||||
&& CollectionUtils.isNotEmpty(transferVariableGroup.get(constant.getName()))) {
|
||||
constant.setValue(transferVariableGroup.get(constant.getName()).get(0).getValue());
|
||||
}
|
||||
}
|
||||
// 添加当前没有的值
|
||||
transferVariables.forEach(item -> {
|
||||
if (!constantsGroup.containsKey(item.getName())) {
|
||||
variables.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void margeParentVariables(List<ScenarioVariable> variables, MsTestElement parent) {
|
||||
// 取出父级场景且父场景不是顶级场景
|
||||
MsScenario scenario = getScenario(parent);
|
||||
if (scenario == null || BooleanUtils.isFalse(scenario.getMixEnable()) || CollectionUtils.isEmpty(scenario.getVariables())) {
|
||||
return;
|
||||
}
|
||||
this.margeVariables(variables, scenario.getVariables());
|
||||
}
|
||||
|
||||
private MsScenario getScenario(MsTestElement parent) {
|
||||
if (parent != null && parent instanceof MsScenario) {
|
||||
return parent.getParent() != null ? (MsScenario) parent : null;
|
||||
} else if (parent != null && parent.getParent() != null) {
|
||||
getScenario(parent.getParent());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ public class MsHashTreeService {
|
|||
public static final String NUM = "num";
|
||||
public static final String ENV_ENABLE = "environmentEnable";
|
||||
public static final String VARIABLE_ENABLE = "variableEnable";
|
||||
public static final String MIX_ENABLE = "mixEnable";
|
||||
public static final String DISABLED = "disabled";
|
||||
public static final String VERSION_NAME = "versionName";
|
||||
public static final String VERSION_ENABLE = "versionEnable";
|
||||
|
@ -199,14 +200,17 @@ public class MsHashTreeService {
|
|||
|
||||
private JSONObject setRefScenario(JSONObject element) {
|
||||
boolean enable = element.has(ENABLE) ? element.optBoolean(ENABLE) : true;
|
||||
if (!element.has(VARIABLE_ENABLE)) {
|
||||
element.put(VARIABLE_ENABLE, true);
|
||||
if (!element.has(MIX_ENABLE)) {
|
||||
element.put(MIX_ENABLE, true);
|
||||
}
|
||||
|
||||
ApiScenarioDTO scenarioWithBLOBs = extApiScenarioMapper.selectById(element.optString(ID));
|
||||
if (scenarioWithBLOBs != null && StringUtils.isNotEmpty(scenarioWithBLOBs.getScenarioDefinition())) {
|
||||
boolean environmentEnable = element.has(ENV_ENABLE) ? element.optBoolean(ENV_ENABLE) : false;
|
||||
boolean variableEnable = element.has(VARIABLE_ENABLE) ? element.optBoolean(VARIABLE_ENABLE) : true;
|
||||
boolean variableEnable = element.has(VARIABLE_ENABLE) ? element.optBoolean(VARIABLE_ENABLE) : false;
|
||||
boolean mixEnable = element.has(MIX_ENABLE)
|
||||
? element.getBoolean(MIX_ENABLE) : true;
|
||||
|
||||
if (environmentEnable && StringUtils.isNotEmpty(scenarioWithBLOBs.getEnvironmentJson())) {
|
||||
element.put(ENV_MAP, JSON.parseObject(scenarioWithBLOBs.getEnvironmentJson(), Map.class));
|
||||
}
|
||||
|
@ -220,6 +224,9 @@ public class MsHashTreeService {
|
|||
if (!element.has(VARIABLE_ENABLE)) {
|
||||
element.put(VARIABLE_ENABLE, variableEnable);
|
||||
}
|
||||
if (!element.has(MIX_ENABLE) && !variableEnable) {
|
||||
element.put(MIX_ENABLE, mixEnable);
|
||||
}
|
||||
//获取场景的当前项目是否开启了自定义id
|
||||
ProjectConfig projectApplication = baseProjectApplicationService.getSpecificTypeValue(scenarioWithBLOBs.getProjectId(), "SCENARIO_CUSTOM_NUM");
|
||||
element.put(SHOW_CUSTOM_NUM, projectApplication.getScenarioCustomNum());
|
||||
|
|
|
@ -1524,7 +1524,7 @@ export default {
|
|||
}
|
||||
this.resetResourceId(item.hashTree, item.referenced);
|
||||
item.enable === undefined ? (item.enable = true) : item.enable;
|
||||
item.variableEnable = item.variableEnable === undefined ? true : item.variableEnable;
|
||||
item.mixEnable = item.mixEnable === undefined && !item.variableEnable ? true : item.mixEnable;
|
||||
if (this.selectedTreeNode) {
|
||||
if (this.stepFilter.get('SpecialSteps').indexOf(this.selectedTreeNode.type) !== -1) {
|
||||
this.scenarioDefinition.splice(this.selectedTreeNode.index, 0, item);
|
||||
|
|
|
@ -42,16 +42,22 @@
|
|||
|
||||
<ms-add-api-case :currentProtocol="currentProtocol" ref="apiCase" />
|
||||
|
||||
<el-dialog :title="$t('commons.reference_settings')" :visible.sync="dialogVisible" width="400px">
|
||||
<el-dialog :title="$t('commons.reference_settings')" :visible.sync="dialogVisible" width="700px">
|
||||
<ul>
|
||||
<el-tooltip :content="$t('commons.enable_scene_info')" placement="top" v-if="showEnableScenario">
|
||||
<el-checkbox v-model="data.environmentEnable" @change="checkEnv">
|
||||
{{ $t('commons.enable_scene') }}
|
||||
</el-checkbox>
|
||||
</el-tooltip>
|
||||
<el-checkbox v-model="data.variableEnable">
|
||||
<br />
|
||||
|
||||
<el-checkbox v-model="data.variableEnable" @change="variableChange">
|
||||
{{ $t('commons.variable_scene') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="data.mixEnable" @change="mixChange">
|
||||
{{ $t('api_case.mix_enable') }}
|
||||
</el-checkbox>
|
||||
</ul>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
@ -100,6 +106,16 @@ export default {
|
|||
this.allSamplers = this.filter.get('DEFINITION');
|
||||
},
|
||||
methods: {
|
||||
variableChange() {
|
||||
if (this.data.variableEnable) {
|
||||
this.data.mixEnable = false;
|
||||
}
|
||||
},
|
||||
mixChange() {
|
||||
if (this.data.mixEnable) {
|
||||
this.data.variableEnable = false;
|
||||
}
|
||||
},
|
||||
handleCommand(cmd) {
|
||||
switch (cmd) {
|
||||
case 'copy':
|
||||
|
|
|
@ -5,6 +5,7 @@ import mf from 'metersphere-frontend/src/i18n/lang/en-US';
|
|||
const message = {
|
||||
api_case: {
|
||||
please_add_api_case: 'Please add api case',
|
||||
mix_enable: 'The current scene variable is used first, and the original scene variable is used if there is no',
|
||||
},
|
||||
api_definition: {
|
||||
debug_pool_warning:
|
||||
|
|
|
@ -5,6 +5,7 @@ import mf from 'metersphere-frontend/src/i18n/lang/zh-CN';
|
|||
const message = {
|
||||
api_case: {
|
||||
please_add_api_case: '请先添加接口用例',
|
||||
mix_enable: '优先使用当前场景变量,没有则使用原场景变量',
|
||||
},
|
||||
api_definition: {
|
||||
debug_pool_warning: '调用资源池执行失败,请检查资源池是否配置正常',
|
||||
|
|
|
@ -5,6 +5,7 @@ import mf from 'metersphere-frontend/src/i18n/lang/zh-TW';
|
|||
const message = {
|
||||
api_case: {
|
||||
please_add_api_case: '请先添加接口用例',
|
||||
mix_enable: '優先使用當前場景變量,沒有則使用原場景變量',
|
||||
},
|
||||
api_definition: {
|
||||
debug_pool_warning: '調用資源池執行失敗,請檢查資源池是否配置正常',
|
||||
|
|
|
@ -60,7 +60,7 @@ export default {
|
|||
return this.height ? (this.height + 'px') : (this.enableAutoHeight ? null : 'calc(100vh - 50px)')
|
||||
},
|
||||
containerCalHeight() {
|
||||
return this.height ? (this.height - 30 + 'px') : (this.enableAutoHeight ? null : 'calc(100vh - 60px)')
|
||||
return this.height ? (this.height - 30 + 'px') : (this.enableAutoHeight ? null : 'calc(100vh - 62px)')
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
|
|
@ -34,8 +34,8 @@ a:hover {
|
|||
|
||||
/* 滚动条样式 */
|
||||
::-webkit-scrollbar{
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
position: fixed;
|
||||
}
|
||||
::-webkit-scrollbar-thumb{
|
||||
|
|
|
@ -197,8 +197,8 @@ textarea {
|
|||
|
||||
/* 滚动条样式 */
|
||||
::-webkit-scrollbar{
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
position: fixed;
|
||||
}
|
||||
::-webkit-scrollbar-thumb{
|
||||
|
|
Loading…
Reference in New Issue