diff --git a/.classpath b/.classpath deleted file mode 100644 index 01edbc4..0000000 --- a/.classpath +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.project b/.project deleted file mode 100644 index 57f71f7..0000000 --- a/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - LuckyFrame - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/pom.xml b/pom.xml index e48dd96..e4b4d60 100644 --- a/pom.xml +++ b/pom.xml @@ -298,5 +298,12 @@ reflections 0.9.11 + + + + com.jayway.jsonpath + json-path + 2.4.0 + diff --git a/src/main/java/luckyclient/caserun/OneCaseExecute.java b/src/main/java/luckyclient/caserun/OneCaseExecute.java index c8532b4..b6ab191 100644 --- a/src/main/java/luckyclient/caserun/OneCaseExecute.java +++ b/src/main/java/luckyclient/caserun/OneCaseExecute.java @@ -21,11 +21,11 @@ import luckyclient.serverapi.entity.TaskScheduling; * 这是一个受限制的自由软件!您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途;也不允许对程序代码修改后以任何形式任何目的的再发布。 * 为了尊重作者的劳动成果,LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论。 QQ:1573584944 seagull1985 * ================================================================= - * + * * @author: seagull - * + * * @date 2017年12月1日 上午9:29:40 - * + * */ public class OneCaseExecute extends TestControl { @@ -57,7 +57,7 @@ public class OneCaseExecute extends TestControl { String.valueOf(task.getTaskId())); } - } + } }catch(Exception e){ LogUtil.APP.error("启动单个用例运行主函数出现异常,请检查!",e); } finally{ diff --git a/src/main/java/luckyclient/caserun/exinterface/TestCaseExecution.java b/src/main/java/luckyclient/caserun/exinterface/TestCaseExecution.java index 795b1f7..e678a7a 100644 --- a/src/main/java/luckyclient/caserun/exinterface/TestCaseExecution.java +++ b/src/main/java/luckyclient/caserun/exinterface/TestCaseExecution.java @@ -1,11 +1,17 @@ package luckyclient.caserun.exinterface; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.JsonPath; import org.openqa.selenium.WebDriver; import io.appium.java_client.android.AndroidDriver; @@ -44,8 +50,9 @@ public class TestCaseExecution { protected static final String FUZZY_MATCHING_SIGN = "%="; protected static final String REGULAR_MATCHING_SIGN = "~="; protected static final String ASSIGNMENT_GLOBALSIGN = "$A="; + protected static final String JSONPATH_SIGN = "$J="; private static Map VARIABLE = new HashMap(0); - + /** * @param projectname 项目名 * @param testCaseExternalId 用例编号 @@ -139,7 +146,7 @@ public class TestCaseExecution { LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),steps.get(i).getStepSerialNumber()); } } - + } catch (Exception e) { caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "调用方法过程出错,方法名:" + functionname + " 请重新检查脚本方法名称以及参数!", "error", String.valueOf(i + 1), ""); LogUtil.APP.error("调用方法过程出错,方法名:{} 请重新检查脚本方法名称以及参数!",functionname, e); @@ -154,7 +161,7 @@ public class TestCaseExecution { } } } - + VARIABLE.clear(); // 清空传参MAP // 如果调用方法过程中未出错,进入设置测试结果流程 if (!testnote.contains("CallCase调用出错!") && !testnote.contains("解析出错啦!")) { @@ -281,6 +288,26 @@ public class TestCaseExecution { break; // 某一步骤失败后,此条用例置为失败退出 } } + //jsonpath断言 + else if (expectedresults.length() > JSONPATH_SIGN.length() && expectedresults.startsWith(JSONPATH_SIGN)) { + expectedresults = expectedresults.substring(JSONPATH_SIGN.length()); + String jsonpath = expectedresults.split("=")[0]; + String exceptResult = expectedresults.split("=")[1]; + List exceptResults = Arrays.asList(exceptResult.split(",")); + Configuration conf = Configuration.defaultConfiguration(); + JSONArray datasArray = JSON.parseArray(JSON.toJSONString(JsonPath.using(conf).parse(testnote).read(jsonpath))); + List result = JSONObject.parseArray(datasArray.toJSONString(), String.class); + if (exceptResults.equals(result)) { + setresult = 0; + LogUtil.APP.info("用例:{} 第{}步,jsonpath断言预期结果成功!预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),(i+1),exceptResults,result); + } else { + setresult = 1; + LogUtil.APP.warn("用例:{} 第{}步,jsonpath断言预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(REGULAR_MATCHING_SIGN.length()),testnote); + testnote = "用例第" + (i + 1) + "步,jsonpath断言预期结果失败!"; + // 某一步骤失败后,此条用例置为失败退出 + break; + } + } // 完全相等 else { if (expectedresults.equals(testnote)) { @@ -311,7 +338,7 @@ public class TestCaseExecution { } /** - * + * * @param testCaseExternalId * @param taskid * @param caselog @@ -352,7 +379,7 @@ public class TestCaseExecution { params = AppDriverAnalyticCase.analyticCaseStep(testcase, step, taskid,caselog,VARIABLE); } else{ params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog,VARIABLE); - } + } // 判断分析步骤参数是否有异常 if (params.get("exception") != null && params.get("exception").contains("解析异常")) { @@ -361,7 +388,7 @@ public class TestCaseExecution { } expectedresults = params.get("ExpectedResults"); - + // 根据步骤类型来执行步骤 if (1 == step.getStepType()){ WebDriver wd=(WebDriver)driver; @@ -380,12 +407,12 @@ public class TestCaseExecution { // 判断结果 setresult = IosCaseExecution.judgeResult(testcase, step, params, ios, taskid, expectedresults, testnote, caselog); } - + } else{ testnote = runStep(params, taskid, testcase.getCaseSign(), step, caselog); // 判断结果 setresult = interfaceJudgeResult(testcase, step, taskid, expectedresults, testnote, caselog); - } + } if (0 != setresult){ break; @@ -400,7 +427,7 @@ public class TestCaseExecution { } return testnote; } - + /** * 其他类型测试用例中调用接口测试步骤 * @param params @@ -460,7 +487,7 @@ public class TestCaseExecution { } return result; } - + private static int interfaceJudgeResult(ProjectCase testcase, ProjectCaseSteps step, String taskid, String expectedresults, String testnote, LogOperation caselog){ int setresult = 0; try{ @@ -505,6 +532,26 @@ public class TestCaseExecution { testnote = "用例第" + step.getStepSerialNumber() + "步,正则匹配预期结果失败!"; } } + //jsonpath断言 + else if (expectedresults.length() > JSONPATH_SIGN.length() && expectedresults.startsWith(JSONPATH_SIGN)) { + expectedresults = expectedresults.substring(JSONPATH_SIGN.length()); + String jsonpath = expectedresults.split("=")[0]; + String exceptResult = expectedresults.split("=")[1]; + List exceptResults = Arrays.asList(exceptResult.split(",")); + Configuration conf = Configuration.defaultConfiguration(); + JSONArray datasArray = JSON.parseArray(JSON.toJSONString(JsonPath.using(conf).parse(testnote).read(jsonpath))); + List result = JSONObject.parseArray(datasArray.toJSONString(), String.class); + if (exceptResults.equals(result)) { + setresult = 0; + LogUtil.APP.info("用例:{} 第{}步,jsonpath断言预期结果成功!预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),step.getStepSerialNumber(),exceptResults,result); + } else { + setresult = 1; + LogUtil.APP.warn("用例:{} 第{}步,jsonpath断言预期结果失败!预期结果:{},测试结果:{}" + expectedresults + ",测试结果:" + result.toString(), "error", String.valueOf(step.getStepSerialNumber()), ""); + testnote = "用例第" + step.getStepSerialNumber() + "步,jsonpath断言预期结果失败!"; + // 某一步骤失败后,此条用例置为失败退出 + } + + } // 完全相等 else { if (expectedresults.equals(testnote)) { @@ -520,11 +567,11 @@ public class TestCaseExecution { } }catch(Exception e){ LogUtil.APP.error("匹配接口预期结果出现异常!",e); - setresult = 2; + setresult = 2; return setresult; } - return setresult; + return setresult; } - - + + } diff --git a/src/main/java/luckyclient/caserun/exinterface/ThreadForExecuteCase.java b/src/main/java/luckyclient/caserun/exinterface/ThreadForExecuteCase.java index a782f9d..5658571 100644 --- a/src/main/java/luckyclient/caserun/exinterface/ThreadForExecuteCase.java +++ b/src/main/java/luckyclient/caserun/exinterface/ThreadForExecuteCase.java @@ -1,11 +1,17 @@ package luckyclient.caserun.exinterface; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.JsonPath; import luckyclient.caserun.exinterface.analyticsteps.InterfaceAnalyticCase; import luckyclient.caserun.publicdispose.ActionManageForSteps; import luckyclient.caserun.publicdispose.ParamsManageForSteps; @@ -33,6 +39,7 @@ public class ThreadForExecuteCase extends Thread { private static final String ASSIGNMENT_GLOBALSIGN = "$A="; private static final String FUZZY_MATCHING_SIGN = "%="; private static final String REGULAR_MATCHING_SIGN = "~="; + private static final String JSONPATH_SIGN = "$J="; private Integer caseId; private String caseSign; @@ -77,8 +84,8 @@ public class ThreadForExecuteCase extends Thread { // 解析单个步骤中的脚本 Map casescript = InterfaceAnalyticCase.analyticCaseStep(testcase, steps.get(i), taskid, caselog,variable); try { - packagename = casescript.get("PackageName"); - functionname = casescript.get("FunctionName"); + packagename = casescript.get("PackageName"); + functionname = casescript.get("FunctionName"); } catch (Exception e) { k = 0; LogUtil.APP.error("用例:{} 解析包名或是方法名出现异常,请检查!",testcase.getCaseSign(),e); @@ -169,6 +176,35 @@ public class ThreadForExecuteCase extends Thread { } } } + //jsonpath断言 + else if (expectedresults.length() > JSONPATH_SIGN.length() && expectedresults.startsWith(JSONPATH_SIGN)) { + expectedresults = expectedresults.substring(JSONPATH_SIGN.length()); + String jsonpath = expectedresults.split("=")[0]; + String exceptResult = expectedresults.split("=")[1]; + List exceptResults = Arrays.asList(exceptResult.split(",")); + Configuration conf = Configuration.defaultConfiguration(); + JSONArray datasArray = JSON.parseArray(JSON.toJSONString(JsonPath.using(conf).parse(testnote).read(jsonpath))); + List result = JSONObject.parseArray(datasArray.toJSONString(), String.class); + if (exceptResults.equals(result)) { + setcaseresult = 0; + LogUtil.APP.info("用例【{}】 第【{}】步,jsonpath断言预期结果成功!预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),(i+1),exceptResults,result); + caselog.insertTaskCaseLog(taskid, caseId, "jsonpath断言预期结果成功!预期结果:"+ expectedresults + "测试结果:" + result + "执行结果:true","info", String.valueOf(i + 1), ""); + } else { + setcaseresult = 1; + LogUtil.APP.warn("用例:{} 第{}步,jsonpath断言预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults,result); + caselog.insertTaskCaseLog(taskid, caseId, "第" + (i + 1) + "步,正则匹配预期结果失败!预期结果:" + exceptResults + ",测试结果:" + result, "error", String.valueOf(i + 1), ""); + testnote = "用例第" + (i + 1) + "步,jsonpath断言预期结果失败!"; + if (testcase.getFailcontinue() == 0) { + LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1)); + break; + } else { + LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1)); + } + + // 某一步骤失败后,此条用例置为失败退出 + break; + } + } // 完全相等 else { if (expectedresults.equals(testnote)) { diff --git a/src/main/java/luckyclient/caserun/exinterface/WebTestCaseDebug.java b/src/main/java/luckyclient/caserun/exinterface/WebTestCaseDebug.java index 4428077..df22fa5 100644 --- a/src/main/java/luckyclient/caserun/exinterface/WebTestCaseDebug.java +++ b/src/main/java/luckyclient/caserun/exinterface/WebTestCaseDebug.java @@ -1,11 +1,17 @@ package luckyclient.caserun.exinterface; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.JsonPath; import luckyclient.caserun.exinterface.analyticsteps.InterfaceAnalyticCase; import luckyclient.caserun.publicdispose.ActionManageForSteps; import luckyclient.publicclass.InvokeMethod; @@ -32,7 +38,8 @@ public class WebTestCaseDebug { private static final String ASSIGNMENT_SIGN = "$="; private static final String FUZZY_MATCHING_SIGN = "%="; private static final String REGULAR_MATCHING_SIGN = "~="; - + protected static final String JSONPATH_SIGN = "$J="; + /** * @param executor * @param sign 用于在WEB页面上调试用例时提供的接口 @@ -139,6 +146,30 @@ public class WebTestCaseDebug { } } } + //jsonpath断言 + else if (expectedresults.length() > JSONPATH_SIGN.length() && expectedresults.startsWith(JSONPATH_SIGN)) { + expectedresults = expectedresults.substring(JSONPATH_SIGN.length()); + String jsonpath = expectedresults.split("=")[0]; + String exceptResult = expectedresults.split("=")[1]; + List exceptResults = Arrays.asList(exceptResult.split(",")); + Configuration conf = Configuration.defaultConfiguration(); + JSONArray datasArray = JSON.parseArray(JSON.toJSONString(JsonPath.using(conf).parse(testnote).read(jsonpath))); + List result = JSONObject.parseArray(datasArray.toJSONString(), String.class); + if (exceptResults.equals(result)) { + setcaseresult = 0; + PostServerAPI.cPostDebugLog(userId, caseId, "INFO", "jsonpath断言预期结果成功!预期结果:" + expectedresults + " 测试结果: " + result.toString() + "校验结果: true", 0); + } else { + setcaseresult = 1; + PostServerAPI.cPostDebugLog(userId, caseId, "ERROR", "第" + (i + 1) + "步,jsonpath断言预期结果失败!预期结果:" + expectedresults + ",测试结果:" + result.toString(),0); + testnote = "用例第" + (i + 1) + "步,jsonpath断言预期结果失败!"; + if (testcase.getFailcontinue() == 0) { + LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1)); + break; + } else { + LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1)); + } + } + } // 完全相等 else { if (expectedresults.equals(testnote)) { @@ -182,6 +213,6 @@ public class WebTestCaseDebug { } public static void main(String[] args) throws Exception { - + } }