refactor(接口测试): 优化csv相关接口

This commit is contained in:
AgAngle 2024-05-16 20:14:28 +08:00 committed by Craftsman
parent f0afd5241c
commit 0ff9b831cd
6 changed files with 70 additions and 40 deletions

View File

@ -1,11 +1,15 @@
package io.metersphere.api.dto.scenario; package io.metersphere.api.dto.scenario;
import io.metersphere.api.dto.ApiFile;
import io.metersphere.sdk.constants.ValueEnum; import io.metersphere.sdk.constants.ValueEnum;
import io.metersphere.system.valid.EnumValue; import io.metersphere.system.valid.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.StringUtils;
/** /**
@ -20,22 +24,15 @@ public class CsvVariable {
@Size(max = 50) @Size(max = 50)
private String id; private String id;
@Schema(description = "文件id/引用文件id", requiredMode = Schema.RequiredMode.REQUIRED)
@Size(max = 50, message = "{api_scenario_csv.file_id.length_range}")
@NotBlank
private String fileId;
@Schema(description = "文件名称")
@NotBlank
private String fileName;
@Schema(description = "是否是关联文件")
private Boolean association = false;
@Schema(description = "csv变量名称", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "csv变量名称", requiredMode = Schema.RequiredMode.REQUIRED)
@Size(max = 255, message = "{api_scenario_csv.name.length_range}") @Size(max = 255, message = "{api_scenario_csv.name.length_range}")
private String name; private String name;
@Schema(description = "csv 文件", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull
@Valid
private ApiFile file;
/** /**
* @see CsvVariableScope * @see CsvVariableScope
*/ */
@ -80,9 +77,12 @@ public class CsvVariable {
@Schema(description = "遇到文件结束符停止线程") @Schema(description = "遇到文件结束符停止线程")
private Boolean stopThreadOnEof = false; private Boolean stopThreadOnEof = false;
public boolean isValid() {
return StringUtils.isNotBlank(name) && file != null;
}
public enum CsvEncodingType implements ValueEnum { public enum CsvEncodingType implements ValueEnum {
UTF8("UTF-8"), UFT16("UTF-16"), ISO885915("ISO-8859-15"), US_ASCII("US-ASCII"); UTF8("UTF-8"), UFT16("UTF-16"), ISO885915("ISO-8859-15"), US_ASCII("US-ASCII"), GBK("GBK");
private String value; private String value;
CsvEncodingType(String value) { CsvEncodingType(String value) {

View File

@ -2,7 +2,6 @@ package io.metersphere.api.mapper;
import io.metersphere.api.domain.ApiScenarioCsvStep; import io.metersphere.api.domain.ApiScenarioCsvStep;
import io.metersphere.api.dto.scenario.ApiScenarioStepDTO; import io.metersphere.api.dto.scenario.ApiScenarioStepDTO;
import io.metersphere.api.dto.scenario.CsvVariable;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -16,8 +15,6 @@ public interface ExtApiScenarioStepMapper {
List<ApiScenarioStepDTO> getStepDTOByScenarioIds(@Param("scenarioIds") List<String> scenarioIds); List<ApiScenarioStepDTO> getStepDTOByScenarioIds(@Param("scenarioIds") List<String> scenarioIds);
List<CsvVariable> getCsvVariableByScenarioId(@Param("id") String id);
List<ApiScenarioCsvStep> getCsvStepByScenarioId(@Param("scenarioId") String scenarioId); List<ApiScenarioCsvStep> getCsvStepByScenarioId(@Param("scenarioId") String scenarioId);
/** /**

View File

@ -13,11 +13,6 @@
#{scenarioId} #{scenarioId}
</foreach> </foreach>
</select> </select>
<select id="getCsvVariableByScenarioId" resultType="io.metersphere.api.dto.scenario.CsvVariable">
select
<include refid="io.metersphere.api.mapper.ApiScenarioCsvMapper.Base_Column_List"/>
from api_scenario_csv where scenario_id = #{id}
</select>
<select id="getCsvStepByScenarioId" resultType="io.metersphere.api.domain.ApiScenarioCsvStep"> <select id="getCsvStepByScenarioId" resultType="io.metersphere.api.domain.ApiScenarioCsvStep">
select select
<include refid="io.metersphere.api.mapper.ApiScenarioCsvStepMapper.Base_Column_List"/> <include refid="io.metersphere.api.mapper.ApiScenarioCsvStepMapper.Base_Column_List"/>

View File

@ -37,9 +37,7 @@ public class MsCsvChildPreConverter extends AbstractJmeterElementConverter<Abstr
csvIds.forEach(csvId -> { csvIds.forEach(csvId -> {
CsvVariable csvVariable = apiParamConfig.getCsvVariable(csvId); CsvVariable csvVariable = apiParamConfig.getCsvVariable(csvId);
if (csvVariable != null) { if (csvVariable != null) {
String shareMode = StringUtils.equals(csvVariable.getScope(), CsvVariable.CsvVariableScope.SCENARIO.name()) ? addCsvDataSet(tree, JmeterProperty.CSVDataSetProperty.SHARE_MODE_THREAD, csvVariable);
JmeterProperty.CSVDataSetProperty.SHARE_MODE_GROUP : JmeterProperty.CSVDataSetProperty.SHARE_MODE_THREAD;
addCsvDataSet(tree, shareMode, csvVariable);
} }
}); });
} }
@ -49,8 +47,11 @@ public class MsCsvChildPreConverter extends AbstractJmeterElementConverter<Abstr
} }
private static void addCsvDataSet(HashTree tree, String shareMode, CsvVariable csvVariable) { private static void addCsvDataSet(HashTree tree, String shareMode, CsvVariable csvVariable) {
if (!csvVariable.isValid()) {
return;
}
// 执行机执行文件存放的缓存目录 // 执行机执行文件存放的缓存目录
String path = LocalRepositoryDir.getSystemCacheDir() + "/" + csvVariable.getFileId() + "/" + csvVariable.getFileName(); String path = LocalRepositoryDir.getSystemCacheDir() + "/" + csvVariable.getFile().getFileId() + "/" + csvVariable.getFile().getFileName();
if (!StringUtils.equals(File.separator, "/")) { if (!StringUtils.equals(File.separator, "/")) {
// windows 系统下运行 / 转换为 \否则jmeter报错 // windows 系统下运行 / 转换为 \否则jmeter报错
path = path.replace("/", File.separator); path = path.replace("/", File.separator);

View File

@ -565,6 +565,11 @@ public class ApiScenarioService extends MoveNodeService {
BeanUtils.copyBean(scenarioCsv, item); BeanUtils.copyBean(scenarioCsv, item);
scenarioCsv.setScenarioId(scenario.getId()); scenarioCsv.setScenarioId(scenario.getId());
scenarioCsv.setProjectId(scenario.getProjectId()); scenarioCsv.setProjectId(scenario.getProjectId());
ApiFile file = item.getFile();
scenarioCsv.setFileId(file.getFileId());
scenarioCsv.setFileName(file.getFileName());
scenarioCsv.setAssociation(BooleanUtils.isFalse(file.getLocal()));
if (!dbCsvIdSet.contains(item.getId())) { if (!dbCsvIdSet.contains(item.getId())) {
addCsvList.add(scenarioCsv); addCsvList.add(scenarioCsv);
} else { } else {
@ -595,7 +600,9 @@ public class ApiScenarioService extends MoveNodeService {
// 获取请求中关联的文件id // 获取请求中关联的文件id
List<String> refFileIds = csvVariables.stream() List<String> refFileIds = csvVariables.stream()
.filter(c -> BooleanUtils.isTrue(c.getAssociation())).map(CsvVariable::getFileId).toList(); .map(CsvVariable::getFile)
.filter(c -> BooleanUtils.isFalse(c.getLocal()))
.map(ApiFile::getFileId).toList();
List<String> unlinkFileIds = ListUtils.subtract(dbRefFileIds, refFileIds); List<String> unlinkFileIds = ListUtils.subtract(dbRefFileIds, refFileIds);
resourceUpdateRequest.setUnLinkFileIds(unlinkFileIds); resourceUpdateRequest.setUnLinkFileIds(unlinkFileIds);
@ -612,8 +619,9 @@ public class ApiScenarioService extends MoveNodeService {
// 获取请求中的本地文件 // 获取请求中的本地文件
List<String> localFileIds = csvVariables.stream() List<String> localFileIds = csvVariables.stream()
.filter(c -> BooleanUtils.isFalse(c.getAssociation())) .map(CsvVariable::getFile)
.map(CsvVariable::getFileId).toList(); .filter(c -> BooleanUtils.isTrue(c.getLocal()))
.map(ApiFile::getFileId).toList();
// 待删除文件 // 待删除文件
List<String> deleteLocals = ListUtils.subtract(dbLocalFileIds, localFileIds); List<String> deleteLocals = ListUtils.subtract(dbLocalFileIds, localFileIds);
@ -2056,6 +2064,15 @@ public class ApiScenarioService extends MoveNodeService {
followerExample.createCriteria().andUserIdEqualTo(userId); followerExample.createCriteria().andUserIdEqualTo(userId);
List<ApiScenarioFollower> followers = apiScenarioFollowerMapper.selectByExample(followerExample); List<ApiScenarioFollower> followers = apiScenarioFollowerMapper.selectByExample(followerExample);
apiScenarioDetailDTO.setFollow(CollectionUtils.isNotEmpty(followers)); apiScenarioDetailDTO.setFollow(CollectionUtils.isNotEmpty(followers));
// 设置关联的文件的最新信息
List<ApiFile> csvApiFiles = apiScenarioDetail.getScenarioConfig()
.getVariable()
.getCsvVariables()
.stream()
.map(CsvVariable::getFile)
.toList();
apiCommonService.setLinkFileInfo(apiScenarioDetail.getId(), csvApiFiles);
return apiScenarioDetailDTO; return apiScenarioDetailDTO;
} }
@ -2104,8 +2121,7 @@ public class ApiScenarioService extends MoveNodeService {
} }
//存放csv变量 //存放csv变量
List<CsvVariable> csvVariables = extApiScenarioStepMapper.getCsvVariableByScenarioId(scenarioId); apiScenarioDetail.getScenarioConfig().getVariable().setCsvVariables(getCsvVariables(scenarioId));
apiScenarioDetail.getScenarioConfig().getVariable().setCsvVariables(csvVariables);
// 获取所有步骤 // 获取所有步骤
List<ApiScenarioStepDTO> allSteps = getAllStepsByScenarioIds(List.of(scenarioId)) List<ApiScenarioStepDTO> allSteps = getAllStepsByScenarioIds(List.of(scenarioId))
@ -2154,6 +2170,22 @@ public class ApiScenarioService extends MoveNodeService {
return apiScenarioDetail; return apiScenarioDetail;
} }
private List<CsvVariable> getCsvVariables(String scenarioId) {
ApiScenarioCsvExample example = new ApiScenarioCsvExample();
example.createCriteria().andScenarioIdEqualTo(scenarioId);
List<ApiScenarioCsv> csvList = apiScenarioCsvMapper.selectByExample(example);
List<CsvVariable> csvVariables = csvList.stream().map(apiScenarioCsv -> {
CsvVariable csvVariable = BeanUtils.copyBean(new CsvVariable(), apiScenarioCsv);
ApiFile apiFile = new ApiFile();
apiFile.setFileId(apiScenarioCsv.getFileId());
apiFile.setLocal(!apiScenarioCsv.getAssociation());
apiFile.setFileName(apiScenarioCsv.getFileName());
csvVariable.setFile(apiFile);
return csvVariable;
}).collect(Collectors.toList());
return csvVariables;
}
/** /**
* 设置部分引用的步骤的启用状态 * 设置部分引用的步骤的启用状态
*/ */
@ -2312,7 +2344,6 @@ public class ApiScenarioService extends MoveNodeService {
if (stepDetail instanceof AbstractMsTestElement msTestElement) { if (stepDetail instanceof AbstractMsTestElement msTestElement) {
// 设置关联的文件的最新信息 // 设置关联的文件的最新信息
if (isRef(step.getRefType())) { if (isRef(step.getRefType())) {
apiCommonService.setLinkFileInfo(step.getResourceId(), msTestElement);
if (isApi(step.getStepType())) { if (isApi(step.getStepType())) {
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(step.getResourceId()); ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(step.getResourceId());
apiCommonService.setApiDefinitionExecuteInfo(msTestElement, apiDefinition); apiCommonService.setApiDefinitionExecuteInfo(msTestElement, apiDefinition);
@ -2321,9 +2352,9 @@ public class ApiScenarioService extends MoveNodeService {
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(apiTestCase.getApiDefinitionId()); ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(apiTestCase.getApiDefinitionId());
apiCommonService.setApiDefinitionExecuteInfo(msTestElement, apiDefinition); apiCommonService.setApiDefinitionExecuteInfo(msTestElement, apiDefinition);
} }
} else {
apiCommonService.setLinkFileInfo(step.getScenarioId(), msTestElement);
} }
apiCommonService.setLinkFileInfo(step.getId(), msTestElement);
apiCommonService.setEnableCommonScriptProcessorInfo(msTestElement); apiCommonService.setEnableCommonScriptProcessorInfo(msTestElement);
} else if (stepDetail instanceof MsScriptElement msScriptElement) { } else if (stepDetail instanceof MsScriptElement msScriptElement) {
apiCommonService.setEnableCommonScriptProcessorInfo(msScriptElement); apiCommonService.setEnableCommonScriptProcessorInfo(msScriptElement);

View File

@ -481,18 +481,24 @@ public class ApiScenarioControllerTests extends BaseTest {
List<CsvVariable> csvVariables = new ArrayList<>(); List<CsvVariable> csvVariables = new ArrayList<>();
CsvVariable csvVariable = new CsvVariable(); CsvVariable csvVariable = new CsvVariable();
csvVariable.setId(UUID.randomUUID().toString()); csvVariable.setId(UUID.randomUUID().toString());
csvVariable.setFileId(localFileId);
csvVariable.setName("csv变量"); csvVariable.setName("csv变量");
csvVariable.setFileName("test.jbc");
csvVariable.setScope(CsvVariable.CsvVariableScope.SCENARIO.name()); csvVariable.setScope(CsvVariable.CsvVariableScope.SCENARIO.name());
ApiFile file = new ApiFile();
file.setFileName("test.jbc");
file.setLocal(true);
file.setFileId(localFileId);
csvVariable.setFile(file);
csvVariables.add(csvVariable); csvVariables.add(csvVariable);
csvVariable = new CsvVariable(); csvVariable = new CsvVariable();
csvVariable.setId(UUID.randomUUID().toString()); csvVariable.setId(UUID.randomUUID().toString());
csvVariable.setFileId(fileMetadataId);
csvVariable.setName("csv-关联的"); csvVariable.setName("csv-关联的");
csvVariable.setFileName("test.jbc"); file = new ApiFile();
file.setFileId(fileMetadataId);
file.setFileName("test.jbc");
file.setLocal(false);
csvVariable.setScope(CsvVariable.CsvVariableScope.SCENARIO.name()); csvVariable.setScope(CsvVariable.CsvVariableScope.SCENARIO.name());
csvVariable.setAssociation(true); csvVariable.setFile(file);
csvVariables.add(csvVariable); csvVariables.add(csvVariable);
return csvVariables; return csvVariables;
} }
@ -646,9 +652,9 @@ public class ApiScenarioControllerTests extends BaseTest {
// 验证修改步骤 // 验证修改步骤
steps.get(0).setName("test name update"); steps.get(0).setName("test name update");
CsvVariable csvVariable = request.getScenarioConfig().getVariable().getCsvVariables().get(0); CsvVariable csvVariable = request.getScenarioConfig().getVariable().getCsvVariables().get(0);
request.getScenarioConfig().getVariable().getCsvVariables().get(0).setId(collect.get(csvVariable.getFileId()).getId()); request.getScenarioConfig().getVariable().getCsvVariables().get(0).setId(collect.get(csvVariable.getFile().getFileId()).getId());
CsvVariable csvVariable1 = request.getScenarioConfig().getVariable().getCsvVariables().get(0); CsvVariable csvVariable1 = request.getScenarioConfig().getVariable().getCsvVariables().get(0);
request.getScenarioConfig().getVariable().getCsvVariables().get(1).setId(collect.get(csvVariable1.getFileId()).getId()); request.getScenarioConfig().getVariable().getCsvVariables().get(1).setId(collect.get(csvVariable1.getFile().getFileId()).getId());
this.requestPostWithOk(DEFAULT_UPDATE, request); this.requestPostWithOk(DEFAULT_UPDATE, request);
assertUpdateSteps(steps, steptDetailMap); assertUpdateSteps(steps, steptDetailMap);
addApiScenarioSteps = steps; addApiScenarioSteps = steps;