fix(接口自动化): 修复 GET请求query参数未生效;接口测试-场景,自定义请求有域名的执行报错;批量执行串行-集合报告执行失败,所有用例测试报告页面所选用例都只running,不是一个报告 等问题
This commit is contained in:
parent
b89f3856a6
commit
fa8bb155fe
|
@ -182,7 +182,7 @@ public class ApiDefinitionController {
|
||||||
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
|
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
|
||||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
public ApiDefinitionImport testCaseImport(@RequestPart(value = "file", required = false) MultipartFile file, @RequestPart("request") ApiTestImportRequest request) {
|
public ApiDefinitionImport testCaseImport(@RequestPart(value = "file", required = false) MultipartFile file, @RequestPart("request") ApiTestImportRequest request) {
|
||||||
return apiDefinitionService.apiTestImport(file, request);//95821329-9eaa-4d2a-aa24-e6f912994716"
|
return apiDefinitionService.apiTestImport(file, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/export/{type}")
|
@PostMapping(value = "/export/{type}")
|
||||||
|
|
|
@ -7,5 +7,6 @@ public class RunModeConfig {
|
||||||
private String mode;
|
private String mode;
|
||||||
private String reportType;
|
private String reportType;
|
||||||
private String reportName;
|
private String reportName;
|
||||||
|
private String reportId;
|
||||||
private boolean onSampleError;
|
private boolean onSampleError;
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,8 +287,12 @@ public abstract class MsTestElement {
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isURL(String str) {
|
public boolean isURL(String str) {
|
||||||
try {
|
try {
|
||||||
|
if (StringUtils.isEmpty(str)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
new URL(str);
|
new URL(str);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -204,7 +204,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
try {
|
try {
|
||||||
if (config.isEffective(this.getProjectId())) {
|
if (config.isEffective(this.getProjectId())) {
|
||||||
HttpConfig httpConfig = getHttpConfig(config.getConfig().get(this.getProjectId()).getHttpConfig(), tree);
|
HttpConfig httpConfig = getHttpConfig(config.getConfig().get(this.getProjectId()).getHttpConfig(), tree);
|
||||||
if (httpConfig == null) {
|
if (httpConfig == null && !isURL(this.getUrl())) {
|
||||||
MSException.throwException("未匹配到环境,请检查环境配置");
|
MSException.throwException("未匹配到环境,请检查环境配置");
|
||||||
}
|
}
|
||||||
String url = httpConfig.getProtocol() + "://" + httpConfig.getSocket();
|
String url = httpConfig.getProtocol() + "://" + httpConfig.getSocket();
|
||||||
|
@ -228,10 +228,9 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
sampler.setProtocol(urlObject.getProtocol());
|
sampler.setProtocol(urlObject.getProtocol());
|
||||||
sampler.setPath(urlObject.getPath());
|
sampler.setPath(urlObject.getPath());
|
||||||
} else {
|
} else {
|
||||||
sampler.setDomain(httpConfig.getDomain());
|
|
||||||
//1.9 增加对Mock环境的判断
|
//1.9 增加对Mock环境的判断
|
||||||
if (this.isMockEnvironment()) {
|
if (this.isMockEnvironment()) {
|
||||||
url = url = httpConfig.getProtocol() + "://" + httpConfig.getSocket() + "/mock/" + this.getProjectId();
|
url = httpConfig.getProtocol() + "://" + httpConfig.getSocket() + "/mock/" + this.getProjectId();
|
||||||
} else {
|
} else {
|
||||||
url = httpConfig.getProtocol() + "://" + httpConfig.getSocket();
|
url = httpConfig.getProtocol() + "://" + httpConfig.getSocket();
|
||||||
}
|
}
|
||||||
|
@ -240,8 +239,14 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
if (StringUtils.isNotBlank(this.getPath())) {
|
if (StringUtils.isNotBlank(this.getPath())) {
|
||||||
envPath += this.getPath();
|
envPath += this.getPath();
|
||||||
}
|
}
|
||||||
sampler.setPort(httpConfig.getPort());
|
if (StringUtils.isNotEmpty(httpConfig.getDomain())) {
|
||||||
|
sampler.setDomain(httpConfig.getDomain());
|
||||||
sampler.setProtocol(httpConfig.getProtocol());
|
sampler.setProtocol(httpConfig.getProtocol());
|
||||||
|
} else {
|
||||||
|
sampler.setDomain("");
|
||||||
|
sampler.setProtocol("");
|
||||||
|
}
|
||||||
|
sampler.setPort(httpConfig.getPort());
|
||||||
sampler.setPath(envPath);
|
sampler.setPath(envPath);
|
||||||
}
|
}
|
||||||
String envPath = sampler.getPath();
|
String envPath = sampler.getPath();
|
||||||
|
@ -258,7 +263,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
String port = sampler.getPort() != 80 ? ":" + sampler.getPort() : "";
|
String port = sampler.getPort() != 80 ? ":" + sampler.getPort() : "";
|
||||||
path = sampler.getProtocol() + "://" + sampler.getDomain() + port + path;
|
path = sampler.getProtocol() + "://" + sampler.getDomain() + port + path;
|
||||||
}
|
}
|
||||||
sampler.setPath(path);
|
sampler.setProperty("HTTPSampler.path", path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String url = this.getUrl();
|
String url = this.getUrl();
|
||||||
|
@ -488,9 +493,6 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (httpConfig != null && (StringUtils.isEmpty(httpConfig.getProtocol()) || StringUtils.isEmpty(httpConfig.getSocket()))) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// HTTP 环境中请求头
|
// HTTP 环境中请求头
|
||||||
if (httpConfig != null) {
|
if (httpConfig != null) {
|
||||||
Arguments arguments = arguments(httpConfig.getHeaders());
|
Arguments arguments = arguments(httpConfig.getHeaders());
|
||||||
|
|
|
@ -13,17 +13,11 @@ public class HttpConfig {
|
||||||
private String socket;
|
private String socket;
|
||||||
private String domain;
|
private String domain;
|
||||||
private String protocol = "https";
|
private String protocol = "https";
|
||||||
private String defaultCondition;
|
|
||||||
private int port;
|
private int port;
|
||||||
private boolean isMock;
|
private boolean isMock;
|
||||||
private List<HttpConfigCondition> conditions;
|
private List<HttpConfigCondition> conditions;
|
||||||
private List<KeyValue> headers;
|
private List<KeyValue> headers;
|
||||||
|
|
||||||
|
|
||||||
public boolean isNode(String type) {
|
|
||||||
return StringUtils.equals(defaultCondition, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpConfig initHttpConfig(HttpConfigCondition configCondition) {
|
public HttpConfig initHttpConfig(HttpConfigCondition configCondition) {
|
||||||
HttpConfig config = new HttpConfig();
|
HttpConfig config = new HttpConfig();
|
||||||
BeanUtils.copyBean(config, configCondition);
|
BeanUtils.copyBean(config, configCondition);
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
|
|
||||||
public final static String TEST_ID = "ms.test.id";
|
public final static String TEST_ID = "ms.test.id";
|
||||||
|
|
||||||
public final static String TEST_REPORT_NAME = "ms.test.report.name";
|
public final static String TEST_REPORT_ID = "ms.test.report.name";
|
||||||
|
|
||||||
private final static String THREAD_SPLIT = " ";
|
private final static String THREAD_SPLIT = " ";
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
|
|
||||||
private String debugReportId;
|
private String debugReportId;
|
||||||
// 只有合并报告是这个有值
|
// 只有合并报告是这个有值
|
||||||
private String reportName;
|
private String setReportId;
|
||||||
|
|
||||||
//获得控制台内容
|
//获得控制台内容
|
||||||
private PrintStream oldPrintStream = System.out;
|
private PrintStream oldPrintStream = System.out;
|
||||||
|
@ -143,7 +143,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
TestResult testResult = new TestResult();
|
TestResult testResult = new TestResult();
|
||||||
testResult.setTestId(testId);
|
testResult.setTestId(testId);
|
||||||
testResult.setTotal(queue.size());
|
testResult.setTotal(queue.size());
|
||||||
testResult.setReportName(this.reportName);
|
testResult.setSetReportId(this.setReportId);
|
||||||
|
|
||||||
// 一个脚本里可能包含多个场景(ThreadGroup),所以要区分开,key: 场景Id
|
// 一个脚本里可能包含多个场景(ThreadGroup),所以要区分开,key: 场景Id
|
||||||
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
|
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
|
||||||
|
@ -484,7 +484,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
|
|
||||||
private void setParam(BackendListenerContext context) {
|
private void setParam(BackendListenerContext context) {
|
||||||
this.testId = context.getParameter(TEST_ID);
|
this.testId = context.getParameter(TEST_ID);
|
||||||
this.reportName = context.getParameter(TEST_REPORT_NAME);
|
this.setReportId = context.getParameter(TEST_REPORT_ID);
|
||||||
this.runMode = context.getParameter("runMode");
|
this.runMode = context.getParameter("runMode");
|
||||||
this.debugReportId = context.getParameter("debugReportId");
|
this.debugReportId = context.getParameter("debugReportId");
|
||||||
if (StringUtils.isBlank(this.runMode)) {
|
if (StringUtils.isBlank(this.runMode)) {
|
||||||
|
|
|
@ -129,7 +129,8 @@ public class JMeterService {
|
||||||
backendListener.setName(testId);
|
backendListener.setName(testId);
|
||||||
Arguments arguments = new Arguments();
|
Arguments arguments = new Arguments();
|
||||||
if (config != null && config.getMode().equals("serial") && config.getReportType().equals("setReport")) {
|
if (config != null && config.getMode().equals("serial") && config.getReportType().equals("setReport")) {
|
||||||
arguments.addArgument(APIBackendListenerClient.TEST_REPORT_NAME, config.getReportName());
|
arguments.addArgument(APIBackendListenerClient.TEST_REPORT_ID, config.getReportId());
|
||||||
|
|
||||||
}
|
}
|
||||||
arguments.addArgument(APIBackendListenerClient.TEST_ID, testId);
|
arguments.addArgument(APIBackendListenerClient.TEST_ID, testId);
|
||||||
if (StringUtils.isNotBlank(runMode)) {
|
if (StringUtils.isNotBlank(runMode)) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ public class TestResult {
|
||||||
|
|
||||||
private String testId;
|
private String testId;
|
||||||
|
|
||||||
private String reportName;
|
private String setReportId;
|
||||||
|
|
||||||
private String userId;
|
private String userId;
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class ApiAutomationService {
|
||||||
@Resource
|
@Resource
|
||||||
private UserMapper userMapper;
|
private UserMapper userMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private SystemParameterService systemParameterService ;
|
private SystemParameterService systemParameterService;
|
||||||
|
|
||||||
public ApiScenarioWithBLOBs getDto(String id) {
|
public ApiScenarioWithBLOBs getDto(String id) {
|
||||||
return apiScenarioMapper.selectByPrimaryKey(id);
|
return apiScenarioMapper.selectByPrimaryKey(id);
|
||||||
|
@ -692,6 +692,21 @@ public class ApiAutomationService {
|
||||||
return testPlan.getJmx(jmeterHashTree);
|
return testPlan.getJmx(jmeterHashTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkEnv(RunScenarioRequest request, List<ApiScenarioWithBLOBs> apiScenarios) {
|
||||||
|
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO.name())) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (ApiScenarioWithBLOBs apiScenarioWithBLOBs : apiScenarios) {
|
||||||
|
boolean haveEnv = checkScenarioEnv(apiScenarioWithBLOBs);
|
||||||
|
if (!haveEnv) {
|
||||||
|
builder.append(apiScenarioWithBLOBs.getName()).append("; ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (builder.length() > 0) {
|
||||||
|
MSException.throwException("场景:" + builder.toString() + "运行环境未配置,请检查!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景测试并行执行
|
* 场景测试并行执行
|
||||||
* 这种方法性能有问题 2021/04/12
|
* 这种方法性能有问题 2021/04/12
|
||||||
|
@ -712,6 +727,9 @@ public class ApiAutomationService {
|
||||||
if (apiScenarios != null && apiScenarios.size() == 1 && (apiScenarios.get(0).getStepTotal() == null || apiScenarios.get(0).getStepTotal() == 0)) {
|
if (apiScenarios != null && apiScenarios.size() == 1 && (apiScenarios.get(0).getStepTotal() == null || apiScenarios.get(0).getStepTotal() == 0)) {
|
||||||
MSException.throwException((apiScenarios.get(0).getName() + "," + Translator.get("automation_exec_info")));
|
MSException.throwException((apiScenarios.get(0).getName() + "," + Translator.get("automation_exec_info")));
|
||||||
}
|
}
|
||||||
|
// 环境检查
|
||||||
|
this.checkEnv(request, apiScenarios);
|
||||||
|
|
||||||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||||
request.setTriggerMode(ReportTriggerMode.MANUAL.name());
|
request.setTriggerMode(ReportTriggerMode.MANUAL.name());
|
||||||
}
|
}
|
||||||
|
@ -783,6 +801,9 @@ public class ApiAutomationService {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
boolean isFirst = true;
|
boolean isFirst = true;
|
||||||
|
List<String> reportList = new ArrayList<>();
|
||||||
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
|
||||||
for (ApiScenarioWithBLOBs item : apiScenarios) {
|
for (ApiScenarioWithBLOBs item : apiScenarios) {
|
||||||
if (item.getStepTotal() == null || item.getStepTotal() == 0) {
|
if (item.getStepTotal() == null || item.getStepTotal() == 0) {
|
||||||
// 只有一个场景且没有测试步骤,则提示
|
// 只有一个场景且没有测试步骤,则提示
|
||||||
|
@ -844,7 +865,8 @@ public class ApiAutomationService {
|
||||||
report = createScenarioReport(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
|
report = createScenarioReport(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
|
||||||
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig());
|
request.getExecuteType(), item.getProjectId(), request.getReportUserID(), request.getConfig());
|
||||||
}
|
}
|
||||||
apiScenarioReportMapper.insert(report);
|
reportList.add(report.getId());
|
||||||
|
batchMapper.insert(report);
|
||||||
reportIds.add(group.getName());
|
reportIds.add(group.getName());
|
||||||
}
|
}
|
||||||
group.setHashTree(scenarios);
|
group.setHashTree(scenarios);
|
||||||
|
@ -852,6 +874,14 @@ public class ApiAutomationService {
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
}
|
}
|
||||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
||||||
|
// 生成集成报告
|
||||||
|
if (request.getConfig() != null && request.getConfig().getMode().equals("serial")) {
|
||||||
|
request.getConfig().setReportId(UUID.randomUUID().toString());
|
||||||
|
APIScenarioReportResult report = createScenarioReport(request.getConfig().getReportId(), JSON.toJSONString(reportList), request.getConfig().getReportName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
|
||||||
|
ExecuteType.Saved.name(), request.getProjectId(), request.getReportUserID(), request.getConfig());
|
||||||
|
batchMapper.insert(report);
|
||||||
|
}
|
||||||
|
sqlSession.flushStatements();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
MSException.throwException(ex.getMessage());
|
MSException.throwException(ex.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -864,52 +894,46 @@ public class ApiAutomationService {
|
||||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
String definition = apiScenarioWithBLOBs.getScenarioDefinition();
|
String definition = apiScenarioWithBLOBs.getScenarioDefinition();
|
||||||
MsScenario scenario = JSONObject.parseObject(definition, MsScenario.class);
|
MsScenario scenario = JSONObject.parseObject(definition, MsScenario.class);
|
||||||
boolean sign = true;
|
boolean isEnv = true;
|
||||||
Map<String, String> envMap = scenario.getEnvironmentMap();
|
Map<String, String> envMap = scenario.getEnvironmentMap();
|
||||||
if (envMap == null) {
|
|
||||||
sign = false;
|
|
||||||
} else {
|
|
||||||
Set<String> set = envMap.keySet();
|
|
||||||
if (CollectionUtils.isEmpty(set)) {
|
|
||||||
sign = false;
|
|
||||||
} else {
|
|
||||||
ScenarioEnv apiScenarioEnv = getApiScenarioEnv(definition);
|
ScenarioEnv apiScenarioEnv = getApiScenarioEnv(definition);
|
||||||
// 所有请求非全路径检查环境
|
// 所有请求非全路径检查环境
|
||||||
if (!apiScenarioEnv.getFullUrl()) {
|
if (!apiScenarioEnv.getFullUrl()) {
|
||||||
try {
|
try {
|
||||||
|
if (envMap == null || envMap.isEmpty()) {
|
||||||
|
isEnv = false;
|
||||||
|
} else {
|
||||||
Set<String> projectIds = apiScenarioEnv.getProjectIds();
|
Set<String> projectIds = apiScenarioEnv.getProjectIds();
|
||||||
if (CollectionUtils.isNotEmpty(set)) {
|
if (CollectionUtils.isNotEmpty(envMap.keySet())) {
|
||||||
for (String id : projectIds) {
|
for (String id : projectIds) {
|
||||||
String s = envMap.get(id);
|
String s = envMap.get(id);
|
||||||
if (StringUtils.isBlank(s)) {
|
if (StringUtils.isBlank(s)) {
|
||||||
sign = false;
|
isEnv = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sign = false;
|
isEnv = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
sign = false;
|
isEnv = false;
|
||||||
LogUtil.error(e.getMessage(), e);
|
LogUtil.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.8 之前环境是 environmentId
|
// 1.8 之前环境是 environmentId
|
||||||
if (!sign) {
|
if (!isEnv) {
|
||||||
String envId = scenario.getEnvironmentId();
|
String envId = scenario.getEnvironmentId();
|
||||||
if (StringUtils.isNotBlank(envId)) {
|
if (StringUtils.isNotBlank(envId)) {
|
||||||
sign = true;
|
isEnv = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sign;
|
return isEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景执行
|
* 串行,利用JMETER自身串行机制执行
|
||||||
*
|
*
|
||||||
* @param request
|
* @param request
|
||||||
* @return
|
* @return
|
||||||
|
@ -926,18 +950,6 @@ public class ApiAutomationService {
|
||||||
});
|
});
|
||||||
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectByIds(idStr.toString().substring(0, idStr.toString().length() - 1), "\"" + StringUtils.join(ids, ",") + "\"");
|
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectByIds(idStr.toString().substring(0, idStr.toString().length() - 1), "\"" + StringUtils.join(ids, ",") + "\"");
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO.name())) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for (ApiScenarioWithBLOBs apiScenarioWithBLOBs : apiScenarios) {
|
|
||||||
boolean haveEnv = checkScenarioEnv(apiScenarioWithBLOBs);
|
|
||||||
if (!haveEnv) {
|
|
||||||
builder.append(apiScenarioWithBLOBs.getName()).append("; ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (builder.length() > 0) {
|
|
||||||
MSException.throwException("场景:" + builder.toString() + "运行环境未配置,请检查!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String runMode = ApiRunMode.SCENARIO.name();
|
String runMode = ApiRunMode.SCENARIO.name();
|
||||||
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
||||||
runMode = ApiRunMode.SCENARIO_PLAN.name();
|
runMode = ApiRunMode.SCENARIO_PLAN.name();
|
||||||
|
@ -945,6 +957,10 @@ public class ApiAutomationService {
|
||||||
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||||
runMode = ApiRunMode.DEFINITION.name();
|
runMode = ApiRunMode.DEFINITION.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 环境检查
|
||||||
|
this.checkEnv(request, apiScenarios);
|
||||||
|
|
||||||
// 调用执行方法
|
// 调用执行方法
|
||||||
List<String> reportIds = new LinkedList<>();
|
List<String> reportIds = new LinkedList<>();
|
||||||
try {
|
try {
|
||||||
|
@ -1034,6 +1050,8 @@ public class ApiAutomationService {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MSException.throwException(e.getMessage());
|
MSException.throwException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
System.out.println(request.getTestElement().getJmx(hashTree));
|
||||||
|
|
||||||
// 调用执行方法
|
// 调用执行方法
|
||||||
APIScenarioReportResult report = createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
APIScenarioReportResult report = createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
||||||
SessionUtils.getUserId(), null);
|
SessionUtils.getUserId(), null);
|
||||||
|
@ -1296,7 +1314,9 @@ public class ApiAutomationService {
|
||||||
BeanUtils.copyBean(scenarioWithBLOBs, request);
|
BeanUtils.copyBean(scenarioWithBLOBs, request);
|
||||||
scenarioWithBLOBs.setCreateTime(System.currentTimeMillis());
|
scenarioWithBLOBs.setCreateTime(System.currentTimeMillis());
|
||||||
scenarioWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
scenarioWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||||
|
if (StringUtils.isEmpty(scenarioWithBLOBs.getStatus())) {
|
||||||
scenarioWithBLOBs.setStatus(APITestStatus.Underway.name());
|
scenarioWithBLOBs.setStatus(APITestStatus.Underway.name());
|
||||||
|
}
|
||||||
scenarioWithBLOBs.setProjectId(apiTestImportRequest.getProjectId());
|
scenarioWithBLOBs.setProjectId(apiTestImportRequest.getProjectId());
|
||||||
if (StringUtils.isEmpty(request.getPrincipal())) {
|
if (StringUtils.isEmpty(request.getPrincipal())) {
|
||||||
scenarioWithBLOBs.setPrincipal(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
scenarioWithBLOBs.setPrincipal(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||||
|
|
|
@ -366,7 +366,9 @@ public class ApiDefinitionService {
|
||||||
BeanUtils.copyBean(saveReq, apiDefinition);
|
BeanUtils.copyBean(saveReq, apiDefinition);
|
||||||
apiDefinition.setCreateTime(System.currentTimeMillis());
|
apiDefinition.setCreateTime(System.currentTimeMillis());
|
||||||
apiDefinition.setUpdateTime(System.currentTimeMillis());
|
apiDefinition.setUpdateTime(System.currentTimeMillis());
|
||||||
|
if(StringUtils.isEmpty(apiDefinition.getStatus())) {
|
||||||
apiDefinition.setStatus(APITestStatus.Underway.name());
|
apiDefinition.setStatus(APITestStatus.Underway.name());
|
||||||
|
}
|
||||||
if (apiDefinition.getUserId() == null) {
|
if (apiDefinition.getUserId() == null) {
|
||||||
apiDefinition.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
apiDefinition.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -37,6 +37,7 @@ import javax.annotation.Resource;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -343,11 +344,23 @@ public class ApiScenarioReportService {
|
||||||
|
|
||||||
private void margeReport(TestResult result, StringBuilder scenarioIds, StringBuilder scenarioNames, String runMode, String projectId, String userId, List<String> reportIds) {
|
private void margeReport(TestResult result, StringBuilder scenarioIds, StringBuilder scenarioNames, String runMode, String projectId, String userId, List<String> reportIds) {
|
||||||
// 合并生成一份报告
|
// 合并生成一份报告
|
||||||
if (StringUtils.isNotEmpty(result.getReportName())) {
|
if (StringUtils.isNotEmpty(result.getSetReportId())) {
|
||||||
// 清理其他报告保留一份合并后的报告
|
// 清理其他报告保留一份合并后的报告
|
||||||
this.deleteByIds(reportIds);
|
this.deleteByIds(reportIds);
|
||||||
|
|
||||||
ApiScenarioReport report = createScenarioReport(scenarioIds.toString(), result.getReportName(), result.getError() > 0 ? "Error" : "Success", scenarioNames.toString().substring(0, scenarioNames.toString().length() - 1), runMode, projectId, userId);
|
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(result.getSetReportId());
|
||||||
|
report.setStatus(result.getError() > 0 ? "Error" : "Success");
|
||||||
|
if (StringUtils.isNotEmpty(userId)) {
|
||||||
|
report.setUserId(userId);
|
||||||
|
} else {
|
||||||
|
report.setUserId(SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
report.setTriggerMode(runMode);
|
||||||
|
report.setExecuteType(ExecuteType.Saved.name());
|
||||||
|
report.setProjectId(projectId);
|
||||||
|
report.setScenarioName(scenarioNames.toString().substring(0, scenarioNames.toString().length() - 1));
|
||||||
|
report.setScenarioId(scenarioIds.toString());
|
||||||
|
apiScenarioReportMapper.updateByPrimaryKey(report);
|
||||||
ApiScenarioReportDetail detail = new ApiScenarioReportDetail();
|
ApiScenarioReportDetail detail = new ApiScenarioReportDetail();
|
||||||
detail.setContent(JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8));
|
detail.setContent(JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8));
|
||||||
detail.setReportId(report.getId());
|
detail.setReportId(report.getId());
|
||||||
|
@ -424,8 +437,27 @@ public class ApiScenarioReportService {
|
||||||
return report.getId();
|
return report.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<String> getReportIds(String content) {
|
||||||
|
try {
|
||||||
|
return JSON.parseObject(content, List.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void delete(DeleteAPIReportRequest request) {
|
public void delete(DeleteAPIReportRequest request) {
|
||||||
apiScenarioReportDetailMapper.deleteByPrimaryKey(request.getId());
|
apiScenarioReportDetailMapper.deleteByPrimaryKey(request.getId());
|
||||||
|
// 补充逻辑,如果是集成报告则把零时报告全部删除
|
||||||
|
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(request.getId());
|
||||||
|
if (report != null && StringUtils.isNotEmpty(report.getScenarioId())) {
|
||||||
|
List<String> list = getReportIds(report.getScenarioId());
|
||||||
|
if (CollectionUtils.isNotEmpty(list)) {
|
||||||
|
APIReportBatchRequest reportRequest = new APIReportBatchRequest();
|
||||||
|
reportRequest.setIds(list);
|
||||||
|
this.deleteAPIReportBatch(reportRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
apiScenarioReportMapper.deleteByPrimaryKey(request.getId());
|
apiScenarioReportMapper.deleteByPrimaryKey(request.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +483,18 @@ public class ApiScenarioReportService {
|
||||||
ids.removeAll(reportRequest.getUnSelectIds());
|
ids.removeAll(reportRequest.getUnSelectIds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ApiScenarioReportExample example = new ApiScenarioReportExample();
|
||||||
|
example.createCriteria().andIdIn(reportRequest.getIds());
|
||||||
|
List<ApiScenarioReport> reportList = apiScenarioReportMapper.selectByExample(example);
|
||||||
|
// 取出可能是集成报告的ID 放入删除
|
||||||
|
reportList.forEach(item -> {
|
||||||
|
List<String> reportIds = getReportIds(item.getScenarioId());
|
||||||
|
if (CollectionUtils.isNotEmpty(reportIds)) {
|
||||||
|
reportRequest.getIds().addAll(reportIds);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List<String> myList = reportRequest.getIds().stream().distinct().collect(Collectors.toList());
|
||||||
|
reportRequest.setIds(myList);
|
||||||
//为预防数量太多,调用删除方法时引起SQL过长的Bug,此处采取分批执行的方式。
|
//为预防数量太多,调用删除方法时引起SQL过长的Bug,此处采取分批执行的方式。
|
||||||
//每次处理的数据数量
|
//每次处理的数据数量
|
||||||
int handleCount = 7000;
|
int handleCount = 7000;
|
||||||
|
|
|
@ -99,13 +99,19 @@
|
||||||
this.isActive = !this.isActive;
|
this.isActive = !this.isActive;
|
||||||
},
|
},
|
||||||
getName(name) {
|
getName(name) {
|
||||||
if (name && name.indexOf("^@~@^") != -1) {
|
if (name && name.indexOf("^@~@^") !== -1) {
|
||||||
let arr = name.split("^@~@^");
|
let arr = name.split("^@~@^");
|
||||||
if (arr[arr.length - 1].indexOf("UUID=")) {
|
if (arr[arr.length - 1].indexOf("UUID=")) {
|
||||||
return arr[arr.length - 1].split("UUID=")[0];
|
return arr[arr.length - 1].split("UUID=")[0];
|
||||||
}
|
}
|
||||||
|
if (arr[arr.length - 1] && arr[arr.length - 1].startsWith("UUID=")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return arr[arr.length - 1];
|
return arr[arr.length - 1];
|
||||||
}
|
}
|
||||||
|
if (name && name.startsWith("UUID=")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -35,6 +35,15 @@
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div v-if="apiCase.id" style="color: #999999;font-size: 12px">
|
<div v-if="apiCase.id" style="color: #999999;font-size: 12px">
|
||||||
|
<span v-if="api.protocol==='HTTP'">
|
||||||
|
<el-tag size="mini"
|
||||||
|
:style="{'background-color': getColor(true, apiCase.request.method), border: getColor(true, apiCase.request.method)}"
|
||||||
|
class="api-el-tag">
|
||||||
|
{{ apiCase.request.method }}
|
||||||
|
</el-tag>
|
||||||
|
{{apiCase.request.path}}
|
||||||
|
<br/>
|
||||||
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{{ apiCase.createTime | timestampFormatDate }}
|
{{ apiCase.createTime | timestampFormatDate }}
|
||||||
{{ apiCase.createUser }} {{ $t('api_test.definition.request.create_info') }}
|
{{ apiCase.createUser }} {{ $t('api_test.definition.request.create_info') }}
|
||||||
|
@ -133,6 +142,7 @@
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {};
|
const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {};
|
||||||
const esbDefinitionResponse = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {};
|
const esbDefinitionResponse = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {};
|
||||||
|
import {API_METHOD_COLOUR} from "../../model/JsonData";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ApiCaseItem",
|
name: "ApiCaseItem",
|
||||||
|
@ -173,6 +183,7 @@
|
||||||
{name: this.$t('api_test.automation.batch_execute'), handleClick: this.handleRunBatch},
|
{name: this.$t('api_test.automation.batch_execute'), handleClick: this.handleRunBatch},
|
||||||
{name: this.$t('test_track.case.batch_edit_case'), handleClick: this.handleEditBatch}
|
{name: this.$t('test_track.case.batch_edit_case'), handleClick: this.handleEditBatch}
|
||||||
],
|
],
|
||||||
|
methodColorMap: new Map(API_METHOD_COLOUR),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -208,6 +219,11 @@
|
||||||
handleRunBatch() {
|
handleRunBatch() {
|
||||||
this.$emit('batchRun');
|
this.$emit('batchRun');
|
||||||
},
|
},
|
||||||
|
getColor(enable, method) {
|
||||||
|
if (enable) {
|
||||||
|
return this.methodColorMap.get(method);
|
||||||
|
}
|
||||||
|
},
|
||||||
handleEditBatch() {
|
handleEditBatch() {
|
||||||
this.$emit('batchEditCase');
|
this.$emit('batchEditCase');
|
||||||
},
|
},
|
||||||
|
@ -281,7 +297,7 @@
|
||||||
let data = this.api;
|
let data = this.api;
|
||||||
data.name = this.apiCase.name;
|
data.name = this.apiCase.name;
|
||||||
data.moduleId = module;
|
data.moduleId = module;
|
||||||
data.modulePath ="/"+ this.$t('commons.module_title');
|
data.modulePath = "/" + this.$t('commons.module_title');
|
||||||
this.setParameters(data);
|
this.setParameters(data);
|
||||||
let bodyFiles = this.getBodyUploadFiles(data);
|
let bodyFiles = this.getBodyUploadFiles(data);
|
||||||
this.$fileUpload("/api/definition/create", null, bodyFiles, data, () => {
|
this.$fileUpload("/api/definition/create", null, bodyFiles, data, () => {
|
||||||
|
@ -291,7 +307,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveCase(row,hideAlert) {
|
saveCase(row, hideAlert) {
|
||||||
let tmp = JSON.parse(JSON.stringify(row));
|
let tmp = JSON.parse(JSON.stringify(row));
|
||||||
this.isShowInput = false;
|
this.isShowInput = false;
|
||||||
if (this.validate(tmp)) {
|
if (this.validate(tmp)) {
|
||||||
|
@ -328,18 +344,18 @@
|
||||||
row.createTime = data.createTime;
|
row.createTime = data.createTime;
|
||||||
row.updateTime = data.updateTime;
|
row.updateTime = data.updateTime;
|
||||||
if (!row.message) {
|
if (!row.message) {
|
||||||
if(!hideAlert){
|
if (!hideAlert) {
|
||||||
this.$success(this.$t('commons.save_success'));
|
this.$success(this.$t('commons.save_success'));
|
||||||
this.$emit('refresh');
|
this.$emit('refresh');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveTestCase(row,hideAlert) {
|
saveTestCase(row, hideAlert) {
|
||||||
if (this.api.saved) {
|
if (this.api.saved) {
|
||||||
this.addModule(row);
|
this.addModule(row);
|
||||||
} else {
|
} else {
|
||||||
this.saveCase(row,hideAlert);
|
this.saveCase(row, hideAlert);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
showInput(row) {
|
showInput(row) {
|
||||||
|
@ -429,6 +445,12 @@
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.api-el-tag {
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 10px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.tag-item {
|
.tag-item {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,12 @@
|
||||||
return this.$t("api_test.definition.api_path");
|
return this.$t("api_test.definition.api_path");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
clearHisData() {
|
||||||
|
this.httpConfig.socket = undefined;
|
||||||
|
this.httpConfig.protocol = undefined;
|
||||||
|
this.httpConfig.port = undefined;
|
||||||
|
this.httpConfig.domain = undefined;
|
||||||
|
},
|
||||||
getDetails(row) {
|
getDetails(row) {
|
||||||
if (row && row.type === "MODULE") {
|
if (row && row.type === "MODULE") {
|
||||||
if (row.details && row.details instanceof Array) {
|
if (row.details && row.details instanceof Array) {
|
||||||
|
@ -250,7 +256,7 @@
|
||||||
return index > 1;
|
return index > 1;
|
||||||
},
|
},
|
||||||
add() {
|
add() {
|
||||||
if (this.condition.type ==="NONE" && this.checkNode()) {
|
if (this.condition.type === "NONE" && this.checkNode()) {
|
||||||
this.$warning("启用条件为 '无' 的域名已经存在请更新!");
|
this.$warning("启用条件为 '无' 的域名已经存在请更新!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -265,14 +271,12 @@
|
||||||
obj.details = this.condition.details ? JSON.parse(JSON.stringify(this.condition.details)) : this.condition.details;
|
obj.details = this.condition.details ? JSON.parse(JSON.stringify(this.condition.details)) : this.condition.details;
|
||||||
}
|
}
|
||||||
this.httpConfig.conditions.unshift(obj);
|
this.httpConfig.conditions.unshift(obj);
|
||||||
this.httpConfig.socket = null;
|
this.clearHisData();
|
||||||
this.httpConfig.protocol = null;
|
|
||||||
this.httpConfig.port = null;
|
|
||||||
this.httpConfig.domain = null;
|
|
||||||
},
|
},
|
||||||
remove(row) {
|
remove(row) {
|
||||||
const index = this.httpConfig.conditions.findIndex((d) => d.id === row.id);
|
const index = this.httpConfig.conditions.findIndex((d) => d.id === row.id);
|
||||||
this.httpConfig.conditions.splice(index, 1);
|
this.httpConfig.conditions.splice(index, 1);
|
||||||
|
this.clearHisData();
|
||||||
},
|
},
|
||||||
copy(row) {
|
copy(row) {
|
||||||
if (row.type === "NONE") {
|
if (row.type === "NONE") {
|
||||||
|
|
Loading…
Reference in New Issue