feat(接口测试): 场景变量支持启用自身场景变量优先策略
--story=1010745 --user=赵勇 场景嵌套引用的变量取值优化-接口场景 https://www.tapd.cn/55049933/s/1312907
This commit is contained in:
parent
bed8db3a55
commit
0f174ae73e
|
@ -29,6 +29,7 @@ import io.metersphere.service.EnvironmentGroupProjectService;
|
|||
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.jmeter.protocol.http.control.Header;
|
||||
|
@ -78,6 +79,9 @@ public class MsScenario extends MsTestElement {
|
|||
@JSONField(ordinal = 30)
|
||||
private Boolean variableEnable;
|
||||
|
||||
@JSONField(ordinal = 31)
|
||||
private Boolean mixEnable;
|
||||
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
|
||||
public MsScenario() {
|
||||
|
@ -127,7 +131,8 @@ public class MsScenario extends MsTestElement {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(this.getVariables()) && (this.variableEnable == null || this.variableEnable)) {
|
||||
|
||||
if (CollectionUtils.isNotEmpty(this.getVariables()) && (this.variableEnable == null || this.variableEnable)) {
|
||||
config.setVariables(this.variables);
|
||||
}
|
||||
HashTree scenarioTree = tree;
|
||||
|
@ -144,12 +149,19 @@ 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 = arguments(this.isEnvironmentEnable() ? newConfig : config);
|
||||
if (arguments != null && (this.variableEnable == null || this.variableEnable)) {
|
||||
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);
|
||||
|
@ -167,6 +179,7 @@ public class MsScenario extends MsTestElement {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加全局前置
|
||||
this.setGlobProcessor(this.isEnvironmentEnable() ? newConfig : config, scenarioTree, true);
|
||||
|
||||
|
|
|
@ -21,10 +21,12 @@ import io.metersphere.plugin.core.MsTestElement;
|
|||
import io.metersphere.track.service.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 {
|
||||
|
@ -138,7 +140,7 @@ public class ParameterConfig extends MsParameter {
|
|||
} else {
|
||||
apiDefinition = apiDefinitionService.get(samplerProxy.getId());
|
||||
// 兼容导入数据
|
||||
if(apiDefinition == null ){
|
||||
if (apiDefinition == null) {
|
||||
apiDefinition = apiDefinitionService.get(samplerProxy.getName());
|
||||
}
|
||||
ApiTestCaseWithBLOBs apiTestCaseWithBLOBs = apiTestCaseService.get(samplerProxy.getId());
|
||||
|
@ -249,4 +251,45 @@ public class ParameterConfig extends MsParameter {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,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";
|
||||
|
@ -245,8 +246,8 @@ public class MsHashTreeService {
|
|||
|
||||
private JSONObject setRefScenario(JSONObject element) {
|
||||
boolean enable = element.containsKey(ENABLE) ? element.getBoolean(ENABLE) : true;
|
||||
if (!element.containsKey(VARIABLE_ENABLE)) {
|
||||
element.put(VARIABLE_ENABLE, true);
|
||||
if (!element.containsKey(MIX_ENABLE)) {
|
||||
element.put(MIX_ENABLE, true);
|
||||
}
|
||||
|
||||
ApiScenarioDTO scenarioWithBLOBs = extApiScenarioMapper.selectById(element.getString(ID));
|
||||
|
@ -254,7 +255,9 @@ public class MsHashTreeService {
|
|||
boolean environmentEnable = element.containsKey(ENV_ENABLE)
|
||||
? element.getBoolean(ENV_ENABLE) : false;
|
||||
boolean variableEnable = element.containsKey(VARIABLE_ENABLE)
|
||||
? element.getBoolean(VARIABLE_ENABLE) : true;
|
||||
? element.getBoolean(VARIABLE_ENABLE) : false;
|
||||
boolean mixEnable = element.containsKey(MIX_ENABLE)
|
||||
? element.getBoolean(MIX_ENABLE) : true;
|
||||
|
||||
if (environmentEnable && StringUtils.isNotEmpty(scenarioWithBLOBs.getEnvironmentJson())) {
|
||||
element.put(ENV_MAP, JSON.parseObject(scenarioWithBLOBs.getEnvironmentJson(), Map.class));
|
||||
|
@ -269,6 +272,9 @@ public class MsHashTreeService {
|
|||
if (!element.containsKey(VARIABLE_ENABLE)) {
|
||||
element.put(VARIABLE_ENABLE, variableEnable);
|
||||
}
|
||||
if (!element.containsKey(MIX_ENABLE) && !variableEnable) {
|
||||
element.put(MIX_ENABLE, mixEnable);
|
||||
}
|
||||
this.setElement(element, scenarioWithBLOBs.getNum(), enable, scenarioWithBLOBs.getVersionName(), scenarioWithBLOBs.getVersionEnable());
|
||||
} else {
|
||||
if (StringUtils.equalsIgnoreCase(element.getString(REFERENCED), REF)) {
|
||||
|
|
|
@ -1271,7 +1271,7 @@ export default {
|
|||
}
|
||||
this.resetResourceId(item.hashTree);
|
||||
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 !== undefined) {
|
||||
if (this.stepFilter.get("SpecialSteps").indexOf(this.selectedTreeNode.type) !== -1) {
|
||||
this.scenarioDefinition.splice(this.selectedTreeNode.index, 0, item);
|
||||
|
|
|
@ -6,17 +6,27 @@
|
|||
</el-link>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="copy" v-if="data.command">{{ this.$t('commons.copy') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="enable" v-if="data.command && data.enable">{{ this.$t('ui.disable') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="enable" v-if="data.command && !data.enable">{{ this.$t('ui.enable') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="enable" v-if="data.command && data.enable">{{
|
||||
this.$t('ui.disable')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="enable" v-if="data.command && !data.enable">{{
|
||||
this.$t('ui.enable')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="remove">{{ this.$t('api_test.automation.delete_step') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="rename" v-if="!isScenario">{{ this.$t('test_track.module.rename') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="rename" v-if="!isScenario">{{
|
||||
this.$t('test_track.module.rename')
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="scenarioVar" v-if="data.type==='scenario'">
|
||||
{{ this.$t("api_test.automation.view_scene_variables") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="openScenario" v-if="data.type==='scenario' && data.referenced==='REF'">
|
||||
{{ this.$t("api_test.automation.open_scene") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="saveAs" v-if="allSamplers.indexOf(data.type)!=-1 && (data.referenced===undefined || data.referenced ==='Created' )">
|
||||
<el-dropdown-item command="saveAs"
|
||||
v-if="allSamplers.indexOf(data.type)!=-1 && (data.referenced===undefined || data.referenced ==='Created' )">
|
||||
{{ this.$t("api_test.automation.save_as_api") }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="setScenario" v-if="data.type==='scenario'">
|
||||
|
@ -30,16 +40,21 @@
|
|||
|
||||
<el-dialog
|
||||
:title="$t('commons.reference_settings')"
|
||||
:visible.sync="dialogVisible" width="400px">
|
||||
:visible.sync="dialogVisible" width="700px">
|
||||
<ul>
|
||||
<el-tooltip :content="$t('commons.enable_scene_info')" placement="top" v-if = 'showEnableScence'>
|
||||
<el-tooltip :content="$t('commons.enable_scene_info')" placement="top" v-if='showEnableScence'>
|
||||
<el-checkbox v-model="data.environmentEnable" @change="checkEnv" :disabled="data.disabled">
|
||||
{{ $t('commons.enable_scene') }}
|
||||
</el-checkbox>
|
||||
</el-tooltip>
|
||||
<el-checkbox v-model="data.variableEnable" :disabled="data.disabled">
|
||||
<br/>
|
||||
<el-checkbox v-model="data.variableEnable" :disabled="data.disabled" @change="variableChange">
|
||||
{{ $t('commons.variable_scene') }}
|
||||
</el-checkbox>
|
||||
<br/>
|
||||
<el-checkbox v-model="data.mixEnable" :disabled="data.disabled" @change="mixChange">
|
||||
{{ $t('commons.mix_enable') }}
|
||||
</el-checkbox>
|
||||
</ul>
|
||||
</el-dialog>
|
||||
|
||||
|
@ -85,6 +100,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":
|
||||
|
|
|
@ -242,6 +242,7 @@ export default {
|
|||
testing: "Testing",
|
||||
enable_scene: "Original scene environment",
|
||||
variable_scene: "Original scene variable",
|
||||
mix_enable: "The current scene variable is used first, and the original scene variable is used if there is no",
|
||||
reference_settings: "Reference settings",
|
||||
enable_scene_info: "Enable scene environment: the current step uses the original environment configuration of the scene to run",
|
||||
edit_info: "Edit details",
|
||||
|
|
|
@ -244,6 +244,7 @@ export default {
|
|||
edit_info: "编辑详情",
|
||||
enable_scene: "原场景环境",
|
||||
variable_scene: "原场景变量",
|
||||
mix_enable: "优先使用当前场景变量,没有则使用原场景变量",
|
||||
reference_settings: "场景设置",
|
||||
enable_scene_info: "启用场景环境:当前步骤使用场景原始环境配置运行",
|
||||
environment: "运行环境",
|
||||
|
|
|
@ -244,6 +244,7 @@ export default {
|
|||
edit_info: "編輯詳情",
|
||||
enable_scene: "原場景環境",
|
||||
variable_scene: "原場景变量",
|
||||
mix_enable: "優先使用當前場景變量,沒有則使用原場景變量",
|
||||
reference_settings: "场景设置",
|
||||
enable_scene_info: "啟用場景環境:當前步驟使用場景原始環境配置運行",
|
||||
environment: "運行環境",
|
||||
|
|
Loading…
Reference in New Issue