diff --git a/src/main/java/yi/master/business/message/action/AutoTestAction.java b/src/main/java/yi/master/business/message/action/AutoTestAction.java index 3e17db65dfac459e2869307a620b73e10d0ff88a..42bd3c358455377e2365fa4c5de521e0af35a6ec 100644 --- a/src/main/java/yi/master/business/message/action/AutoTestAction.java +++ b/src/main/java/yi/master/business/message/action/AutoTestAction.java @@ -22,6 +22,7 @@ import yi.master.business.user.bean.User; import yi.master.business.user.service.UserService; import yi.master.constant.SystemConsts; import yi.master.coretest.message.parse.MessageParse; +import yi.master.coretest.message.parse.URLMessageParse; import yi.master.coretest.message.test.MessageAutoTest; import yi.master.coretest.message.test.TestMessageScene; import yi.master.exception.AppErrorCode; @@ -112,16 +113,16 @@ public class AutoTestAction extends ActionSupport implements ModelDriven testObjects = autoTest.packageRequestObject(task.getScene(), config, task.getSystem(), null); @@ -183,10 +184,10 @@ public class AutoTestAction extends ActionSupport implements ModelDriven { model.setUser(FrameworkUtil.getLoginUser()); if ("1".equals(model.getParented())) { //创建测试配置 - TestConfig config = (TestConfig) testConfigService.getConfigByUserId(0).clone(); + TestConfig config = (TestConfig) testConfigService.configByUserId(0).clone(); config.setConfigId(null); config.setUserId(null); testConfigService.save(config); @@ -180,7 +180,7 @@ public class TestSetAction extends BaseAction { TestConfig config = null; if ("0".equals(mode)) { - config = (TestConfig) testConfigService.getConfigByUserId(0).clone(); + config = (TestConfig) testConfigService.configByUserId(0).clone(); config.setConfigId(null); config.setUserId(null); testConfigService.save(config); diff --git a/src/main/java/yi/master/business/message/bean/Message.hbm.xml b/src/main/java/yi/master/business/message/bean/Message.hbm.xml index 0f6ec3ef2c71dc506bbbf69c656d8554ded3ff1f..f36007e6a4ff34f81cc2cf0ed2f8310ed3ad4f0e 100644 --- a/src/main/java/yi/master/business/message/bean/Message.hbm.xml +++ b/src/main/java/yi/master/business/message/bean/Message.hbm.xml @@ -52,6 +52,10 @@ + + + + diff --git a/src/main/java/yi/master/business/message/bean/Message.java b/src/main/java/yi/master/business/message/bean/Message.java index 1a3df0db58fd624170d44a0a8baf320dcf8c77b1..964874df0a78df7165c53ef91fa70245d42a115b 100644 --- a/src/main/java/yi/master/business/message/bean/Message.java +++ b/src/main/java/yi/master/business/message/bean/Message.java @@ -117,6 +117,11 @@ public class Message implements Serializable{ * 报文处理参数 */ private String processParameter; + + /** + * body转query参数 + */ + private String bodyToQuery; // Constructors @@ -172,8 +177,17 @@ public class Message implements Serializable{ } return interfaceId; } - - public String getSystems() { + + + public String getBodyToQuery() { + return bodyToQuery; + } + + public void setBodyToQuery(String bodyToQuery) { + this.bodyToQuery = bodyToQuery; + } + + public String getSystems() { return systems; } diff --git a/src/main/java/yi/master/business/testconfig/bean/GlobalVariable.java b/src/main/java/yi/master/business/testconfig/bean/GlobalVariable.java index 8e3a7efe7893abbb6c07079d8e150a4c49c8ced4..5cfb5fffe873450f0b75057580a2716a7c4f77ff 100644 --- a/src/main/java/yi/master/business/testconfig/bean/GlobalVariable.java +++ b/src/main/java/yi/master/business/testconfig/bean/GlobalVariable.java @@ -60,9 +60,10 @@ public class GlobalVariable implements Serializable { private String variableName; @FieldRealSearch(names = {"HTTP调用参数", "Socket调用参数", "WebService调用参数", "验证关联规则", "测试集运行时配置" - , "常量", "日期", "随机数", "时间戳", "随机字符串", "动态接口", "文件参数", "数据库取值"}, + , "常量", "日期", "随机数", "时间戳", "随机字符串", "动态接口", "动态组合接口","文件参数", "数据库取值"}, values = {"httpCallParameter", "socketCallParameter", "webServiceCallParameter", "relatedKeyWord", "setRuntimeSetting" - , "constant", "datetime", "randomNum", "currentTimestamp", "randomString", "dynamicInterface", "fileParameter", "dbSql"}) + , "constant", "datetime", "randomNum", "currentTimestamp", "randomString", "dynamicInterface", "dynamicComplexInterface" + , "fileParameter", "dbSql"}) private String variableType; /** * 如果这个变量可以被使用,则需要设置key值
@@ -80,6 +81,7 @@ public class GlobalVariable implements Serializable { * randomString 两个数字,第一位表示字符串长度,第二位表示组成:0-只有大写字母 1-只有小写字母 2-大小写字母混合 3-数字和字母
* uuid 间隔符
* dynamicInterface 对应配置的JSON字符串 + * dynamicComplexInterface 对应配置的JSON字符串 * fileParameter 文件路径 */ private String value; @@ -396,6 +398,20 @@ public class GlobalVariable implements Serializable { return this.lastCreateValue; } + if (GlobalVariableType.dynamicComplexInterface.name().equalsIgnoreCase(this.variableType)) { + if (this.expiryDate != null && this.expiryDate.getTime() > System.currentTimeMillis() + && StringUtils.isNotBlank(this.lastCreateValue) + && !forceCreate) { + return this.lastCreateValue; + } + MessageAutoTest autoTest = (MessageAutoTest) FrameworkUtil.getSpringBean(MessageAutoTest.class); + + this.lastCreateValue = autoTest.dynamicComplexInterfaceGetValue(maps.get(GlobalVariableConstant.DYNAMIC_COMPLEX_INTERFACE_SCENE_ID) + , maps.get(GlobalVariableConstant.DYNAMIC_COMPLEX_INTERFACE_VALUE_NAME)); + update(); + return this.lastCreateValue; + } + if (GlobalVariableType.dbSql.name().equalsIgnoreCase(this.variableType)) { if (this.expiryDate != null && this.expiryDate.getTime() > System.currentTimeMillis() && StringUtils.isNotBlank(this.lastCreateValue) diff --git a/src/main/java/yi/master/business/testconfig/bean/TestConfig.java b/src/main/java/yi/master/business/testconfig/bean/TestConfig.java index ab768052880647e03ae588386a7f350a969cf8f8..1c6d022997abbd4b0c26e728dc0d3c11488dbbfb 100644 --- a/src/main/java/yi/master/business/testconfig/bean/TestConfig.java +++ b/src/main/java/yi/master/business/testconfig/bean/TestConfig.java @@ -345,9 +345,10 @@ public class TestConfig implements Serializable, Cloneable { TestConfig config = null; try { config = (TestConfig) super.clone(); + config.setDataPool(null); + config.setPoolItemIds(""); config.setRules(new HashSet<>()); } catch (Exception e) { - LOGGER.warn("clone exception!", e); } return config; diff --git a/src/main/java/yi/master/business/testconfig/enums/GlobalVariableType.java b/src/main/java/yi/master/business/testconfig/enums/GlobalVariableType.java index 90debed84de3ae78d4cbb2594d1e8148453c7ab7..7b71849fd99d2aeb777d336a7b1d56b9ff5be9b0 100644 --- a/src/main/java/yi/master/business/testconfig/enums/GlobalVariableType.java +++ b/src/main/java/yi/master/business/testconfig/enums/GlobalVariableType.java @@ -53,6 +53,10 @@ public enum GlobalVariableType { * 动态接口 */ dynamicInterface, + /** + * 动态组合接口 + */ + dynamicComplexInterface, /** * 文件 */ diff --git a/src/main/java/yi/master/business/testconfig/service/TestConfigService.java b/src/main/java/yi/master/business/testconfig/service/TestConfigService.java index 5529afe366d7ba9f3c157c933cce15401c9e22c1..8a57581abd0a169cfd374c29694f6d24d7627701 100644 --- a/src/main/java/yi/master/business/testconfig/service/TestConfigService.java +++ b/src/main/java/yi/master/business/testconfig/service/TestConfigService.java @@ -10,5 +10,5 @@ public interface TestConfigService extends BaseService { * @param userId 0为系统默认配置 * @return */ - TestConfig getConfigByUserId(Integer userId); + TestConfig configByUserId(Integer userId); } diff --git a/src/main/java/yi/master/business/testconfig/service/impl/PoolDataItemServiceImpl.java b/src/main/java/yi/master/business/testconfig/service/impl/PoolDataItemServiceImpl.java index 6abb2f36be6d59d03ef5473cbf19e4cec496dbaf..328b21750a283e6cbe96c90e4f0923f1970aee3f 100644 --- a/src/main/java/yi/master/business/testconfig/service/impl/PoolDataItemServiceImpl.java +++ b/src/main/java/yi/master/business/testconfig/service/impl/PoolDataItemServiceImpl.java @@ -92,7 +92,7 @@ public class PoolDataItemServiceImpl extends BaseServiceImpl imple if (poolDataItem.getSceneSystem() == null) { throw new YiException("数据池[{}]自动获取数据出错:你必须为接口场景选择一个可用的测试环境", poolDataItem.getDataPool().getName()); } - TestConfig testConfig = testConfigService.getConfigByUserId(FrameworkUtil.getLoginUser().getUserId()); + TestConfig testConfig = testConfigService.configByUserId(FrameworkUtil.getLoginUser().getUserId()); Set testMessageScenes = messageAutoTest.packageRequestObject(poolDataItem.getMessageScene(), testConfig, poolDataItem.getSceneSystem(), null); if (CollUtil.isEmpty(testMessageScenes)) { throw new YiException("数据池[{}]自动获取数据出错:通过接口获取数据出错:无法解析要使用的接口场景", poolDataItem.getDataPool().getName()); diff --git a/src/main/java/yi/master/business/testconfig/service/impl/TestConfigServiceImpl.java b/src/main/java/yi/master/business/testconfig/service/impl/TestConfigServiceImpl.java index 295645315de2ec5602c64a0b21a64bcb0764a46f..f039640407c283d417b6382cc0548f6b02da24e0 100644 --- a/src/main/java/yi/master/business/testconfig/service/impl/TestConfigServiceImpl.java +++ b/src/main/java/yi/master/business/testconfig/service/impl/TestConfigServiceImpl.java @@ -2,7 +2,6 @@ package yi.master.business.testconfig.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; - import yi.master.business.base.service.impl.BaseServiceImpl; import yi.master.business.testconfig.bean.TestConfig; import yi.master.business.testconfig.dao.TestConfigDao; @@ -20,10 +19,10 @@ public class TestConfigServiceImpl extends BaseServiceImpl implement } @Override - public TestConfig getConfigByUserId(Integer userId) { + public TestConfig configByUserId(Integer userId) { TestConfig config = testConfigDao.getConfigByUserId(userId); if (config == null) { - config = (TestConfig) getConfigByUserId(0).clone(); + config = (TestConfig) configByUserId(0).clone(); config.setConfigId(null); config.setUserId(userId); config.setConfigId(save(config)); diff --git a/src/main/java/yi/master/constant/GlobalVariableConstant.java b/src/main/java/yi/master/constant/GlobalVariableConstant.java index dcb336de07146122faff4f95e5d0acdbf2d9e5a3..861cb29f9a887106a57204c74f01236503e64feb 100644 --- a/src/main/java/yi/master/constant/GlobalVariableConstant.java +++ b/src/main/java/yi/master/constant/GlobalVariableConstant.java @@ -41,6 +41,10 @@ public interface GlobalVariableConstant { String DYNAMIC_INTERFACE_SYSTEM_ID = "systemId"; String DYNAMIC_INTERFACE_SCENE_ID = "sceneId"; String DYNAMIC_INTERFACE_VALUE_EXPRESSION = "valueExpression"; + + /**动态组合接口*/ + String DYNAMIC_COMPLEX_INTERFACE_SCENE_ID = "complexSceneId"; + String DYNAMIC_COMPLEX_INTERFACE_VALUE_NAME = "valueName"; /**数据库取值*/ String DB_SQL_DB_ID = "dbId"; diff --git a/src/main/java/yi/master/constant/SystemConsts.java b/src/main/java/yi/master/constant/SystemConsts.java index efb30afb9695cc2022f0d2ed0a39a17060c7ce54..9c2c00a42aeae0b3ff65178f8b67311ac0e083a0 100644 --- a/src/main/java/yi/master/constant/SystemConsts.java +++ b/src/main/java/yi/master/constant/SystemConsts.java @@ -13,7 +13,7 @@ public interface SystemConsts { /** * 当前版本号 */ - String VERSION = "1.1.2"; + String VERSION = "1.1.3"; /** @@ -185,6 +185,7 @@ public interface SystemConsts { */ String GLOBAL_SETTING_MESSAGE_ENCODING = "messageEncoding"; String GLOBAL_SETTING_MESSAGE_REPORT_TITLE = "messageReportTitle"; + String GLOBAL_SETTING_MESSAGE_CALL_HOME_URL = "messageCallHomeUrl"; /** * 邮件推送格式 */ diff --git a/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java b/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java index d5304988d40d0f95f90a093fc47b85c1b4a84269..1abaf715f6f97f515d8273b6a3da6b043fca8e66 100644 --- a/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java @@ -254,7 +254,19 @@ public class HTTPTestClient extends TestClient { + ",proxyPort=" + scene.getBusinessSystem().getProxyPort()); client = proxyClient; } - + + //body转url + if (scene.isBodyToQuery()) { + if (!URLMessageParse.getInstance().messageFormatValidation(requestMessage)) { + throw new RuntimeException("请将报文设置为URL格式"); + } + if (querys == null) { + querys = new HashMap<>(); + } + querys.putAll(URLMessageParse.parseUrlToMap(requestMessage, null)); + requestMessage = ""; + } + HttpResponse response = null; long useTime = 0; HttpRequestBase request = null; @@ -441,10 +453,10 @@ public class HTTPTestClient extends TestClient { * @return * @throws Exception */ - private Object[] doPost(String method, String host, Map headers, Map querys, String body, String charSet, DefaultHttpClient client) + private Object[] doPost(String method, String host, Map headers, Map querys, String body + , String charSet, DefaultHttpClient client) throws Exception { HttpEntityEnclosingRequestBase request = null; - if (HttpMethod.PUT.name().equalsIgnoreCase(method)) { request = new HttpPut(buildUrl(host, querys)); } else if (HttpMethod.DELETE.name().equalsIgnoreCase(method)) { @@ -603,7 +615,7 @@ public class HTTPTestClient extends TestClient { } } } catch (Exception e) { - throw new RuntimeException("设置代理出错,请检查环境的代理配置", e); + throw new RuntimeException("设置代理出错,请检查测试环境的代理配置", e); } return null; diff --git a/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java b/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java index ed15655956e1a23a8fa975af3e697031445f6273..d5fb554b2d06b6bc89a06c83ce8581d64b58e2a5 100644 --- a/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java +++ b/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java @@ -31,6 +31,7 @@ import yi.master.coretest.message.parse.MessageParse; import yi.master.coretest.message.process.MessageProcess; import yi.master.coretest.message.protocol.TestClient; import yi.master.coretest.message.protocol.entity.ClientTestResponseObject; +import yi.master.exception.YiException; import yi.master.util.FrameworkUtil; import yi.master.util.PracticalUtils; import yi.master.util.cache.CacheUtil; @@ -95,7 +96,7 @@ public class MessageAutoTest { LOGGER.warn("当前测试进程无法获取到指定用户的测试配置,但是不影响测试进行,使用全局测试配置!"); } - TestConfig config = testConfigService.getConfigByUserId(testUserId); + TestConfig config = testConfigService.configByUserId(testUserId); //执行测试 MessageScene scene = messageSceneService.get(Integer.valueOf(sceneId)); @@ -134,6 +135,40 @@ public class MessageAutoTest { return v; } + + /** + * 动态组合接口获取数据 + * @param complexSceneId + * @param valueName + * @return + */ + public String dynamicComplexInterfaceGetValue(String complexSceneId, String valueName) throws Exception { + if (StringUtils.isBlank(complexSceneId) || StringUtils.isBlank(valueName)) { + throw new YiException("变量参数不正确"); + } + Integer testUserId = 0; + try { + if (FrameworkUtil.getLoginUser() != null) { + testUserId =FrameworkUtil.getLoginUser().getUserId(); + } + } catch (Exception e) { + LOGGER.warn("当前测试进程无法获取到指定用户的测试配置,但是不影响测试进行,使用全局测试配置!"); + } + TestConfig config = testConfigService.configByUserId(testUserId); + + ComplexScene complexScene = complexSceneService.get(Integer.valueOf(complexSceneId)); + if (complexScene == null) { + throw new YiException("指定的测试场景不存在或者已被删除,请检查!"); + } + + TestMessageScene messageScene = packageComplexRequestObject(complexScene, config, null, null); + Map vars = (Map) singleTestComplexScene(messageScene, null, true, true); + if (MapUtil.isNotEmpty(vars)) { + return vars.get(valueName); + } + + return null; + } /** * 单场景测试 @@ -241,10 +276,11 @@ public class MessageAutoTest { * @param testScene testScene 测试场景对象 * @param report report 测试报告对象 * @param ifDebug ifDebug 是否调试:调试时不保存结果到数据库 + * @param dynamicComplexInterface dynamicComplexInterface 是否是动态组合接口 * @return {@link Object} */ @SuppressWarnings("unchecked") - public Object singleTestComplexScene (TestMessageScene testScene, TestReport report, boolean ifDebug) { + public Object singleTestComplexScene (TestMessageScene testScene, TestReport report, boolean ifDebug, boolean dynamicComplexInterface) { List results = new ArrayList<>(); //获取httpclient,其他协议的暂时也走这个,但是不影响,后期需要针对不同协议的客户端做改动 DefaultHttpClient procotolClient = null; @@ -252,11 +288,11 @@ public class MessageAutoTest { //组合场景测试备注 StringBuilder complexMark = new StringBuilder(); - //组合场景中的场景是否为空 + //该组合场景测试上下文保存的变量 + Map saveVariables = new HashMap(); + //组合场景中的场景是否为空 if (testScene.getScenes().size() > 0) { allSuccessFlag = true; - //该组合场景测试上下文保存的变量 - Map saveVariables = new HashMap(); //停止标记 boolean stopFlag = false; @@ -357,10 +393,14 @@ public class MessageAutoTest { } } - if(testScene.getTestClient() != null) { testScene.getTestClient().putBackTestClient(procotolClient); } + + // 动态组合接口获取值 + if (dynamicComplexInterface) { + return saveVariables; + } //如果缺少场景(结果和场景数量不等),表明有某些场景设定的测试环境在原本的测试场景中已经被删除了或者直接执行了最好一个场景,此时,组合场景必须为测试失败状态并添加备注 if (results.size() != testScene.getScenes().size()) { @@ -549,7 +589,7 @@ public class MessageAutoTest { } //选择测试配置 - TestConfig config1 = testConfigService.getConfigByUserId(user.getUserId()); + TestConfig config1 = testConfigService.configByUserId(user.getUserId()); if (set != null && set.getConfig() != null) { config1 = set.getConfig(); @@ -645,7 +685,7 @@ public class MessageAutoTest { public void run() { //组合场景 if (testSceneT.getComplexFlag()) { - singleTestComplexScene(testSceneT, report, false); + singleTestComplexScene(testSceneT, report, false, false); //单场景 } else { TestResult result = singleTest(testSceneT, null); @@ -865,6 +905,7 @@ public class MessageAutoTest { testScene.setTestClient(TestClient.getTestClientInstance(info.getInterfaceProtocol())); testScene.setRequestMessage(requestMessage); + testScene.setBodyToQuery(SystemConsts.DefaultBooleanIdentify.TRUE.getNumber().equals(msg.getBodyToQuery()) ? true : false); testScene.setComplexFlag(false); testScene.setScene(scene); testScene.setRequestUrl(requestUrl); diff --git a/src/main/java/yi/master/coretest/message/test/TestMessageScene.java b/src/main/java/yi/master/coretest/message/test/TestMessageScene.java index 2688ee5ae3f08ddacab78d42c556444ce88502e4..606589bc2df08799f233796546b9b2d2d6312e92 100644 --- a/src/main/java/yi/master/coretest/message/test/TestMessageScene.java +++ b/src/main/java/yi/master/coretest/message/test/TestMessageScene.java @@ -105,6 +105,11 @@ public class TestMessageScene implements Cloneable { */ private Integer poolDataItemId; + /** + * body转query + */ + private boolean bodyToQuery; + public TestMessageScene(MessageScene scene,String requestUrl, String requestMessage, Integer dataId, Boolean complexFlag) { @@ -138,7 +143,15 @@ public class TestMessageScene implements Cloneable { } - public void setPoolDataItemId(Integer poolDataItemId) { + public boolean isBodyToQuery() { + return bodyToQuery; + } + + public void setBodyToQuery(boolean bodyToQuery) { + this.bodyToQuery = bodyToQuery; + } + + public void setPoolDataItemId(Integer poolDataItemId) { this.poolDataItemId = poolDataItemId; } diff --git a/src/main/java/yi/master/coretest/message/test/performance/PerformanceTestObject.java b/src/main/java/yi/master/coretest/message/test/performance/PerformanceTestObject.java index 5c16a6c9a6885021afd701d85f4c458f7c35fc23..8ae016702bfc3f4f8819a7b29476800be30854a6 100644 --- a/src/main/java/yi/master/coretest/message/test/performance/PerformanceTestObject.java +++ b/src/main/java/yi/master/coretest/message/test/performance/PerformanceTestObject.java @@ -206,9 +206,9 @@ public class PerformanceTestObject { //手动组装场景测试对象 User user = FrameworkUtil.getLoginUser(); TestConfigService testConfigService = (TestConfigService) FrameworkUtil.getSpringBean("testConfigService"); - TestConfig testConfig = testConfigService.getConfigByUserId(user.getUserId()); + TestConfig testConfig = testConfigService.configByUserId(user.getUserId()); if (testConfig == null) { - testConfig = testConfigService.getConfigByUserId(0); + testConfig = testConfigService.configByUserId(0); } testScene = new TestMessageScene(config.getMessageScene(), requestUrl, new String(requestMessage), 0, false, testConfig, PracticalUtils.jsonToMap(PracticalUtils.replaceGlobalVariable(msg.getCallParameter(), null))); testScene.setBusinessSystem(config.getBusinessSystem()); diff --git a/src/main/java/yi/master/listener/VersionUpdateUtil.java b/src/main/java/yi/master/listener/VersionUpdateUtil.java index 44a74c8b7e84d8f7cc34f177438a7f1d64717cc9..fb8a7ec080dafc5743a63893f7e6f5efee7e311f 100644 --- a/src/main/java/yi/master/listener/VersionUpdateUtil.java +++ b/src/main/java/yi/master/listener/VersionUpdateUtil.java @@ -54,6 +54,7 @@ public class VersionUpdateUtil { ALL_VERSION_LIST.add("1.1.0"); ALL_VERSION_LIST.add("1.1.1"); ALL_VERSION_LIST.add("1.1.2"); + ALL_VERSION_LIST.add("1.1.3"); } /** diff --git a/src/main/java/yi/master/util/PracticalUtils.java b/src/main/java/yi/master/util/PracticalUtils.java index 02f75acb82f6df6c5fe5ad9d5c6df793f257fd98..ca4671314989ef2a31764c3c01d8f13c322522d7 100644 --- a/src/main/java/yi/master/util/PracticalUtils.java +++ b/src/main/java/yi/master/util/PracticalUtils.java @@ -1089,6 +1089,8 @@ public class PracticalUtils { return maps; } + + /** * json串转json对象 * @author xuwangcheng diff --git a/src/main/java/yi/master/util/cache/CacheUtil.java b/src/main/java/yi/master/util/cache/CacheUtil.java index 75f33e658d377e59808a081ab6ccd66f7b56c9a6..432bff67e851d31a873e902924548b7fc0c01165 100644 --- a/src/main/java/yi/master/util/cache/CacheUtil.java +++ b/src/main/java/yi/master/util/cache/CacheUtil.java @@ -62,9 +62,13 @@ public class CacheUtil { private static List systemInterfaces = new ArrayList<>(); /** - * 首页地址 + * 配置的首页地址 */ private static String homeUrl; + /** + * 自动获取的首页地址 + */ + private static String autoGetHomeUrl; public static void setQueryDBMap(Map queryDBMap) { CacheUtil.queryDBMap = queryDBMap; @@ -299,10 +303,10 @@ public class CacheUtil { * @param request */ public static void setHomeUrl (HttpServletRequest request) { - if (StringUtils.isNotBlank(homeUrl)) { + if (StringUtils.isNotBlank(autoGetHomeUrl)) { return; } - homeUrl = request.getRequestURL().toString().replace(request.getServletPath(), ""); + autoGetHomeUrl = request.getRequestURL().toString().replace(request.getServletPath(), ""); } /** @@ -313,9 +317,13 @@ public class CacheUtil { * @return {@link String} */ public static String getHomeUrl() { - if (StringUtils.isBlank(homeUrl)) { - return getSettingValue(SystemConsts.GLOBAL_SETTING_HOME); - } - return homeUrl; + if ("0".equals(getSettingValue(SystemConsts.GLOBAL_SETTING_MESSAGE_CALL_HOME_URL))) { + // 使用自动获取的地址 + if (StringUtils.isNotBlank(autoGetHomeUrl)) { + return autoGetHomeUrl; + } + } + // 使用配置的地址 + return getSettingValue(SystemConsts.GLOBAL_SETTING_HOME); } } diff --git a/src/main/resources/applicationContext.xml b/src/main/resources/applicationContext.xml index ba036221de2659e119848cf775bdb0b99f809f96..54a73c4a9ebe01f6c70c7313b08edf6d4558535d 100644 --- a/src/main/resources/applicationContext.xml +++ b/src/main/resources/applicationContext.xml @@ -109,6 +109,7 @@ + diff --git a/src/main/resources/update/1.1.3 b/src/main/resources/update/1.1.3 new file mode 100644 index 0000000000000000000000000000000000000000..5a8320abc86d18cd47beb782dcd94b78689a6aad --- /dev/null +++ b/src/main/resources/update/1.1.3 @@ -0,0 +1,4 @@ +SET FOREIGN_KEY_CHECKS=0; +ALTER TABLE `at_message` ADD COLUMN `body_to_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '0' COMMENT 'body体内容转query参数' AFTER `project_id`; +INSERT INTO `at_global_setting`(`setting_id`, `setting_name`, `default_value`, `setting_value`, `mark`) VALUES (26, 'messageCallHomeUrl', '0', '0', '接口自动化内部请求地址'); +SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file diff --git a/src/main/webapp/js/globalConstant.js b/src/main/webapp/js/globalConstant.js index 24d474655034fb97a6356be2fc07e7ed9052b08d..f823a2ecfc83d0e30735c681d8aa27df58b6728e 100644 --- a/src/main/webapp/js/globalConstant.js +++ b/src/main/webapp/js/globalConstant.js @@ -505,6 +505,8 @@ var MESSAGE_PROTOCOL = { "HTTPS":{ "Headers":{ }, + "Querys":{ + }, "Authorization":{ }, "Method":"POST", diff --git a/src/main/webapp/resource/message/autoTask.js b/src/main/webapp/resource/message/autoTask.js index ab6fe34ec2d2080b5f73efc44e2bd3119813dcc6..16f0fdf1b0264f1c4d5d69af856f9b1c2f62eb95 100644 --- a/src/main/webapp/resource/message/autoTask.js +++ b/src/main/webapp/resource/message/autoTask.js @@ -109,6 +109,7 @@ var templateParams = { }, { required:true, + reminder: "暂不可用", label:"短信通知", select:[{ name:"smsNotify", diff --git a/src/main/webapp/resource/message/chooseComplexScene.html b/src/main/webapp/resource/message/chooseComplexScene.html new file mode 100644 index 0000000000000000000000000000000000000000..7e816b9efdb4578947e9f0617e8c708a6dba8311 --- /dev/null +++ b/src/main/webapp/resource/message/chooseComplexScene.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + + + + + + + + +
ID
+
+
+
+ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/resource/message/chooseComplexScene.js b/src/main/webapp/resource/message/chooseComplexScene.js new file mode 100644 index 0000000000000000000000000000000000000000..56bd20c1f2a4aff9025a3c37c1a463bf66eeee52 --- /dev/null +++ b/src/main/webapp/resource/message/chooseComplexScene.js @@ -0,0 +1,142 @@ +var templateParams = { + tableTheads:["名称", "包含场景", "创建时间", "独立客户端测试","备注", "操作"], + btnTools:[] +}; + +var columnsSetting = [ + { + "data":null, + "render":function(data, type, full, meta){ + return checkboxHmtl(data.complexSceneName, data.id, "selectComplexScene"); + }}, + {"data":"id"}, + ellipsisData("complexSceneName"), + { + "data":"sceneNum", + "render":function(data, type, full, meta){ + var context = + [{ + type:"default", + size:"M", + markClass:"show-scenes", + name:data + }]; + return btnTextTemplate(context); + } + }, + ellipsisData("createTime"), + { + "data":"newClient", + "render":function(data){ + var option = { + "0":{ + btnStyle:"success", + status:"是" + }, + "1":{ + btnStyle:"default", + status:"否" + }, + "default":{ + btnStyle:"default", + status:"否" + } + + }; + return labelCreate(data, option); + } + }, + { + "data":"mark", + "className":"ellipsis", + "render":function(data, type, full, meta) { + if (data != "" && data != null) { + return '' + data + ''; + } + return ""; + } + }, + { + "data":null, + "render":function(data, type, full, meta){ + return btnIconTemplate( + [{ + title:"组合场景测试", + markClass:"object-test", + iconFont:"" + },{ + title:"选择", + markClass:"choose-this-scene", + iconFont:"" + }]); + } + } +]; +var eventList = { + ".object-test":function(){//组合场景测试 + var data = table.row( $(this).parents('tr') ).data(); + layer.confirm('确认测试该组合场景吗?
组合场景的测试时间长度和包含的场景数有关,请耐心等待测试完成!', {title:'提示', icon:3}, function(index){ + var loadIndex = layer.msg('正在测试,请耐心等待...', {icon:16, time:9999999, shade:0.4}); + $.post(REQUEST_URL.AUTO_TEST.TEST_COMPLEX_SCENE_URL, {id:data.id}, function(json){ + layer.close(loadIndex); + if (json.returnCode == 0 && json.data != null) { + var results = json.data; + if (json.data.length == undefined) { + results = json.data.complexSceneResults; + } + layer_show(data.complexSceneName + '-测试结果 点击查看对应详情', templates["complex-scene-results-view"]({results:results}), 600, 300, 1, function(layero, index){ + layero.find('.result-view').bind('click', function(){ + renderResultViewPage(results[$(this).attr("data-id")]); + }); + }, function(index, layero) { + layero.find('.result-view').unbind('click'); + }, null) + } else { + layer.alert(strIsNotEmpty(json.msg) ? json.msg : '测试出错!', {icon:5}); + } + }); + layer.close(index); + }); + }, + ".show-scenes":function() { //管理组合中的测试场景 + var data = table.row( $(this).parents('tr') ).data(); + layer_show(data.complexSceneName + "-组合场景设定", "messageScene.html?complexSceneId=" + data.id, null, null, 2, null, null, function() { + refreshTable(); + }) + }, + ".choose-this-scene": function() { + var data = table.row( $(this).parents('tr') ).data(); + choosedCallBackFun(data); + parent.layer.close(parent.layer.getFrameIndex(window.name)); + } +}; + +var choosedCallBackFun; +var mySetting = { + eventList:eventList, + templateCallBack:function(df){ + choosedCallBackFun = parent[GetQueryString("callbackFun")]; + df.resolve(); + }, + listPage:{ + listUrl:REQUEST_URL.COMPLEX_SCENE.LIST, + tableObj:".table-sort", + columnsSetting:columnsSetting, + columnsJson:[0, 3, 6, 7], + dtOtherSetting:{ + "bStateSave": false + } + }, + templateParams:templateParams +}; + +$(function(){ + publish.renderParams = $.extend(true,publish.renderParams,mySetting); + publish.init(); +}); + +/**********************************************************************************************************************/ + + + + diff --git a/src/main/webapp/resource/message/message.js b/src/main/webapp/resource/message/message.js index 4b548966ec0e6d68acba22945d97ba4279f0219b..fa837bc1c7b2438d5ddb6dc64324f1f77c0ab2ae 100644 --- a/src/main/webapp/resource/message/message.js +++ b/src/main/webapp/resource/message/message.js @@ -138,6 +138,21 @@ var templateParams = { placeholder:"输入报文入参" }] }, + { + required:true, + reminder: "在HTTP/HTTPS协议的POST/DELETE/PUT等请求中,将Body体的参数转换成URL的查询参数,并将Body体置为空", + label:"Body转Query", + select:[{ + name:"bodyToQuery", + option:[{ + value:"0", + text:"否" + },{ + value:"1", + text:"是" + }] + }] + }, { label:"测试环境", required:true, diff --git a/src/main/webapp/resource/setting/variable.js b/src/main/webapp/resource/setting/variable.js index 6ea4d0f1e4f4d24ddbc569ebe8f0b5dc53ac2eac..e9d9cf6ff162c4297263455b7ed416d68be53cf1 100644 --- a/src/main/webapp/resource/setting/variable.js +++ b/src/main/webapp/resource/setting/variable.js @@ -149,6 +149,18 @@ var variableTypeInfo = { keyIsNull:false, ifCreate:true }, + dynamicComplexInterface:{ + text:"动态组合接口", + settingValue:{ + complexSceneId:"", + valueName:"", + complexSceneName:"" + }, + layerHeight:"320", + layerWidth: "700", + keyIsNull:false, + ifCreate:true + }, fileParameter: { text:"文件参数", settingValue:"", @@ -237,6 +249,7 @@ var templateParams = { {value:"randomString", text:variableTypeInfo.randomString.text}, {value:"uuid", text:variableTypeInfo.uuid.text}, {value:"dynamicInterface", text:variableTypeInfo.dynamicInterface.text}, + {value:"dynamicComplexInterface", text:variableTypeInfo.dynamicComplexInterface.text}, {value:"fileParameter", text:variableTypeInfo.fileParameter.text}, {value:"dbSql", text:variableTypeInfo.dbSql.text}] }] @@ -386,6 +399,10 @@ var columnsSetting = [ status:"动态接口", btnStyle:"danger" }, + dynamicComplexInterface:{ + status:"动态组合接口", + btnStyle:"danger" + }, fileParameter:{ status:"文件参数", btnStyle:"success" @@ -516,13 +533,17 @@ var eventList = { layer.alert('常量值:
' + data.value, {icon:1, anim:5, offset: '120px', title:data.variableName}); return; } + $(".page-container").spinModal(); $.post(REQUEST_URL.GLOBAL_VARIABLE.CREATE_VARIABLE, {variableId:data.variableId}, function(json) { + $(".page-container").spinModal(false); if (json.returnCode == 0) { layer.alert('
生成变量成功:
' + json.msg + '
' , {icon:1, anim:5, title:data.variableName, btn: ['强制刷新', '确定'], offset: '120px'} ,function(index, layero){ + $(".page-container").spinModal(); $.post(REQUEST_URL.GLOBAL_VARIABLE.CREATE_VARIABLE, {variableId:data.variableId, forceCreate:true}, function(json){ - if (json.returnCode == 0) { + $(".page-container").spinModal(false); + if (json.returnCode == 0) { $(layero).find('#create-result').html('生成变量成功:
' + json.msg); } else { layer.close(index); @@ -701,6 +722,7 @@ function changeFormByVariableType (variableType) { case "relatedKeyWord": case "setRuntimeSetting": case "dynamicInterface": + case "dynamicComplexInterface": showOrHideInput('hidden', 'button', 'hidden', null); break; case "dbSql": @@ -801,7 +823,12 @@ function showSettingPage(title) { } }); }); - + + // 选择组合场景 + $(layero).find('#choose-complex-scene').click(function(){ + layer_show("选择组合场景", "../message/chooseComplexScene.html?callbackFun=chooseComplexScene", null, null, 2); + }); + //选择测试场景 $(layero).find('#choose-scene').click(function(){ layer_show("选择测试场景", "../advanced/chooseMessageScene.html?callbackFun=chooseTestScene¬Multiple=true", null, null, 2); @@ -821,8 +848,8 @@ function showSettingPage(title) { $("#objectSeqText").text(n); } - //动态接口 - if (i == "systemName" || i == "sceneName") { + //动态接口 动态组合接口 + if (i == "systemName" || i == "sceneName" || i == "complexSceneName") { $("#" + i + "Text").text(n); } } @@ -848,6 +875,19 @@ function chooseTestScene (sceneObj) { $('.dynamicInterface #sceneNameText').text(sceneObj.interfaceName + '-' + sceneObj.messageName + '-' + sceneObj.sceneName); } +/** + * 选择组合场景之后的回调 + * @param complexScene + */ +function chooseComplexScene(complexScene){ + if (complexScene == null) { + return false; + } + $('.dynamicComplexInterface #complexSceneId').val(complexScene.id); + $('.dynamicComplexInterface #complexSceneName').val(complexScene.complexSceneName); + $('.dynamicComplexInterface #complexSceneNameText').text(complexScene.complexSceneName); +} + /** * uuid生成 * @returns diff --git a/src/main/webapp/resource/system/globalSetting.html b/src/main/webapp/resource/system/globalSetting.html index 2b5e2818b431077589a236734f08f3aee8e3eb96..f315150a5aebf39184d966a91f4c9a60f8d5730b 100644 --- a/src/main/webapp/resource/system/globalSetting.html +++ b/src/main/webapp/resource/system/globalSetting.html @@ -29,7 +29,7 @@
-
网站设置邮件设置阿里云短信接口配置接口自动化设置WEB自动化设置
+
网站设置邮件设置接口自动化设置
@@ -177,56 +177,56 @@ -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -237,6 +237,17 @@
+
+ +
+ + + +
+
@@ -247,26 +258,26 @@ -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
+ + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/webapp/resource/template/customTemplate.htm b/src/main/webapp/resource/template/customTemplate.htm index 12878dd0f56823faa2da8380819998abdf615801..5e7b020b381575b874908a028fbd012e50b14f71 100644 --- a/src/main/webapp/resource/template/customTemplate.htm +++ b/src/main/webapp/resource/template/customTemplate.htm @@ -147,7 +147,7 @@ {{/if}} {{#if textarea}} {{#each textarea}} - {{#if embellish}}{{{embellish}}}{{/if}} + {{#if embellish}}{{{embellish}}}{{/if}} {{/each}} {{/if}}
@@ -667,12 +667,12 @@
-
- -
- -
-
+ + + + + +
@@ -1120,6 +1120,29 @@
+ +
+
+ 选择一个组合场景,保存组合场景执行后的某一个上下文保存的变量名称到全局变量,供其他地方使用。 + 同动态接口一样,在有效期内不会重复调用接口获取。 +
+
+
+ +
+ + + + +
+
+
+ +
+ +
+
+
diff --git a/update.md b/update.md index 90982747aeafa1618a892b62b7644589a87fded8..d21d102022f18029d07156a188e912a0605a58ed 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,9 @@ +### v1.1.3 +#### 2021.02.04 +- 增加全局变量动态组合接口类型,通过组合场景去获取变量参数; +- 修复测试时获取不到用户的全局配置的问题; +- 报文增加BodyToQuery选项,方便在Post请求时管理Query参数; + ### v1.1.2 #### 2021.01.30 - 在组合场景中的替换变量配置中,支持使用全局变量、数据池变量、测试集公共变量(使用格式为:${__变量名})、上下文变量(使用格式为:${变量名})以及常量,且可以自由组合放在一起使用,使用时注意变量替换的优先级即可;