!32 功能优化

Merge pull request !32 from testerMrli/master
This commit is contained in:
seagull 2022-01-29 06:48:44 +00:00 committed by Gitee
commit 6a5e631021
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
19 changed files with 971 additions and 37 deletions

View File

@ -327,6 +327,11 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies> </dependencies>
<!--排除版本管理警告--> <!--排除版本管理警告-->
<dependencyManagement> <dependencyManagement>

View File

@ -1,8 +1,8 @@
title Web界面用例调试【%1 title Web界面用例调试【%1
set classpath=%CLASSPATH%;.\luckyclient; set classpath=%CLASSPATH%;.\luckyclient;
@echo Web界面调试用例接口 @echo Web界面调试用例接口
@echo 参数说明 依次为:用例编号 执行者 @echo 参数说明 依次为:用例编号 执行者 用例类型
java -Djava.ext.dirs=./lib;.%3 luckyclient.execution.WebDebugExecute %1 %2 java -Djava.ext.dirs=./lib;.%4 luckyclient.execution.WebDebugExecute %1 %2 %3
@echo 当前用例调试窗口将在90秒后退出 @echo 当前用例调试窗口将在90秒后退出
ping 127.0.0.1 -n 90 >nul ping 127.0.0.1 -n 90 >nul
exit exit

View File

@ -1,9 +1,9 @@
#!/bin/sh #!/bin/sh
BASE_DIR="." BASE_DIR="."
LIB="${BASE_DIR}/lib" LIB="${BASE_DIR}/lib"
DRIVENPATH="${BASE_DIR}/$3" DRIVENPATH="${BASE_DIR}/$4"
JAVA_OPTS=" -Xmx2048m -XX:PermSize=64m -XX:MaxPermSize=512m -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=1024k -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/mtdperf.hprof -server -Dfile.encoding=UTF-8" JAVA_OPTS=" -Xmx2048m -XX:PermSize=64m -XX:MaxPermSize=512m -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=1024k -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/mtdperf.hprof -server -Dfile.encoding=UTF-8"
START_CLASS="luckyclient.execution.WebDebugExecute $1 $2" START_CLASS="luckyclient.execution.WebDebugExecute $1 $2 $3"
echo ${LIB} echo ${LIB}

View File

@ -0,0 +1,8 @@
title Web界面用例调试【%1
set classpath=%CLASSPATH%;.\luckyclient;
@echo Web界面调试用例接口
@echo 参数说明 依次为:用例编号 执行者 用例类型 web驱动类型
java -Djava.ext.dirs=./lib;.%4 luckyclient.execution.WebDebugExecuteWeb %1 %2 %3 %5
@echo 当前用例调试窗口将在90秒后退出
ping 127.0.0.1 -n 90 >nul
exit

View File

@ -1,10 +1,7 @@
package luckyclient.driven; package luckyclient.driven;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;

View File

@ -34,9 +34,9 @@ public class AppiumInitialization {
public static AndroidDriver<AndroidElement> setAndroidAppium(Properties properties) throws IOException { public static AndroidDriver<AndroidElement> setAndroidAppium(Properties properties) throws IOException {
AndroidDriver<AndroidElement> appium; AndroidDriver<AndroidElement> appium;
DesiredCapabilities capabilities = new DesiredCapabilities(); DesiredCapabilities capabilities = new DesiredCapabilities();
File directory = new File(""); // File directory = new File("");
File app = new File(directory.getCanonicalPath() + File.separator + properties.getProperty("appname")); // File app = new File(directory.getCanonicalPath() + File.separator + properties.getProperty("appname"));
capabilities.setCapability("app", app.getAbsolutePath()); // capabilities.setCapability("app", app.getAbsolutePath());
// 自动化测试服务 // 自动化测试服务
capabilities.setCapability("automationName", properties.getProperty("automationName")); capabilities.setCapability("automationName", properties.getProperty("automationName"));
// 设备名称 // 设备名称

View File

@ -315,6 +315,121 @@ public class TestCaseExecution {
return testnote; return testnote;
} }
//修改点
public String oneCaseExecuteForCase(String testCaseExternalId, Map<String, String> outVariable, Object driver) {
String expectedresults;
int setresult = 1;
int stepJumpNo=0;
String testnote = "初始化测试结果";
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
// if(null==caselog){
// // 初始化写用例结果以及日志模块
// caselog = new serverOperation();
// }
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
RUNCASE_VARIABLE.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
RUNCASE_VARIABLE.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 加入调用用例中的变量
RUNCASE_VARIABLE.putAll(outVariable);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
setresult = 2;
LogUtil.APP.warn("用例中未找到步骤,请检查!");
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "用例中未找到步骤,请检查!", "error", "1", "");
testnote = "用例中未找到步骤,请检查!";
}
// 进入循环解析用例所有步骤
for (int i = 0; i < steps.size(); i++) {
Map<String, String> params = null;
ProjectCaseSteps step = steps.get(i);
//处理步骤跳转语法
if(stepJumpNo!=0&&setresult!=0){
if(stepJumpNo==i+1){
LogUtil.APP.info("跳转至当前用例第{}步",i+1);
}else if(stepJumpNo>i+1){
LogUtil.APP.info("当前用例第{}步,跳过执行...",i+1);
continue;
}else{
LogUtil.APP.info("跳转步骤【{}】小于当前步骤【{}】,直接向下继续执行...",stepJumpNo,i+1);
}
}
// 根据步骤类型来分析步骤参数
if (1 == step.getStepType()){
params = WebDriverAnalyticCase.analyticCaseStep(testcase, step, RUNCASE_VARIABLE);
}else if (3 == step.getStepType()){
// params = AppDriverAnalyticCase.analyticCaseStep(testcase, step, taskid,caselog,RUNCASE_VARIABLE);
} else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step,RUNCASE_VARIABLE);
}
// 判断分析步骤参数是否有异常
if (params.get("exception") != null && params.get("exception").contains("解析异常")) {
setresult = 2;
break;
}
expectedresults = params.get("ExpectedResults");
Map<String,Integer> judgeResult=new HashMap<>();
// 根据步骤类型来执行步骤
if (1 == step.getStepType()){
WebDriver wd=(WebDriver)driver;
testnote = WebCaseExecution.runWebStep(params, wd, testcase.getCaseId(), step.getStepSerialNumber());
testnote = ActionManageForSteps.actionManage(params.get("Action"), testnote);
// 判断结果
judgeResult = WebCaseExecution.judgeResult(testcase, step, params, wd, expectedresults, testnote);//修改点
setresult = judgeResult.get("setResult");
stepJumpNo = judgeResult.get("stepJumpNo");
}else if (3 == step.getStepType()){
// if (driver instanceof AndroidDriver){
// AndroidDriver<AndroidElement> ad=(AndroidDriver<AndroidElement>)driver;
// testnote = AndroidCaseExecution.androidRunStep(params, ad, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
// testnote = ActionManageForSteps.actionManage(params.get("Action"), testnote);
// // 判断结果
// judgeResult = AndroidCaseExecution.judgeResult(testcase, step, params, ad, taskid, expectedresults, testnote, caselog);
// setresult = judgeResult.get("setResult");
// stepJumpNo = judgeResult.get("stepJumpNo");
// }else{
// IOSDriver<IOSElement> ios=(IOSDriver<IOSElement>)driver;
// testnote = IosCaseExecution.iosRunStep(params, RUNCASE_VARIABLE, ios, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
// testnote = ActionManageForSteps.actionManage(params.get("Action"), testnote);
// // 判断结果
// judgeResult = IosCaseExecution.judgeResult(testcase, step, params, ios, taskid, expectedresults, testnote, caselog);
// setresult = judgeResult.get("setResult");
// stepJumpNo = judgeResult.get("stepJumpNo");
// }
} else{
testnote = runStep(params, testcase.getCaseSign(), step);
testnote = ActionManageForSteps.actionManage(params.get("Action"), testnote);
// 判断结果
judgeResult = interfaceJudgeResult(testcase, step, expectedresults, testnote);
setresult = judgeResult.get("setResult");
stepJumpNo = judgeResult.get("stepJumpNo");
}
if (0 != setresult){
testnote = "【调用用例:"+testcase.getCaseSign()+""+step.getStepSerialNumber()+"步在执行过程中失败】";
LogUtil.APP.warn("调用用例:{} 第{}步在执行过程中失败,请检查日志!{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
break;
}
}
//屏蔽参数清空放到步骤执行的方法中去清空
// RUNCASE_VARIABLE.clear();
if (0 == setresult) {
LogUtil.APP.info("调用用例:{}步骤全部执行成功!",testcase.getCaseSign());
}
return testnote;
}
/** /**
* 其他类型测试用例中调用接口测试步骤 * 其他类型测试用例中调用接口测试步骤
* @param params 参数 * @param params 参数
@ -379,6 +494,62 @@ public class TestCaseExecution {
return result; return result;
} }
//修改点
public String runStep(Map<String, String> params, String casenum, ProjectCaseSteps step) {
String result;
String packagename;
String functionname = "";
Object[] getParameterValues;
ProjectCase projectCase = GetServerApi.cgetCaseBysign(casenum);
try {
packagename = params.get("PackageName");
functionname = params.get("FunctionName");
if (null != functionname && functionname.contains("解析异常")) {
LogUtil.APP.warn("用例:{}, 解析这个方法【{}】失败!",casenum,functionname);
// caselog.insertTaskCaseLog(taskid, projectCase.getCaseId(), "用例: " + casenum + ", 解析这个方法【" + functionname + "】失败!", "error", String.valueOf(step.getStepSerialNumber()), "");
result = "步骤执行失败:解析用例失败!";
} else {
// 判断方法是否带参数
if (params.size() > 4) {
// 获取传入参数放入对象中
getParameterValues = new Object[params.size() - 4];
for (int j = 0; j < params.size() - 4; j++) {
if (params.get("FunctionParams" + (j + 1)) == null) {
break;
}
String parameterValues = params.get("FunctionParams" + (j + 1));
LogUtil.APP.info("用例:{}, 解析包路径:{}; 方法名:{} 第{}个参数:{}",casenum,packagename,functionname,(j+1),parameterValues);
// caselog.insertTaskCaseLog(taskid, projectCase.getCaseId(), "用例: " + casenum + ", 解析包名:" + packagename + " 方法名:" + functionname + "" + (j + 1) + "个参数:" + parameterValues, "info", String.valueOf(step.getStepSerialNumber()), "");
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
LogUtil.APP.info("二次解析用例过程完成,等待进行接口操作......");
// caselog.insertTaskCaseLog(taskid, projectCase.getCaseId(), "包路径: " + packagename + "; 方法名: " + functionname, "info", String.valueOf(step.getStepSerialNumber()), "");
// 接口用例支持使用runcase关键字
if ((null != functionname && "runcase".equals(functionname))) {
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.oneCaseExecuteForCase(getParameterValues[0].toString(), RUNCASE_VARIABLE, null);
}else{
result = InvokeMethod.callCase(packagename, functionname, getParameterValues, step.getStepType(), step.getExtend());
}
}
} catch (Exception e) {
LogUtil.APP.error("调用方法过程出错,方法名:{},请重新检查脚本方法名称以及参数!",functionname,e);
result = "步骤执行失败:接口调用出错!";
}
if (result.contains("步骤执行失败:")){
// caselog.insertTaskCaseLog(taskid, projectCase.getCaseId(), result, "error", String.valueOf(step.getStepSerialNumber()), "");
} else{
// caselog.insertTaskCaseLog(taskid, projectCase.getCaseId(), result, "info", String.valueOf(step.getStepSerialNumber()), "");
}
return result;
}
private Map<String,Integer> interfaceJudgeResult(ProjectCase testcase, ProjectCaseSteps step, String taskid, String expectedresults, String testnote, serverOperation caselog){ private Map<String,Integer> interfaceJudgeResult(ProjectCase testcase, ProjectCaseSteps step, String taskid, String expectedresults, String testnote, serverOperation caselog){
Map<String,Integer> judgeResult=new HashMap<>(); Map<String,Integer> judgeResult=new HashMap<>();
judgeResult.put("setResult",0); judgeResult.put("setResult",0);
@ -482,5 +653,108 @@ public class TestCaseExecution {
return judgeResult; return judgeResult;
} }
//修改点
private Map<String,Integer> interfaceJudgeResult(ProjectCase testcase, ProjectCaseSteps step, String expectedresults, String testnote){
Map<String,Integer> judgeResult=new HashMap<>();
judgeResult.put("setResult",0);
judgeResult.put("stepJumpNo",0);
try{
if (null != expectedresults && !expectedresults.isEmpty()) {
//处理步骤跳转
if (expectedresults.length() > Constants.IFFAIL_JUMP.length() && expectedresults.startsWith(Constants.IFFAIL_JUMP)) {
LogUtil.APP.info("预期结果中存在判断条件跳转步骤,处理前原始字符串:{}",expectedresults);
String expectedTemp = expectedresults.substring(Constants.IFFAIL_JUMP.length());
if(expectedTemp.contains(Constants.SYMLINK)){
expectedresults = expectedTemp.substring(expectedTemp.indexOf(Constants.SYMLINK)+2);
try{
Integer stepJumpNo = Integer.parseInt(expectedTemp.substring(0,expectedTemp.indexOf(Constants.SYMLINK)));
judgeResult.put("stepJumpNo",stepJumpNo);
}catch (NumberFormatException nfe){
LogUtil.APP.error("步骤跳转语法解析失败,步骤编号不是数字,请确认:{}",expectedTemp.substring(0,expectedTemp.indexOf(Constants.SYMLINK)));
}
}else{
LogUtil.APP.warn("处理预期结果条件判断失败,请确认预期结果语法结构:【"+Constants.IFFAIL_JUMP+">>预期结果】,原始预期结果值:{}",expectedresults);
}
}
LogUtil.APP.info("expectedResults=【{}】",expectedresults);
// 赋值传参
if (expectedresults.length() > Constants.ASSIGNMENT_SIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_SIGN)) {
RUNCASE_VARIABLE.put(expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()), testnote);
LogUtil.APP.info("用例:{} 第{}步,将测试结果【{}】赋值给变量【{}】",testcase.getCaseSign(),step.getStepSerialNumber(),testnote,expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()));
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "将测试结果【" + testnote + "】赋值给变量【" + expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()) + "", "info", String.valueOf(step.getStepSerialNumber()), "");
}
// 赋值全局变量
else if (expectedresults.length() > Constants.ASSIGNMENT_GLOBALSIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_GLOBALSIGN)) {
RUNCASE_VARIABLE.put(expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()), testnote);
ParamsManageForSteps.GLOBAL_VARIABLE.put(expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()), testnote);
LogUtil.APP.info("用例:{} 第{}步,将测试结果【{}】赋值给全局变量【{}】",testcase.getCaseSign(),step.getStepSerialNumber(),testnote,expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()));
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "将测试结果【" + testnote + "】赋值给全局变量【" + expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()) + "", "info", String.valueOf(step.getStepSerialNumber()), "");
}
// 模糊匹配
else if (expectedresults.length() > Constants.FUZZY_MATCHING_SIGN.length() && expectedresults.startsWith(Constants.FUZZY_MATCHING_SIGN)) {
if (testnote.contains(expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()))) {
LogUtil.APP.info("用例:{} 第{}步,模糊匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "模糊匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
judgeResult.put("setResult",1);
LogUtil.APP.warn("用例:{} 第{}步,模糊匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()),testnote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "模糊匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()) + ",测试结果:" + testnote, "error", String.valueOf(step.getStepSerialNumber()), "");
}
}
// 正则匹配
else if (expectedresults.length() > Constants.REGULAR_MATCHING_SIGN.length() && expectedresults.startsWith(Constants.REGULAR_MATCHING_SIGN)) {
Pattern pattern = Pattern.compile(expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()));
Matcher matcher = pattern.matcher(testnote);
if (matcher.find()) {
LogUtil.APP.info("用例:{} 第{}步,正则匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "正则匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
judgeResult.put("setResult",1);
LogUtil.APP.warn("用例:{} 第{}步,正则匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()),testnote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "正则匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()) + ",测试结果:" + testnote, "error", String.valueOf(step.getStepSerialNumber()), "");
}
}
//jsonpath断言
else if (expectedresults.length() > Constants.JSONPATH_SIGN.length() && expectedresults.startsWith(Constants.JSONPATH_SIGN)) {
expectedresults = expectedresults.substring(Constants.JSONPATH_SIGN.length());
String expression = expectedresults.split("(?<!\\\\)=")[0].replace("\\=","=");
String exceptResult = expectedresults.split("(?<!\\\\)=")[1].replace("\\=","=");
//对测试结果进行jsonPath取值
String result = SubString.jsonPathGetParams(expression, testnote);
if (exceptResult.equals(result)) {
judgeResult.put("setResult",0);
LogUtil.APP.info("用例:{} 第{}步jsonpath断言预期结果成功预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),step.getStepSerialNumber(),exceptResult,result);
} else {
judgeResult.put("setResult",1);
LogUtil.APP.warn("用例:{} 第{}步jsonpath断言预期结果失败预期结果:{},测试结果:{}" + expectedresults + ",测试结果:" + result, "error", step.getStepSerialNumber(), "");
// 某一步骤失败后此条用例置为失败退出
}
}
// 完全相等
else {
if (expectedresults.equals(testnote)) {
LogUtil.APP.info("用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(step.getStepSerialNumber()), "");
} else if(expectedresults.trim().equals("NULL")&& StringUtils.isBlank(testnote)){
testnote = "返回结果为空匹配NULL成功";
LogUtil.APP.info("用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
judgeResult.put("setResult",1);
LogUtil.APP.warn("用例:{} 第{}步,精确匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),expectedresults,testnote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果失败!预期结果:" + expectedresults + ",测试结果:" + testnote, "error", String.valueOf(step.getStepSerialNumber()), "");
}
}
}
}catch(Exception e){
LogUtil.APP.error("匹配接口预期结果出现异常!",e);
judgeResult.put("setResult",2);
return judgeResult;
}
return judgeResult;
}
} }

View File

@ -10,6 +10,7 @@ import luckyclient.driven.SubString;
import luckyclient.execution.dispose.ActionManageForSteps; import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps; import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase; import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.execution.webdriver.ex.WebOneCaseExecute;
import luckyclient.remote.api.GetServerApi; import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.PostServerApi; import luckyclient.remote.api.PostServerApi;
import luckyclient.remote.api.serverOperation; import luckyclient.remote.api.serverOperation;
@ -38,8 +39,11 @@ public class WebTestCaseDebug {
* 用于在WEB页面上调试用例时提供的接口 * 用于在WEB页面上调试用例时提供的接口
* @param caseIdStr 用例ID * @param caseIdStr 用例ID
* @param userIdStr 用户ID * @param userIdStr 用户ID
* @param caseTypeStr 用例类型针对0或者2
*/ */
public static void oneCaseDebug(String caseIdStr, String userIdStr) { public static void oneCaseDebug(String caseIdStr, String userIdStr,String caseTypeStr) {
//修改点
if (Integer.parseInt(caseTypeStr)==0||Integer.parseInt(caseTypeStr)==2){
Map<String, String> variable = new HashMap<>(0); Map<String, String> variable = new HashMap<>(0);
serverOperation.exetype=1; serverOperation.exetype=1;
String packagename; String packagename;
@ -257,5 +261,19 @@ public class WebTestCaseDebug {
PostServerApi.cPostDebugLog(userId, caseId, "ERRORover", "用例 " + sign + "在执行过程中失败,请检查!",1); PostServerApi.cPostDebugLog(userId, caseId, "ERRORover", "用例 " + sign + "在执行过程中失败,请检查!",1);
} }
} }
}
//修改点
/**
* 用于在WEB页面上调试用例时提供的接口
* @param caseIdStr 用例ID
* @param userIdStr 用户ID
* @param caseTypeStr 用例类型针对1
* @param browserTypeStr web驱动0 IE 1 火狐 2 谷歌 3 Edge
*/
public static void oneCaseDebug(String caseIdStr, String userIdStr,String caseTypeStr,String browserTypeStr) {
int caseId=Integer.parseInt(caseIdStr);
int browserType=Integer.parseInt(browserTypeStr);
WebOneCaseExecute.debugoneCaseExecute(caseId, browserType);
}
} }

View File

@ -79,7 +79,56 @@ public class InterfaceAnalyticCase{
return params; return params;
} }
public static Map<String,String> analyticCaseStep(ProjectCase projectcase,ProjectCaseSteps step, Map<String, String> variable){
Map<String,String> params = new HashMap<>(0);
try {
String resultstr = step.getExpectedResult();
params.put("Action", step.getAction());
// 处理值传递
String packageName = ChangString.changparams(step.getStepPath(), variable, "包路径");
params.put("PackageName", packageName);
// 处理值传递
String functionName = ChangString.changparams(step.getStepOperation(), variable, "方法名");
params.put("FunctionName", functionName);
String stepParams = replaceSpi(step.getStepParameters(),0);
String[] temp=stepParams.split("\\|",-1);
for(int i=0;i<temp.length;i++){
if("".equals(temp[i])){
continue;
}if(" ".equals(temp[i])){
//带一个空格的时候传入空字符串
params.put("FunctionParams"+(i+1), "");
}else{
//set第N个传入参数
String parameterValues = ChangString.changparams(replaceSpi(temp[i],1), variable, "用例参数");
params.put("FunctionParams"+(i+1), parameterValues);
}
}
//set预期结果
if(null==resultstr||"".equals(resultstr)){
params.put("ExpectedResults", "");
}else{
String expectedResults = ChangString.changparams(subComment(resultstr), variable, "预期结果");
params.put("ExpectedResults", expectedResults);
}
LogUtil.APP.info("用例编号:{} 步骤编号:{} 解析自动化用例步骤脚本完成!",projectcase.getCaseSign(),step.getStepSerialNumber());
// if(null!=caselog){
// caselog.insertTaskCaseLog(taskid, projectcase.getCaseId(),"步骤编号:"+step.getStepSerialNumber()+" 解析自动化用例步骤脚本完成!","info",String.valueOf(step.getStepSerialNumber()),"");
// }
}catch(Exception e) {
// if(null!=caselog){
// caselog.insertTaskCaseLog(taskid, projectcase.getCaseId(),"步骤编号:"+step.getStepSerialNumber()+" 解析自动化用例步骤脚本出错!","error",String.valueOf(step.getStepSerialNumber()),"");
// }
LogUtil.APP.error("用例编号:{} 步骤编号:{} 解析自动化用例步骤脚本出错!",projectcase.getCaseSign(),step.getStepSerialNumber(),e);
params.put("exception","用例编号:"+projectcase.getCaseSign()+"|解析异常,用例步骤为空或是用例脚本错误!");
return params;
}
return params;
}
public static String subComment(String htmlStr) { public static String subComment(String htmlStr) {
// 定义script的正则表达式 // 定义script的正则表达式
String regExscript = "<script[^>]*?>[\\s\\S]*?</script>"; String regExscript = "<script[^>]*?>[\\s\\S]*?</script>";

View File

@ -7,15 +7,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.Alert; import org.openqa.selenium.*;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.Point;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.FluentWait;
@ -372,6 +364,12 @@ public class EncapsulateOperation {
case "gotowindow": case "gotowindow":
result = switchToTargetWindow(wd, operationValue); result = switchToTargetWindow(wd, operationValue);
break; break;
case "switchtowindow":
switchToWindow(wd);
break;
case "windowsetsize":
manageWindowSetSize(wd,operationValue);
break;
case "closewindow": case "closewindow":
wd.close(); wd.close();
result = "¹Ø±Õµ±Ç°ä¯ÀÀÆ÷´°¿Ú..."; result = "¹Ø±Õµ±Ç°ä¯ÀÀÆ÷´°¿Ú...";
@ -606,6 +604,34 @@ public class EncapsulateOperation {
return result; return result;
} }
} }
//新增修改点 切换句柄
private static void switchToWindow(WebDriver driver) {
String current_window_handle=driver.getWindowHandle();
LogUtil.APP.info("当前句柄:"+current_window_handle);
driver.close();
LogUtil.APP.info("关闭当前句柄:"+current_window_handle);
for (String s : driver.getWindowHandles()) {
if (!s.equals(current_window_handle)) {
driver.switchTo().window(s);
}
}
}
//新增修改点 设置浏览器窗口大小
private static void manageWindowSetSize(WebDriver driver,String operationValue) {
if(operationValue.contains(",")){
String[] index=operationValue.split(",");
if (index.length==2){
driver.manage().window().setSize(new Dimension(Integer.parseInt(index[0].trim()), Integer.parseInt(index[1].trim())));
}else {
LogUtil.APP.info("参数格式不正确参数格式为xxx,xxx");
}
}else {
LogUtil.APP.info("参数格式不正确参数格式为xxx,xxx");
}
}
} }

View File

@ -119,6 +119,86 @@ public class WebCaseExecution{
} }
} }
//修改点
public static void caseExcution(ProjectCase testcase, List<ProjectCaseSteps> steps, WebDriver wd, List<ProjectCaseParams> pcplist) {
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 0:成功 1:失败 2:锁定 其他锁定
int setcaseresult = 0;
//步骤跳转标识
int stepJumpNo=0;
for (int i = 0; i < steps.size(); i++) {
Map<String, String> params;
String result;
ProjectCaseSteps step = steps.get(i);
//处理步骤跳转语法
if(stepJumpNo!=0&&setcaseresult!=0){
if(stepJumpNo==i+1){
setcaseresult = 0;
LogUtil.APP.info("跳转至当前用例第{}步",i+1);
}else if(stepJumpNo>i+1){
LogUtil.APP.info("当前用例第{}步,跳过执行...",i+1);
continue;
}else{
LogUtil.APP.info("跳转步骤【{}】小于当前步骤【{}】,直接向下继续执行...",stepJumpNo,i+1);
}
}
// 根据步骤类型来分析步骤参数
if (1 == step.getStepType()){
params = WebDriverAnalyticCase.analyticCaseStep(testcase, step, variable);
}else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, variable);
}
// 判断分析步骤参数是否有异常
if (null != params.get("exception") && params.get("exception").contains("解析异常")) {
setcaseresult = 2;
break;
}
// 根据步骤类型来执行步骤
if (1 == step.getStepType()){
result = runWebStep(params, wd, testcase.getCaseId(), step.getStepSerialNumber());
}else{
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.runStep(params, testcase.getCaseSign(), step);
}
String expectedResults = params.get("ExpectedResults");
// 判断结果
Map<String,Integer> judgeResult = judgeResult(testcase, step, params, wd, expectedResults, result);
Integer stepresult = judgeResult.get("setResult");
stepJumpNo = judgeResult.get("stepJumpNo");
// 失败并且不在继续,直接终止
if (0 != stepresult) {
setcaseresult = stepresult;
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),step.getStepSerialNumber());
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),step.getStepSerialNumber());
}
}
}
variable.clear();
// caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), setcaseresult);
if (setcaseresult == 0) {
LogUtil.APP.info("用例【{}】全部步骤执行结果成功...",testcase.getCaseSign());
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "用例全部步骤执行结果成功", "info", "ending", "");
} else {
LogUtil.APP.warn("用例【{}】步骤执行过程中失败或是锁定...请查看具体原因:{}",testcase.getCaseSign(),casenote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "用例执行过程中失败或是锁定" + casenote, "error", "ending", "");
}
}
public static String runWebStep(Map<String, String> params, WebDriver wd, String taskid, Integer caseId, int stepno, serverOperation caselog) { public static String runWebStep(Map<String, String> params, WebDriver wd, String taskid, Integer caseId, int stepno, serverOperation caselog) {
String result; String result;
String property; String property;
@ -157,8 +237,12 @@ public class WebCaseExecution{
// 页面元素层 // 页面元素层
if (null != property && null != propertyValue && null != operation) { if (null != property && null != propertyValue && null != operation) {
WebElement we = isElementExist(wd, property, propertyValue); WebElement we;
if (!property.equals("classnames")){
we = isElementExist(wd, property, propertyValue);
}else{
we = isElementExist(wd, property, propertyValue,operationValue);
}
//判断元素是否存在关键字 //判断元素是否存在关键字
if(operation.equals("iselementexist")){ if(operation.equals("iselementexist")){
// 判断此元素是否存在 // 判断此元素是否存在
@ -221,6 +305,113 @@ public class WebCaseExecution{
} }
//修改点
public static String runWebStep(Map<String, String> params, WebDriver wd, Integer caseId, int stepno) {
String result;
String property;
String propertyValue;
String operation;
String operationValue;
try {
property = params.get("property");
propertyValue = params.get("property_value");
operation = params.get("operation");
operationValue = params.get("operation_value");
LogUtil.APP.info("二次解析用例过程完成,等待进行对象操作......");
// caselog.insertTaskCaseLog(taskid, caseId, "对象操作:" + operation + "; 操作值:" + operationValue, "info", String.valueOf(stepno), "");
} catch (Exception e) {
LogUtil.APP.error("二次解析用例过程抛出异常!",e);
return "步骤执行失败:解析用例失败!";
}
try {
//调用另一条用例支持接口web类型用例
if (null != operationValue && "runcase".equals(operation)) {
String[] temp = operationValue.split(",", -1);
TestCaseExecution testCaseExecution=new TestCaseExecution();
String ex = testCaseExecution.oneCaseExecuteForCase(temp[0], variable, wd);
if (!ex.contains("CallCase调用出错") && !ex.contains("解析出错啦!") && !ex.contains("失败")) {
// 加入runcase中的变量
variable.putAll(testCaseExecution.RUNCASE_VARIABLE);
testCaseExecution.RUNCASE_VARIABLE.clear();
return ex;
} else {
return "步骤执行失败:"+ex;
}
}
// 页面元素层
if (null != property && null != propertyValue && null != operation) {
WebElement we;
if (!property.equals("classnames")){
we = isElementExist(wd, property, propertyValue);
}else{
we = isElementExist(wd, property, propertyValue,operationValue);
}
//判断元素是否存在关键字
if(operation.equals("iselementexist")){
// 判断此元素是否存在
if (null == we) {
LogUtil.APP.warn("获取到的值是【false】");
return "获取到的值是【false】";
}else{
LogUtil.APP.info("获取到的值是【true】");
return "获取到的值是【true】";
}
}
// 判断此元素是否存在
if (null == we) {
LogUtil.APP.warn("定位对象失败isElementExist为null!");
return "步骤执行失败:定位的元素不存在!";
}
//点亮即将操作的元素
BaseWebDrive.highLightElement(wd, we);
if (operation.contains("select")) {
result = EncapsulateOperation.selectOperation(we, operation, operationValue);
} else if (operation.contains("get")) {
result = EncapsulateOperation.getOperation(wd, we, operation, operationValue);
} else if (operation.contains("mouse")) {
result = EncapsulateOperation.actionWeOperation(wd, we, operation, operationValue, property, propertyValue);
} else {
result = EncapsulateOperation.objectOperation(wd, we, operation, operationValue, property, propertyValue);
}
// Driver层操作
} else if (null == property && null != operation) {
// 处理弹出框事件
if (operation.contains("alert")) {
result = EncapsulateOperation.alertOperation(wd, operation);
} else if (operation.contains("mouse")) {
result = EncapsulateOperation.actionOperation(wd, operation, operationValue);
} else {
result = EncapsulateOperation.driverOperation(wd, operation, operationValue);
}
} else {
LogUtil.APP.warn("元素操作过程失败!");
result = "步骤执行失败:元素操作过程失败!";
}
} catch (Exception e) {
LogUtil.APP.error("元素定位过程或是操作过程失败或异常!",e);
return "步骤执行失败:元素定位过程或是操作过程失败或异常!" + e.getMessage();
}
if (result.contains("步骤执行失败:")){
// caselog.insertTaskCaseLog(taskid, caseId, result, "error", String.valueOf(stepno), "");
} else{
// caselog.insertTaskCaseLog(taskid, caseId, result, "info", String.valueOf(stepno), "");
}
if (result.contains("获取到的值是【") && result.contains("")) {
result = result.substring(result.indexOf("获取到的值是【") + "获取到的值是【".length(), result.length() - 1);
}
return result;
}
private static WebElement isElementExist(WebDriver wd, String property, String propertyValue) { private static WebElement isElementExist(WebDriver wd, String property, String propertyValue) {
try { try {
WebElement we = null; WebElement we = null;
@ -230,6 +421,10 @@ public class WebCaseExecution{
case "id": case "id":
we = wd.findElement(By.id(propertyValue)); we = wd.findElement(By.id(propertyValue));
break; break;
//增加className
case "classname":
we = wd.findElement(By.className(propertyValue));
break;
case "name": case "name":
we = wd.findElement(By.name(propertyValue)); we = wd.findElement(By.name(propertyValue));
break; break;
@ -258,6 +453,26 @@ public class WebCaseExecution{
} }
//修改点
private static WebElement isElementExist(WebDriver wd, String property, String propertyValue,String operationValue) {
try {
int index = Integer.parseInt(operationValue);
WebElement we = null;
property = property.toLowerCase();
// 处理WebElement对象定位
//增加className[]
if ("classnames".equals(property)) {
we = wd.findElements(By.className(propertyValue)).get(index);
}
return we;
} catch (Exception e) {
LogUtil.APP.error("当前对象定位失败!",e);
return null;
}
}
public static Map<String,Integer> judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, WebDriver driver, String taskid, String expect, String result, serverOperation caselog) { public static Map<String,Integer> judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, WebDriver driver, String taskid, String expect, String result, serverOperation caselog) {
Map<String,Integer> judgeResult=new HashMap<>(); Map<String,Integer> judgeResult=new HashMap<>();
judgeResult.put("setResult",0); judgeResult.put("setResult",0);
@ -373,7 +588,127 @@ public class WebCaseExecution{
LogUtil.APP.warn("用例:{} 第{}步,执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),casenote); LogUtil.APP.warn("用例:{} 第{}步,执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),casenote);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "当前步骤在执行过程中解析|定位元素|操作对象失败!" + casenote, "error", String.valueOf(step.getStepSerialNumber()), imagname); caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "当前步骤在执行过程中解析|定位元素|操作对象失败!" + casenote, "error", String.valueOf(step.getStepSerialNumber()), imagname);
} }
return judgeResult;
}
//修改点
public static Map<String,Integer> judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, WebDriver driver, String expect, String result) {
Map<String,Integer> judgeResult=new HashMap<>();
judgeResult.put("setResult",0);
judgeResult.put("stepJumpNo",0);
java.text.DateFormat timeformat = new java.text.SimpleDateFormat("MMdd-hhmmss");
String imagname = timeformat.format(new Date());
result = ActionManageForSteps.actionManage(step.getAction(), result);
if (null != result && !result.contains("步骤执行失败:")) {
// 有预期结果
if (null != expect && !expect.isEmpty()) {
//处理步骤跳转
if (expect.length() > Constants.IFFAIL_JUMP.length() && expect.startsWith(Constants.IFFAIL_JUMP)) {
LogUtil.APP.info("预期结果中存在判断条件跳转步骤,处理前原始字符串:{}",expect);
String expectedTemp = expect.substring(Constants.IFFAIL_JUMP.length());
if(expectedTemp.contains(Constants.SYMLINK)){
expect = expectedTemp.substring(expectedTemp.indexOf(Constants.SYMLINK)+2);
try{
Integer stepJumpNo = Integer.parseInt(expectedTemp.substring(0,expectedTemp.indexOf(Constants.SYMLINK)));
judgeResult.put("stepJumpNo",stepJumpNo);
}catch (NumberFormatException nfe){
LogUtil.APP.error("步骤跳转语法解析失败,步骤编号不是数字,请确认:{}",expectedTemp.substring(0,expectedTemp.indexOf(Constants.SYMLINK)));
}
}else{
LogUtil.APP.warn("处理预期结果条件判断失败,请确认预期结果语法结构:【"+Constants.IFFAIL_JUMP+">>预期结果】,原始预期结果值:{}",expect);
}
}
LogUtil.APP.info("期望结果为【{}】",expect);
// 赋值传参模式
if (expect.length() > Constants.ASSIGNMENT_SIGN.length() && expect.startsWith(Constants.ASSIGNMENT_SIGN)) {
variable.put(expect.substring(Constants.ASSIGNMENT_SIGN.length()), result);
LogUtil.APP.info("用例:{} 第{}步,将测试结果【{}】赋值给变量【{}】",testcase.getCaseSign(),step.getStepSerialNumber(),result,expect.substring(Constants.ASSIGNMENT_SIGN.length()));
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "将测试结果【" + result + "】赋值给变量【" + expect.substring(Constants.ASSIGNMENT_SIGN.length()) + "", "info", String.valueOf(step.getStepSerialNumber()), "");
}
// 赋值全局变量
else if (expect.length() > Constants.ASSIGNMENT_GLOBALSIGN.length() && expect.startsWith(Constants.ASSIGNMENT_GLOBALSIGN)) {
variable.put(expect.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()), result);
ParamsManageForSteps.GLOBAL_VARIABLE.put(expect.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()), result);
LogUtil.APP.info("用例:{} 第{}步,将测试结果【{}】赋值给全局变量【{}】",testcase.getCaseSign(),step.getStepSerialNumber(),result,expect.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()));
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "将测试结果【" + result + "】赋值给全局变量【" + expect.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()) + "", "info", String.valueOf(step.getStepSerialNumber()), "");
}
// WebUI检查模式
else if (1 == step.getStepType() && params.get("checkproperty") != null && params.get("checkproperty_value") != null) {
String checkproperty = params.get("checkproperty");
String checkPropertyValue = params.get("checkproperty_value");
WebElement we = isElementExist(driver, checkproperty, checkPropertyValue);
if (null != we) {
LogUtil.APP.info("用例:{} 第{}步,在当前页面中找到预期结果中对象。当前步骤执行成功!",testcase.getCaseSign(),step.getStepSerialNumber());
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在当前页面中找到预期结果中对象。当前步骤执行成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,没有在当前页面中找到预期结果中对象。执行失败!";
judgeResult.put("setResult",1);
BaseWebDrive.webScreenShot(driver, imagname);
LogUtil.APP.warn("用例:{} 第{}步,没有在当前页面中找到预期结果中对象。当前步骤执行失败!",testcase.getCaseSign(),step.getStepSerialNumber());
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在当前页面中没有找到预期结果中对象。当前步骤执行失败!" + "checkproperty【" + checkproperty + "】 checkproperty_value【" + checkPropertyValue + "", "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
}
// 其它匹配模式
else {
// 模糊匹配预期结果模式
if (expect.length() > Constants.FUZZY_MATCHING_SIGN.length() && expect.startsWith(Constants.FUZZY_MATCHING_SIGN)) {
if (result.contains(expect.substring(Constants.FUZZY_MATCHING_SIGN.length()))) {
LogUtil.APP.info("用例:{} 第{}步,模糊匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),result);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "模糊匹配预期结果成功!执行结果:" + result, "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,模糊匹配预期结果失败!";
judgeResult.put("setResult",1);
BaseWebDrive.webScreenShot(driver, imagname);
LogUtil.APP.warn("用例:{} 第{}步,模糊匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),expect.substring(Constants.FUZZY_MATCHING_SIGN.length()),result);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "模糊匹配预期结果失败!预期结果:" + expect.substring(Constants.FUZZY_MATCHING_SIGN.length()) + ",测试结果:" + result, "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
}
// 正则匹配预期结果模式
else if (expect.length() > Constants.REGULAR_MATCHING_SIGN.length() && expect.startsWith(Constants.REGULAR_MATCHING_SIGN)) {
Pattern pattern = Pattern.compile(expect.substring(Constants.REGULAR_MATCHING_SIGN.length()));
Matcher matcher = pattern.matcher(result);
if (matcher.find()) {
LogUtil.APP.info("用例:{} 第{}步,正则匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),result);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "正则匹配预期结果成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,正则匹配预期结果失败!";
judgeResult.put("setResult",1);
BaseWebDrive.webScreenShot(driver, imagname);
LogUtil.APP.warn("用例:{} 第{}步,正则匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),expect.substring(Constants.REGULAR_MATCHING_SIGN.length()),result);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "正则匹配预期结果失败!预期结果:" + expect.substring(Constants.REGULAR_MATCHING_SIGN.length()) + ",测试结果:" + result, "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
}
// 精确匹配预期结果模式
else {
if (expect.equals(result)) {
LogUtil.APP.info("用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),result);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else if(expect.trim().equals("NULL")&& StringUtils.isBlank(result)){
result = "返回结果为空匹配NULL成功";
LogUtil.APP.info("用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),result);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
judgeResult.put("setResult",1);
BaseWebDrive.webScreenShot(driver, imagname);
LogUtil.APP.warn("用例:{} 第{}步,精确匹配预期结果失败!预期结果是:【{}】 执行结果:【{}】",testcase.getCaseSign(),step.getStepSerialNumber(),expect,result);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果失败!预期结果是:【"+expect+"】 执行结果:【"+ result+"", "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
}
}
}
} else {
casenote = (null != result) ? result : "";
judgeResult.put("setResult",2);
BaseWebDrive.webScreenShot(driver, imagname);
LogUtil.APP.warn("用例:{} 第{}步,执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),casenote);
// caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "当前步骤在执行过程中解析|定位元素|操作对象失败!" + casenote, "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
return judgeResult; return judgeResult;
} }

View File

@ -107,6 +107,74 @@ public class WebDriverAnalyticCase {
return params; return params;
} }
public static Map<String, String> analyticCaseStep(ProjectCase projectcase, ProjectCaseSteps step, Map<String, String> variable) {
Map<String, String> params = new HashMap<>(0);
String resultstr;
try {
// 处理值传递
String path = ChangString.changparams(step.getStepPath(), variable, "包路径|定位路径");
if (null != path && path.contains("=")) {
String property = path.substring(0, path.indexOf("=")).trim();
String propertyValue = path.substring(path.indexOf("=") + 1).trim();
// set属性
params.put("property", property.toLowerCase());
// set属性值
params.put("property_value", propertyValue);
LogUtil.APP.info("对象属性解析结果property:{}; property_value:{}", property, propertyValue);
}
// set操作方法,处理值传递
String operation = ChangString.changparams(step.getStepOperation().toLowerCase(), variable, "操作");
params.put("operation", operation);
// set属性值,处理值传递
String operationValue = ChangString.changparams(step.getStepParameters(), variable, "操作参数");
if (StringUtils.isNotEmpty(operationValue)) {
params.put("operation_value", operationValue);
}
LogUtil.APP.info("对象操作解析结果operation:{}; operation_value:{}", operation,operationValue);
// 获取预期结果字符串
resultstr = step.getExpectedResult();
// set预期结果
if (null == resultstr || "".equals(resultstr)) {
params.put("ExpectedResults", "");
} else {
String expectedResults = subComment(resultstr);
// 处理check字段
if (expectedResults.toLowerCase().startsWith("check(")) {
expectedResults = expectedResults.replace("Check(", "check(");
params.put("checkproperty", expectedResults.substring(expectedResults.indexOf("check(") + 6,
expectedResults.indexOf("=")));
params.put("checkproperty_value", expectedResults.substring(expectedResults.indexOf("=") + 1,
expectedResults.lastIndexOf(")")));
}
//处理值传递
expectedResults = ChangString.changparams(expectedResults, variable, "预期结果");
params.put("ExpectedResults", expectedResults);
LogUtil.APP.info("预期结果解析ExpectedResults:{}", expectedResults);
}
LogUtil.APP.info("用例编号:{} 第{}步,解析自动化用例步骤脚本完成!", projectcase.getCaseSign(), step.getStepSerialNumber());
// if (null != caselog) {
// caselog.insertTaskCaseLog(taskid, projectcase.getCaseId(),
// "步骤编号:" + step.getStepSerialNumber() + " 解析自动化用例步骤脚本完成!", "info",
// String.valueOf(step.getStepSerialNumber()), "");
// }
} catch (Exception e) {
LogUtil.APP.error("用例编号:{} 第{}步,解析自动化用例步骤脚本出现异常!", projectcase.getCaseSign(), step.getStepSerialNumber(),
e);
// if (null != caselog) {
// caselog.insertTaskCaseLog(taskid, projectcase.getCaseId(),
// "步骤编号:" + step.getStepSerialNumber() + " 解析自动化用例步骤脚本出错!", "error",
// String.valueOf(step.getStepSerialNumber()), "");
// }
params.put("exception", "用例编号:" + projectcase.getCaseSign() + "|解析异常,用例步骤为空或是用例脚本错误!");
return params;
}
return params;
}
private static String subComment(String htmlStr) { private static String subComment(String htmlStr) {
// 定义script的正则表达式 // 定义script的正则表达式
String regExScript = "<script[^>]*?>[\\s\\S]*?</script>"; String regExScript = "<script[^>]*?>[\\s\\S]*?</script>";

View File

@ -58,4 +58,33 @@ public class WebOneCaseExecute{
wd.quit(); wd.quit();
} }
public static void debugoneCaseExecute(int caseId, int drivertype){
// //记录日志到数据库
// serverOperation.exetype = 1;
WebDriver wd = null;
try {
wd = WebDriverInitialization.setWebDriverForTask(drivertype);
} catch (IOException e1) {
LogUtil.APP.error("初始化WebDriver出错", e1);
}
// serverOperation caselog = new serverOperation();
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseId);
//删除旧的日志
// serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
List<ProjectCaseParams> pcplist=GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
LogUtil.APP.info("开始执行用例:【{}】......",testcase.getCaseSign());
try {
List<ProjectCaseSteps> steps=GetServerApi.getStepsbycaseid(testcase.getCaseId());
WebCaseExecution.caseExcution(testcase, steps, wd,pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
// serverOperation.updateTaskExecuteData(taskid, 0,2);
//关闭浏览器
assert wd != null;
wd.quit();
}
} }

View File

@ -0,0 +1,67 @@
package luckyclient.tool;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import luckyclient.utils.LogUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
/**
* @author lifengyang
*/
public class SpecialProjectT {
public static String set_String(String set){
LogUtil.APP.info("设置的字符串为:"+set);
return set;
}
//输入json字符串后对其key进行自然排序
public static String jsonStringNaturalOrdering(String jsonString){
LogUtil.APP.info("设置的jsonString字符串为"+jsonString);
jsonString=JSONObject.toJSONString(JSONObject.parseObject(jsonString), SerializerFeature.MapSortField);
LogUtil.APP.info("自然排序后的jsonString字符串为"+jsonString);
return jsonString;
}
/**
* windows 执行cmd
* @param cmd
* @return 返回cmd命令执行结果
* @throws IOException
*/
public String exeCMD(String cmd) throws IOException {
LogUtil.APP.info("cmd命令为"+cmd);
String lw=cmd.toLowerCase();
if(!lw.contains("cmd /c")){
cmd="cmd /c "+lw;
}
//针对jmeter 生成报告做处理
if(cmd.contains("jmeter -g")){
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd_HH_mm_ss");
String time=formatter.format(date);
cmd=cmd+time;
}
Process process=Runtime.getRuntime().exec(cmd);
InputStream input = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input,"GBK"));
String s;
StringBuilder sb = new StringBuilder();
while((s=reader.readLine())!=null){
sb.append(s+"\n");
}
reader.close();
input.close();
s=sb.toString();
LogUtil.APP.info(s);
return s;
}
}

View File

@ -0,0 +1,31 @@
package luckyclient.tool;
public class UseConstant {
public static final String[] tag_names ={"span","label","div","input","a"};
// public static final String tag_names_span="span";
// public static final String tag_names_label="span";
// public static final String tag_names_div="div";
// public static final String tag_names_input="input";
// public static final String tag_names_a="a";
public static final String attribute_value_starts_with="starts-with";
public static final String attribute_value_contains="contains";
public static final String attribute_value_ends_with="ends-with";
public static final String ID = "id";
public static final String XPATH = "xpath";
public static final String LINK_TEXT = "link text";
public static final String PARTIAL_LINK_TEXT = "partial link text";
public static final String NAME = "name";
public static final String TAG_NAME = "tag name";
public static final String CLASS_NAME = "class name";
public static final String CSS_SELECTOR = "css selector";
public static final String XPATH_OTHER = "xpath other";
}

View File

@ -13,6 +13,7 @@ import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import luckyclient.execution.dispose.ChangString; import luckyclient.execution.dispose.ChangString;
import luckyclient.execution.dispose.ParamsManageForSteps; import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.remote.api.GetServerApi; import luckyclient.remote.api.GetServerApi;
@ -192,7 +193,7 @@ public class InvokeMethod {
} }
//处理参数对象 //处理参数对象
if (ptp.getParamType() == 1) { if (ptp.getParamType() == 1) {
JSONObject json = JSONObject.parseObject(tempparam); JSONObject json = JSONObject.parseObject(tempparam, Feature.OrderedField);
params.put(ptp.getParamName().replace("&quot;", "\""), json); params.put(ptp.getParamName().replace("&quot;", "\""), json);
LogUtil.APP.info("模板参数【{}】 JSONObject类型参数值:【{}】",ptp.getParamName(),json.toString()); LogUtil.APP.info("模板参数【{}】 JSONObject类型参数值:【{}】",ptp.getParamName(),json.toString());
} else if (ptp.getParamType() == 2) { } else if (ptp.getParamType() == 2) {

View File

@ -19,6 +19,7 @@ import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
@ -41,6 +42,7 @@ import java.security.KeyStore;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -577,7 +579,7 @@ public class HttpClientTools {
* @param ppt 协议模板对象 * @param ppt 协议模板对象
* @return 返回请求结果 * @return 返回请求结果
*/ */
public String httpClientPostJson(String urlParam, Map<String, Object> params, Map<String, String> headmsg, ProjectProtocolTemplate ppt) throws NoSuchAlgorithmException, KeyManagementException { public String httpClientPostJson(String urlParam, Map<String, Object> params, Map<String, String> headmsg, ProjectProtocolTemplate ppt) throws NoSuchAlgorithmException, KeyManagementException, UnsupportedEncodingException {
String cerpath = ppt.getCerificatePath(); String cerpath = ppt.getCerificatePath();
String charset = ppt.getEncoding().toLowerCase(); String charset = ppt.getEncoding().toLowerCase();
int timeout = ppt.getTimeout() * 1000; int timeout = ppt.getTimeout() * 1000;
@ -611,7 +613,7 @@ public class HttpClientTools {
try { try {
if (params.size() > 0) { if (params.size() > 0) {
if (1 == params.size() && params.containsKey("_forTextJson")) { if (1 == params.size() && params.containsKey("_forTextJson")) {
LogUtil.APP.info("参数类型:TEXT,设置HTTPPostJson参数信息...【{}】", params.get("_forTextJson").toString()); LogUtil.APP.info("参数类型:RAW,设置HTTPPostJson参数信息...【{}】", params.get("_forTextJson").toString());
StringEntity entity = new StringEntity(params.get("_forTextJson").toString(), charset); StringEntity entity = new StringEntity(params.get("_forTextJson").toString(), charset);
httpPost.setEntity(entity); httpPost.setEntity(entity);
} else { } else {

View File

@ -178,7 +178,7 @@ public class HttpImpl {
e.printStackTrace(); e.printStackTrace();
} }
WebDebugCaseEntity webDebugCaseEntity = JSONObject.parseObject(sbd.toString(), WebDebugCaseEntity.class); WebDebugCaseEntity webDebugCaseEntity = JSONObject.parseObject(sbd.toString(), WebDebugCaseEntity.class);
log.info("Web端调试用例ID:{} 发起人ID:{}",webDebugCaseEntity.getCaseId(),webDebugCaseEntity.getUserId()); log.info("Web端调试用例ID:{} 发起人ID:{} 调试用例类型:{}",webDebugCaseEntity.getCaseId(),webDebugCaseEntity.getUserId(),webDebugCaseEntity.getCaseType());
try{ try{
File file =new File(RunService.APPLICATION_HOME+webDebugCaseEntity.getLoadpath()); File file =new File(RunService.APPLICATION_HOME+webDebugCaseEntity.getLoadpath());
if (!file .isDirectory()) if (!file .isDirectory())
@ -190,13 +190,23 @@ public class HttpImpl {
StringBuilder sb=new StringBuilder(); StringBuilder sb=new StringBuilder();
sb.append(webDebugCaseEntity.getCaseId()).append(" "); sb.append(webDebugCaseEntity.getCaseId()).append(" ");
sb.append(webDebugCaseEntity.getUserId()).append(" "); sb.append(webDebugCaseEntity.getUserId()).append(" ");
sb.append(webDebugCaseEntity.getCaseType()).append(" ");//修改点
sb.append(webDebugCaseEntity.getLoadpath()); sb.append(webDebugCaseEntity.getLoadpath());
if(OS.startsWith("win")){ if(webDebugCaseEntity.getCaseType().intValue()==0||webDebugCaseEntity.getCaseType().intValue()==2){
run.exec("cmd.exe /k start " + "web_debugcase.cmd" + " " +sb.toString(), null,new File(RunService.APPLICATION_HOME+File.separator)); if(OS.startsWith("win")){
}else{ run.exec("cmd.exe /k start " + "web_debugcase.cmd" + " " +sb.toString(), null,new File(RunService.APPLICATION_HOME+File.separator));
Process ps = Runtime.getRuntime().exec(RunService.APPLICATION_HOME+File.separator+"web_debugcase.sh"+ " " +sb.toString()); }else{
ps.waitFor(); Process ps = Runtime.getRuntime().exec(RunService.APPLICATION_HOME+File.separator+"web_debugcase.sh"+ " " +sb.toString());
} ps.waitFor();
}
}else if (webDebugCaseEntity.getCaseType().intValue()==1){
if(OS.startsWith("win")){
sb.append(" ").append(webDebugCaseEntity.getBrowserType());
run.exec("cmd.exe /k start " + "web_debugcase_web.cmd" + " " +sb.toString(), null,new File(RunService.APPLICATION_HOME+File.separator));
}else{
//待补充
}
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("启动Web调试模式测试程序异常",e); log.error("启动Web调试模式测试程序异常",e);

View File

@ -19,7 +19,10 @@ public class WebDebugCaseEntity implements Serializable {
private Integer caseId; private Integer caseId;
private Integer userId; private Integer userId;
private String loadpath; private String loadpath;
//修改点
private Integer caseType;
private Integer browserType;
public Integer getCaseId() { public Integer getCaseId() {
return caseId; return caseId;
} }
@ -39,4 +42,15 @@ public class WebDebugCaseEntity implements Serializable {
this.loadpath = loadpath; this.loadpath = loadpath;
} }
//修改点
public Integer getCaseType(){return caseType; }
public void setCaseType(Integer caseType) {
this.caseType = caseType;
}
public Integer getBrowserType() {
return browserType;
}
public void setBrowserType(Integer browserType) {
this.browserType = browserType;
}
} }