根据IDEA提示全面优化代码

This commit is contained in:
seagull 2020-03-16 19:32:07 +08:00
parent 6974d06d77
commit 60f7a1947e
76 changed files with 8036 additions and 8267 deletions

View File

@ -1,37 +1,49 @@
package luckyclient.driven;
import java.util.Properties;
import luckyclient.utils.DbOperation;
import luckyclient.utils.config.DrivenConfig;
/**
* 提供数据库查询操作的默认测试驱动
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2020年2月17日
*/
public class DbDriven {
public String executeSql(String sql) throws Exception{
Properties properties = DrivenConfig.getConfiguration();
String url = properties.getProperty("db.url");
String username = properties.getProperty("db.username");
String password = properties.getProperty("db.password");
DbOperation db=new DbOperation(url,username,password);
return db.executeQuery(sql);
}
public String executeQuery(String sql) throws Exception{
Properties properties = DrivenConfig.getConfiguration();
String url = properties.getProperty("db.url");
String username = properties.getProperty("db.username");
String password = properties.getProperty("db.password");
DbOperation db=new DbOperation(url,username,password);
return db.executeQuery(sql);
}
}
package luckyclient.driven;
import java.util.Properties;
import luckyclient.utils.DbOperation;
import luckyclient.utils.config.DrivenConfig;
/**
* 提供数据库查询操作的默认测试驱动
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2020年2月17日
*/
public class DbDriven {
/**
* 执行SQL语句
* @param sql 执行SQL语句
* @return 返回执行结果条数才及提示
* @throws Exception 抛异常
*/
public String executeSql(String sql) throws Exception{
Properties properties = DrivenConfig.getConfiguration();
String url = properties.getProperty("db.url");
String username = properties.getProperty("db.username");
String password = properties.getProperty("db.password");
DbOperation db=new DbOperation(url,username,password);
return db.executeSql(sql);
}
/**
* 查询SQL语句
* @param sql 查询SQL
* @return 返回查询结果
* @throws Exception 异常信息
*/
public String executeQuery(String sql) throws Exception{
Properties properties = DrivenConfig.getConfiguration();
String url = properties.getProperty("db.url");
String username = properties.getProperty("db.username");
String password = properties.getProperty("db.password");
DbOperation db=new DbOperation(url,username,password);
return db.executeQuery(sql);
}
}

View File

@ -1,5 +1,6 @@
package luckyclient.driven;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@ -32,10 +33,10 @@ public class SubString {
/**
* 截取指定字符串的中间字段
*
* @param str
* @param startstr
* @param endstr
* @return
* @param str 原始字符串
* @param startstr 开始字符
* @param endstr 结束字符
* @return 返回字符串截取结果
*/
public static String subCentreStr(String str, String startstr, String endstr) {
try{
@ -47,8 +48,7 @@ public class SubString {
if(!"".equals(endstr)){
endnum=str.indexOf(endstr, str.indexOf(startstr) + startstr.length());
}
String getstr = str.substring(startnum,endnum);
return getstr;
return str.substring(startnum,endnum);
}catch(Exception e){
LogUtil.APP.error("subCentreStr截取字符串出现异常请检查参数",e);
return "截取字符串出现异常,请检查参数!";
@ -58,14 +58,13 @@ public class SubString {
/**
* 截取字符串从指定字符开始
*
* @param str
* @param startstr
* @return
* @param str 原始字符
* @param startstr 开始字符
* @return 返回字符串截取结果
*/
public static String subStartStr(String str, String startstr) {
try{
String getstr = str.substring(str.indexOf(startstr) + startstr.length());
return getstr;
return str.substring(str.indexOf(startstr) + startstr.length());
}catch(Exception e){
LogUtil.APP.error("subStartStr截取字符串出现异常请检查参数",e);
return "截取字符串出现异常,请检查参数!";
@ -75,14 +74,13 @@ public class SubString {
/**
* 截取字符串到指定字符结束
*
* @param str
* @param endstr
* @return
* @param str 原始字符
* @param endstr 结束字符
* @return 返回字符串截取结果
*/
public static String subEndStr(String str, String endstr) {
try{
String getstr = str.substring(0, str.indexOf(endstr));
return getstr;
return str.substring(0, str.indexOf(endstr));
}catch(Exception e){
LogUtil.APP.error("subEndStr截取字符串出现异常请检查参数",e);
return "截取字符串出现异常,请检查参数!";
@ -92,13 +90,13 @@ public class SubString {
/**
* 通过字符串位置截取指定字符串的中间字段
*
* @param str
* @param startnum
* @param endnum
* @return
* @param str 原始字符
* @param startnum 开始字符位置
* @param endnum 结果位置
* @return 返回字符串截取结果
*/
public static String subCentreNum(String str, String startnum, String endnum) {
String getstr = "";
String getstr;
if("".equals(startnum)){
startnum="0";
}
@ -107,11 +105,11 @@ public class SubString {
}
try{
if (isInteger(startnum) && isInteger(endnum)) {
int start = Integer.valueOf(startnum);
int end = Integer.valueOf(endnum);
int start = Integer.parseInt(startnum);
int end = Integer.parseInt(endnum);
if (start > end) {
getstr = "截取字符串开始位置数字不能大于结束位置数字";
} else if (start < 0 || end < 0) {
} else if (start < 0) {
getstr = "截取字符串位置的数字不能小于0";
} else if (start > str.length() || end > str.length()) {
getstr = "截取字符串位置的数字不能大于字符串本身的长度【" + str.length() + "";
@ -132,15 +130,15 @@ public class SubString {
/**
* 通过字符串位置截取字符串从指定字符开始
*
* @param str
* @param startnum
* @return
* @param str 原始字符
* @param startnum 字符开始位置
* @return 返回字符串截取结果
*/
public static String subStartNum(String str, String startnum) {
String getstr = "";
String getstr;
try{
if (isInteger(startnum)) {
int start = Integer.valueOf(startnum);
int start = Integer.parseInt(startnum);
if (start < 0) {
getstr = "截取字符串位置的数字不能小于0";
} else if (start > str.length()) {
@ -162,15 +160,15 @@ public class SubString {
/**
* 截取字符串到指定字符结束
*
* @param str
* @param endnum
* @return
* @param str 原始字符
* @param endnum 结束位置
* @return 返回字符串截取结果
*/
public static String subEndNum(String str, String endnum) {
String getstr = "";
String getstr;
try{
if (isInteger(endnum)) {
int end = Integer.valueOf(endnum);
int end = Integer.parseInt(endnum);
if (end < 0) {
getstr = "截取字符串位置的数字不能小于0";
} else if (end > str.length()) {
@ -189,8 +187,15 @@ public class SubString {
}
}
/**
* 正则匹配字符串
* @param str 原始字符串
* @param rgex 正则表达式
* @param num 字符索引
* @return 匹配到的字符串
*/
public static String subStrRgex(String str, String rgex, String num) {
List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<>();
try{
// 匹配的模式
Pattern pattern = Pattern.compile(rgex);
@ -201,9 +206,9 @@ public class SubString {
// i++;
}
String getstr = "";
String getstr;
if (isInteger(num)) {
int index = Integer.valueOf(num);
int index = Integer.parseInt(num);
if (index < 0) {
getstr = "截取字符串索引数字不能小于0";
} else if (index > str.length()) {
@ -223,8 +228,13 @@ public class SubString {
}
}
/**
* 判断是否是整型数字
* @param str 整形字符
* @return 返回布尔型结果
*/
private static boolean isInteger(String str) {
String patternStr="^[-\\+]?[\\d]*$";
String patternStr="^[-+]?[\\d]*$";
Pattern pattern = Pattern.compile(patternStr);
return pattern.matcher(str).matches();
}
@ -241,11 +251,10 @@ public class SubString {
/**
* 遍历JSON对象
*
* @param json
* @param key
* @param keyindex
* @return
* @param json 原始JSON
* @param key 查询key值
* @param keyindex key值索引
* @return 返回json对象
*/
private static JSONObject parseJsonString(String json, String key, int keyindex) {
LinkedHashMap<String, Object> jsonMap = JSON.parseObject(json,
@ -259,14 +268,12 @@ public class SubString {
/**
* 遍历后JSON对象中的key以及value
*
* @param entry
* @param key
* @param keyindex
* @return
* @param entry json中所有的的key以及value
* @param key 需要提取的key
* @param keyindex 提取key的索引
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Map.Entry<String, Object> parseJsonMap(Map.Entry<String, Object> entry, String key, int keyindex) {
private static void parseJsonMap(Map.Entry<String, Object> entry, String key, int keyindex) {
// 如果是单个map继续遍历
if (entry.getValue() instanceof Map) {
LinkedHashMap<String, Object> jsonMap = JSON.parseObject(entry.getValue().toString(),
@ -304,23 +311,22 @@ public class SubString {
COUNTER++;
}
return entry;
}
/**
* 获取JSON或是JSONArray对象指定序号Key中的Value
*
* @param json
* @param key
* @param indexstr
* @return
* @param json 原始JSON
* @param key 指定key
* @param indexstr key的索引
* @return 返回指定key的value字符
*/
public static String getJsonValue(String json, String key, String indexstr) {
json = json.trim();
int index = 1;
int index;
String result = JSONVALUE;
if (isInteger(indexstr) && !"0".equals(indexstr)) {
index = Integer.valueOf(indexstr);
index = Integer.parseInt(indexstr);
} else {
result = JSONVALUE + "指定的key值序号不是大于0的整数(序号从1开始),请检查!";
return result;
@ -339,7 +345,7 @@ public class SubString {
try {
// JSONArray jsonarr = JSONArray.parseArray(json);
// 直接使用fastjson的接口实现有序解析
JSONArray jsonarr = JSONArray.parseObject(json.getBytes("UTF-8"), JSONArray.class, Feature.OrderedField);
JSONArray jsonarr = JSONArray.parseObject(json.getBytes(StandardCharsets.UTF_8), JSONArray.class, Feature.OrderedField);
for (int i = 0; i < jsonarr.size(); i++) {
JSONObject jsonStr = jsonarr.getJSONObject(i);
parseJsonString(jsonStr.toJSONString(), key, index);
@ -367,14 +373,14 @@ public class SubString {
/**
* 通过jsonPath表达式获取JSON字符串指定值
* @param expressionParams
* @param jsonString
* @return
* @param expressionParams jsonPath表达式
* @param jsonString json原始字符串
* @return 返回提取到手字符
* @author Seagull
* @date 2019年8月28日
*/
public static String jsonPathGetParams(String expressionParams, String jsonString) {
String type="String";
String type;
String expression="";
if(expressionParams.endsWith("]")&&expressionParams.contains("[")){
try{
@ -394,7 +400,7 @@ public class SubString {
List<Object> list = JsonPath.parse(jsonString).read(expression);
jsonString="";
for(Object result:list){
result = (String)jsonString+result+",";
result = jsonString +result+",";
jsonString = (String)result;
}
}else{
@ -403,7 +409,7 @@ public class SubString {
}catch(PathNotFoundException pnfe){
LogUtil.APP.error("通过jsonPath获取JSON字符串指定值出现异常没有找到对应参数路径请确认JSON字符串【{}】表达式是否正确【{}】!",jsonString,expression);
}catch(Exception e){
LogUtil.APP.error("通过jsonPath获取JSON字符串指定值出现异,请检查您的动作参数格式(String/List[表达式])或是被提取的json字符串是否正常",expressionParams);
LogUtil.APP.error("通过jsonPath获取JSON字符串指定值出现异,请检查您的动作参数格式(String/List[表达式])或是被提取的json字符串是否正常");
}
}else{
LogUtil.APP.warn("获取JSON字符串指定jsonPath表达式【{}】异常,请检查您的动作参数格式(String/List[表达式])是否正常!",expressionParams);
@ -411,5 +417,4 @@ public class SubString {
LogUtil.APP.info("获取JSON字符串指定jsonPath表达式【{}】的值是:{}",expression,jsonString);
return jsonString;
}
}

View File

@ -1,68 +1,68 @@
package luckyclient.execution;
import java.io.File;
import java.util.Properties;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.appium.androidex.AndroidBatchExecute;
import luckyclient.execution.appium.iosex.IosBatchExecute;
import luckyclient.execution.httpinterface.BatchTestCaseExecution;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.ex.WebBatchExecute;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class BatchCaseExecute extends TestControl {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
PropertyConfigurator.configure(System.getProperty("user.dir") + File.separator + "log4j.conf");
String taskid = args[0];
String batchcase = args[1];
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.valueOf(taskid));
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(Integer.valueOf(taskid));
if (taskScheduling.getTaskType() == 0) {
BatchTestCaseExecution.batchCaseExecuteForTast(taskScheduling.getProject().getProjectName(),
String.valueOf(task.getTaskId()), batchcase);
} else if (taskScheduling.getTaskType() == 1) {
// UI测试
WebBatchExecute.batchCaseExecuteForTast(taskScheduling.getProject().getProjectName(),
String.valueOf(task.getTaskId()), batchcase);
} else if (taskScheduling.getTaskType() == 2) {
Properties properties = AppiumConfig.getConfiguration();
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidBatchExecute.batchCaseExecuteForTast(taskScheduling.getProject().getProjectName(),
String.valueOf(task.getTaskId()), batchcase);
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosBatchExecute.batchCaseExecuteForTast(taskScheduling.getProject().getProjectName(),
String.valueOf(task.getTaskId()), batchcase);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("启动批量运行用例主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}
package luckyclient.execution;
import java.io.File;
import java.util.Properties;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.appium.androidex.AndroidBatchExecute;
import luckyclient.execution.appium.iosex.IosBatchExecute;
import luckyclient.execution.httpinterface.BatchTestCaseExecution;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.ex.WebBatchExecute;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class BatchCaseExecute extends TestControl {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
PropertyConfigurator.configure(System.getProperty("user.dir") + File.separator + "log4j.conf");
String taskid = args[0];
String batchcase = args[1];
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(Integer.parseInt(taskid));
if (taskScheduling.getTaskType() == 0) {
BatchTestCaseExecution.batchCaseExecuteForTast(
String.valueOf(task.getTaskId()), batchcase);
} else if (taskScheduling.getTaskType() == 1) {
// UI测试
WebBatchExecute.batchCaseExecuteForTast(
String.valueOf(task.getTaskId()), batchcase);
} else if (taskScheduling.getTaskType() == 2) {
Properties properties = AppiumConfig.getConfiguration();
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidBatchExecute.batchCaseExecuteForTast(
String.valueOf(task.getTaskId()), batchcase);
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosBatchExecute.batchCaseExecuteForTast(
String.valueOf(task.getTaskId()), batchcase);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("启动批量运行用例主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}

View File

@ -1,68 +1,66 @@
package luckyclient.execution;
import java.io.File;
import java.util.Properties;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.appium.androidex.AndroidOneCaseExecute;
import luckyclient.execution.appium.iosex.IosOneCaseExecute;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.ex.WebOneCaseExecute;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class OneCaseExecute extends TestControl {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
try{
PropertyConfigurator.configure(System.getProperty("user.dir")+ File.separator +"log4j.conf");
String taskId = args[0];
String caseId = args[1];
int version = Integer.parseInt(args[2]);
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.valueOf(taskId));
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(Integer.valueOf(taskId));
if (taskScheduling.getTaskType() == 0) {
// 接口测试
TestCaseExecution testCaseExecution=new TestCaseExecution();
testCaseExecution.oneCaseExecuteForTask(taskScheduling.getProject().getProjectName(), Integer.valueOf(caseId), String.valueOf(task.getTaskId()));
} else if (taskScheduling.getTaskType() == 1) {
WebOneCaseExecute.oneCaseExecuteForTast(taskScheduling.getProject().getProjectName(), Integer.valueOf(caseId), version,
String.valueOf(task.getTaskId()));
} else if (taskScheduling.getTaskType() == 2) {
Properties properties = AppiumConfig.getConfiguration();
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidOneCaseExecute.oneCaseExecuteForTast(taskScheduling.getProject().getProjectName(), Integer.valueOf(caseId),
version, String.valueOf(task.getTaskId()));
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosOneCaseExecute.oneCaseExecuteForTast(taskScheduling.getProject().getProjectName(), Integer.valueOf(caseId), version,
String.valueOf(task.getTaskId()));
}
}
}catch(Exception e){
LogUtil.APP.error("启动单个用例运行主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}
package luckyclient.execution;
import java.io.File;
import java.util.Properties;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.appium.androidex.AndroidOneCaseExecute;
import luckyclient.execution.appium.iosex.IosOneCaseExecute;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.ex.WebOneCaseExecute;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class OneCaseExecute extends TestControl {
public static void main(String[] args) {
try{
PropertyConfigurator.configure(System.getProperty("user.dir")+ File.separator +"log4j.conf");
String taskId = args[0];
String caseId = args[1];
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskId));
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(Integer.parseInt(taskId));
if (taskScheduling.getTaskType() == 0) {
// 接口测试
TestCaseExecution testCaseExecution=new TestCaseExecution();
testCaseExecution.oneCaseExecuteForTask(Integer.valueOf(caseId), String.valueOf(task.getTaskId()));
} else if (taskScheduling.getTaskType() == 1) {
WebOneCaseExecute.oneCaseExecuteForTast(Integer.valueOf(caseId),
String.valueOf(task.getTaskId()));
} else if (taskScheduling.getTaskType() == 2) {
Properties properties = AppiumConfig.getConfiguration();
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidOneCaseExecute.oneCaseExecuteForTast(Integer.valueOf(caseId),
String.valueOf(task.getTaskId()));
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosOneCaseExecute.oneCaseExecuteForTast(Integer.valueOf(caseId),
String.valueOf(task.getTaskId()));
}
}
}catch(Exception e){
LogUtil.APP.error("启动单个用例运行主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}

View File

@ -1,50 +1,49 @@
package luckyclient.execution;
import java.io.File;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.appium.AppTestControl;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.WebTestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class RunAutomationTest extends TestControl {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
PropertyConfigurator.configure(System.getProperty("user.dir") + File.separator + "log4j.conf");
String taskid = args[0];
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.valueOf(taskid));
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(Integer.valueOf(taskid));
if (taskScheduling.getTaskType() == 0) {
// 接口测试
TestControl.taskExecutionPlan(task);
} else if (taskScheduling.getTaskType() == 1) {
// UI测试
WebTestControl.taskExecutionPlan(task);
} else if (taskScheduling.getTaskType() == 2) {
AppTestControl.taskExecutionPlan(task);
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("启动测试任务运行主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}
package luckyclient.execution;
import java.io.File;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.appium.AppTestControl;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.WebTestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class RunAutomationTest extends TestControl {
public static void main(String[] args) {
try {
PropertyConfigurator.configure(System.getProperty("user.dir") + File.separator + "log4j.conf");
String taskid = args[0];
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(Integer.parseInt(taskid));
if (taskScheduling.getTaskType() == 0) {
// 接口测试
TestControl.taskExecutionPlan(task);
} else if (taskScheduling.getTaskType() == 1) {
// UI测试
WebTestControl.taskExecutionPlan(task);
} else if (taskScheduling.getTaskType() == 2) {
AppTestControl.taskExecutionPlan(task);
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("启动测试任务运行主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}

View File

@ -1,38 +1,36 @@
package luckyclient.execution;
import java.io.File;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.httpinterface.WebTestCaseDebug;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebDebugExecute extends TestControl{
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
try {
PropertyConfigurator.configure(System.getProperty("user.dir") + File.separator + "log4j.conf");
String caseIdStr = args[0];
String userIdStr = args[1];
WebTestCaseDebug.oneCaseDebug(caseIdStr, userIdStr);
} catch (Exception e) {
// TODO: handle exception
LogUtil.APP.error("启动用例调试主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}
package luckyclient.execution;
import java.io.File;
import org.apache.log4j.PropertyConfigurator;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.httpinterface.WebTestCaseDebug;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebDebugExecute extends TestControl{
public static void main(String[] args) {
try {
PropertyConfigurator.configure(System.getProperty("user.dir") + File.separator + "log4j.conf");
String caseIdStr = args[0];
String userIdStr = args[1];
WebTestCaseDebug.oneCaseDebug(caseIdStr, userIdStr);
} catch (Exception e) {
LogUtil.APP.error("启动用例调试主函数出现异常,请检查!",e);
} finally{
System.exit(0);
}
}
}

View File

@ -1,184 +1,185 @@
package luckyclient.execution.appium;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import luckyclient.execution.dispose.ChangString;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: AnalyticCase
* @Description: 解析单个用例中描述部分的脚本
* @author seagull
* @date 2016年9月18日
*
*/
public class AppDriverAnalyticCase {
//private static String splitFlag = "\\|";
/**
* 移动端的用例步骤解析
* @param projectcase
* @param step
* @param taskid
* @param caselog
* @return
* @author Seagull
* @date 2019年1月17日
*/
public static Map<String,String> analyticCaseStep(ProjectCase projectcase,ProjectCaseSteps step,String taskid,serverOperation caselog, Map<String, String> variable){
Map<String,String> params = new HashMap<String,String>(0);
String resultstr = null;
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, path.length()).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)){
//set属性值
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 if(null!=resultstr){
String expectedResults = subComment(resultstr);
//处理check字段
if(expectedResults.startsWith("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) {
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;
}
private static String subComment(String htmlStr) throws InterruptedException{
// 定义script的正则表达式
String regExScript = "<script[^>]*?>[\\s\\S]*?<\\/script>";
// 定义style的正则表达式
String regExStyle = "<style[^>]*?>[\\s\\S]*?<\\/style>";
// 定义HTML标签的正则表达式
String regExHtml = "<[^>]+>";
//定义空格回车换行符
String regExSpace = "\t|\r|\n";
String scriptstr = null;
if (htmlStr!=null) {
Pattern pScript = Pattern.compile(regExScript, Pattern.CASE_INSENSITIVE);
Matcher mScript = pScript.matcher(htmlStr);
// 过滤script标签
htmlStr = mScript.replaceAll("");
Pattern pStyle = Pattern.compile(regExStyle, Pattern.CASE_INSENSITIVE);
Matcher mStyle = pStyle.matcher(htmlStr);
// 过滤style标签
htmlStr = mStyle.replaceAll("");
Pattern pHtml = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE);
Matcher mHtml = pHtml.matcher(htmlStr);
// 过滤html标签
htmlStr = mHtml.replaceAll("");
Pattern pSpace = Pattern.compile(regExSpace, Pattern.CASE_INSENSITIVE);
Matcher mSpace = pSpace.matcher(htmlStr);
// 过滤空格回车标签
htmlStr = mSpace.replaceAll("");
}
if(htmlStr.indexOf("/*")>-1&&htmlStr.indexOf("*/")>-1){
String commentstr = htmlStr.substring(htmlStr.trim().indexOf("/*"),htmlStr.indexOf("*/")+2);
//去注释
scriptstr = htmlStr.replace(commentstr, "");
}else{
scriptstr = htmlStr;
}
//去掉字符串前后的空格
scriptstr = trimInnerSpaceStr(scriptstr);
//替换空格转义
scriptstr = scriptstr.replaceAll("&nbsp;", " ");
//转义双引号
scriptstr = scriptstr.replaceAll("&quot;", "\"");
//转义单引号
scriptstr = scriptstr.replaceAll("&#39;", "\'");
//转义链接符
scriptstr = scriptstr.replaceAll("&amp;", "&");
scriptstr = scriptstr.replaceAll("&lt;", "<");
scriptstr = scriptstr.replaceAll("&gt;", ">");
return scriptstr;
}
/***
* 去掉字符串前后的空格中间的空格保留
* @param str
* @return
*/
public static String trimInnerSpaceStr(String str) {
str = str.trim();
while (str.startsWith(" ")) {
str = str.substring(1, str.length()).trim();
}
while (str.startsWith("&nbsp;")) {
str = str.substring(6, str.length()).trim();
}
while (str.endsWith(" ")) {
str = str.substring(0, str.length() - 1).trim();
}
while (str.endsWith("&nbsp;")) {
str = str.substring(0, str.length() - 6).trim();
}
return str;
}
public static void main(String[] args){
// TODO Auto-generated method stub
}
}
package luckyclient.execution.appium;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import luckyclient.execution.dispose.ChangString;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: AnalyticCase
* @Description: 解析单个用例中描述部分的脚本
* @author seagull
* @date 2016年9月18日
*
*/
public class AppDriverAnalyticCase {
//private static String splitFlag = "\\|";
/**
* 移动端的用例步骤解析
* @param projectcase 用例对象
* @param step 步骤对象
* @param taskid 任务ID
* @param caselog 日志操作
* @return 返回步骤分析对象MAP
* @author Seagull
* @date 2019年1月17日
*/
public static Map<String,String> analyticCaseStep(ProjectCase projectcase,ProjectCaseSteps step,String taskid,serverOperation caselog, 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)){
//set属性值
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.startsWith("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) {
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;
}
private static String subComment(String htmlStr) {
// 定义script的正则表达式
String regExScript = "<script[^>]*?>[\\s\\S]*?</script>";
// 定义style的正则表达式
String regExStyle = "<style[^>]*?>[\\s\\S]*?</style>";
// 定义HTML标签的正则表达式
String regExHtml = "<[^>]+>";
//定义空格回车换行符
String regExSpace = "[\t\r\n]";
String scriptstr;
if (htmlStr!=null) {
Pattern pScript = Pattern.compile(regExScript, Pattern.CASE_INSENSITIVE);
Matcher mScript = pScript.matcher(htmlStr);
// 过滤script标签
htmlStr = mScript.replaceAll("");
Pattern pStyle = Pattern.compile(regExStyle, Pattern.CASE_INSENSITIVE);
Matcher mStyle = pStyle.matcher(htmlStr);
// 过滤style标签
htmlStr = mStyle.replaceAll("");
Pattern pHtml = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE);
Matcher mHtml = pHtml.matcher(htmlStr);
// 过滤html标签
htmlStr = mHtml.replaceAll("");
Pattern pSpace = Pattern.compile(regExSpace, Pattern.CASE_INSENSITIVE);
Matcher mSpace = pSpace.matcher(htmlStr);
// 过滤空格回车标签
htmlStr = mSpace.replaceAll("");
}
assert htmlStr != null;
if(htmlStr.contains("/*") && htmlStr.contains("*/")){
String commentstr = htmlStr.substring(htmlStr.trim().indexOf("/*"),htmlStr.indexOf("*/")+2);
//去注释
scriptstr = htmlStr.replace(commentstr, "");
}else{
scriptstr = htmlStr;
}
//去掉字符串前后的空格
scriptstr = trimInnerSpaceStr(scriptstr);
//替换空格转义
scriptstr = scriptstr.replaceAll("&nbsp;", " ");
//转义双引号
scriptstr = scriptstr.replaceAll("&quot;", "\"");
//转义单引号
scriptstr = scriptstr.replaceAll("&#39;", "'");
//转义链接符
scriptstr = scriptstr.replaceAll("&amp;", "&");
scriptstr = scriptstr.replaceAll("&lt;", "<");
scriptstr = scriptstr.replaceAll("&gt;", ">");
return scriptstr;
}
/**
* 去掉字符串前后的空格中间的空格保留
* @param str 原始字符串
* @return 返回去掉空格后的字符串
*/
public static String trimInnerSpaceStr(String str) {
str = str.trim();
while (str.startsWith(" ")) {
str = str.substring(1).trim();
}
while (str.startsWith("&nbsp;")) {
str = str.substring(6).trim();
}
while (str.endsWith(" ")) {
str = str.substring(0, str.length() - 1).trim();
}
while (str.endsWith("&nbsp;")) {
str = str.substring(0, str.length() - 6).trim();
}
return str;
}
public static void main(String[] args){
// TODO Auto-generated method stub
}
}

View File

@ -43,7 +43,7 @@ public class AppTestControl {
/**
* 控制台模式调度计划执行用例
* @param planname
* @param planname 测试计划名称
*/
public static void manualExecutionPlan(String planname) {
// 不记日志到数据库
@ -65,7 +65,7 @@ public class AppTestControl {
}
serverOperation caselog = new serverOperation();
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
List<ProjectCaseParams> pcplist = new ArrayList<>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
@ -84,21 +84,18 @@ public class AppTestControl {
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosCaseExecution.caseExcution(testcase, steps, taskid, iosdriver, caselog, pcplist);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出InterruptedException异常", e);
} catch (IOException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出IOException异常", e);
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出Exception异常", e);
}
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
}
LogUtil.APP.info("当前项目测试计划中的用例已经全部执行完成...");
// 关闭APP以及appium会话
if ("Android".equals(properties.getProperty("platformName"))) {
assert androiddriver != null;
androiddriver.closeApp();
} else if ("IOS".equals(properties.getProperty("platformName"))) {
assert iosdriver != null;
iosdriver.closeApp();
}
}
@ -113,7 +110,7 @@ public class AppTestControl {
Properties properties = AppiumConfig.getConfiguration();
AppiumService as=null;
//根据配置自动启动Appiume服务
if(Boolean.valueOf(properties.getProperty("autoRunAppiumService"))){
if(Boolean.parseBoolean(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
@ -127,7 +124,7 @@ public class AppTestControl {
String jobname = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId()).getSchedulingName();
int[] tastcount = null;
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
if (restartstatus.contains("Status:true")) {
// 判断是否构建是否成功
if (BuildResult.SUCCESS.equals(buildResult)) {
try {
@ -161,22 +158,23 @@ public class AppTestControl {
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosCaseExecution.caseExcution(testcase, steps, taskId, iosdriver, caselog, pcplist);
}
} catch (InterruptedException | IOException e) {
// TODO Auto-generated catch block
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
}
tastcount = serverOperation.updateTaskExecuteData(taskId, cases.size(),2);
String testtime = serverOperation.getTestTime(taskId);
LogUtil.APP.info("当前项目【{]】测试计划中的用例已经全部执行完成...",projectname);
LogUtil.APP.info("当前项目【{}】测试计划中的用例已经全部执行完成...",projectname);
MailSendInitialization.sendMailInitialization(HtmlMail.htmlSubjectFormat(jobname),
HtmlMail.htmlContentFormat(tastcount, taskId, buildResult.toString(), restartstatus, testtime, jobname),
taskId, taskScheduling, tastcount);
// 关闭APP以及appium会话
if ("Android".equals(properties.getProperty("platformName"))) {
assert androiddriver != null;
androiddriver.closeApp();
} else if ("IOS".equals(properties.getProperty("platformName"))) {
assert iosdriver != null;
iosdriver.closeApp();
}
} else {

View File

@ -1,108 +1,110 @@
package luckyclient.execution.appium;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class AppiumInitialization {
/**
* 初始化AndroidAppium
*
* @throws IOException
*/
public static AndroidDriver<AndroidElement> setAndroidAppium(Properties properties) throws IOException {
AndroidDriver<AndroidElement> appium = null;
DesiredCapabilities capabilities = new DesiredCapabilities();
File directory = new File("");
File app = new File(directory.getCanonicalPath() + File.separator + properties.getProperty("appname"));
capabilities.setCapability("app", app.getAbsolutePath());
// 自动化测试服务
capabilities.setCapability("automationName", properties.getProperty("automationName"));
// 设备名称
capabilities.setCapability("deviceName", properties.getProperty("deviceName"));
// 平台类型
capabilities.setCapability("platformName", properties.getProperty("platformName"));
// 系统版本
capabilities.setCapability("platformVersion", properties.getProperty("platformVersion"));
// 模拟器上的ip地址
capabilities.setCapability("udid", properties.getProperty("udid"));
// Android应用的包名
capabilities.setCapability("appPackage", properties.getProperty("appPackage"));
// 启动的Android Activity
capabilities.setCapability("appActivity", properties.getProperty("appActivity"));
// 支持中文输入会自动安装Unicode输入
capabilities.setCapability("unicodeKeyboard", Boolean.valueOf(properties.getProperty("unicodeKeyboard")));
// 重置输入法到原有状态
capabilities.setCapability("resetKeyboard", Boolean.valueOf(properties.getProperty("resetKeyboard")));
// 不重新签名apk
capabilities.setCapability("noSign", Boolean.valueOf(properties.getProperty("noSign")));
// 是否避免重新安装APP
capabilities.setCapability("noReset", Boolean.valueOf(properties.getProperty("noReset")));
// 等待超时没接收到命令关闭appium
capabilities.setCapability("newCommandTimeout", properties.getProperty("newCommandTimeout"));
String url="http://" + properties.getProperty("appiumsever") + "/wd/hub";
appium = new AndroidDriver<AndroidElement>(new URL(url), capabilities);
int waittime = Integer.valueOf(properties.getProperty("implicitlyWait"));
appium.manage().timeouts().implicitlyWait(waittime, TimeUnit.SECONDS);
return appium;
}
/**
* 初始化IOSAppium
*
* @throws IOException
*/
public static IOSDriver<IOSElement> setIosAppium(Properties properties) throws IOException {
IOSDriver<IOSElement> appium = null;
DesiredCapabilities capabilities = new DesiredCapabilities();
File directory = new File("");
File app = new File(directory.getCanonicalPath() + File.separator + properties.getProperty("appname"));
capabilities.setCapability("app", app.getAbsolutePath());
// 自动化测试服务
capabilities.setCapability("automationName", properties.getProperty("automationName"));
// 设备名称
capabilities.setCapability("deviceName", properties.getProperty("deviceName"));
// 平台类型
capabilities.setCapability("platformName", properties.getProperty("platformName"));
// 系统版本
capabilities.setCapability("platformVersion", properties.getProperty("platformVersion"));
// 模拟器上的ip地址
capabilities.setCapability("udid", properties.getProperty("udid"));
// 支持中文输入会自动安装Unicode输入
capabilities.setCapability("unicodeKeyboard", Boolean.valueOf(properties.getProperty("unicodeKeyboard")));
// 重置输入法到原有状态
capabilities.setCapability("resetKeyboard", Boolean.valueOf(properties.getProperty("resetKeyboard")));
// 不重新签名apk
capabilities.setCapability("noSign", Boolean.valueOf(properties.getProperty("noSign")));
// 是否避免重新安装APP
capabilities.setCapability("noReset", Boolean.valueOf(properties.getProperty("noReset")));
// 等待超时没接收到命令关闭appium
capabilities.setCapability("newCommandTimeout", properties.getProperty("newCommandTimeout"));
String url="http://" + properties.getProperty("appiumsever") + "/wd/hub";
appium = new IOSDriver<IOSElement>(new URL(url),capabilities);
int waittime = Integer.valueOf(properties.getProperty("implicitlyWait"));
appium.manage().timeouts().implicitlyWait(waittime, TimeUnit.SECONDS);
return appium;
}
}
package luckyclient.execution.appium;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class AppiumInitialization {
/**
* 初始化AndroidAppium
* @param properties 配置文件对象
* @return 返回安卓appium对象
* @throws IOException 抛异常
*/
public static AndroidDriver<AndroidElement> setAndroidAppium(Properties properties) throws IOException {
AndroidDriver<AndroidElement> appium;
DesiredCapabilities capabilities = new DesiredCapabilities();
File directory = new File("");
File app = new File(directory.getCanonicalPath() + File.separator + properties.getProperty("appname"));
capabilities.setCapability("app", app.getAbsolutePath());
// 自动化测试服务
capabilities.setCapability("automationName", properties.getProperty("automationName"));
// 设备名称
capabilities.setCapability("deviceName", properties.getProperty("deviceName"));
// 平台类型
capabilities.setCapability("platformName", properties.getProperty("platformName"));
// 系统版本
capabilities.setCapability("platformVersion", properties.getProperty("platformVersion"));
// 模拟器上的ip地址
capabilities.setCapability("udid", properties.getProperty("udid"));
// Android应用的包名
capabilities.setCapability("appPackage", properties.getProperty("appPackage"));
// 启动的Android Activity
capabilities.setCapability("appActivity", properties.getProperty("appActivity"));
// 支持中文输入会自动安装Unicode输入
capabilities.setCapability("unicodeKeyboard", Boolean.valueOf(properties.getProperty("unicodeKeyboard")));
// 重置输入法到原有状态
capabilities.setCapability("resetKeyboard", Boolean.valueOf(properties.getProperty("resetKeyboard")));
// 不重新签名apk
capabilities.setCapability("noSign", Boolean.valueOf(properties.getProperty("noSign")));
// 是否避免重新安装APP
capabilities.setCapability("noReset", Boolean.valueOf(properties.getProperty("noReset")));
// 等待超时没接收到命令关闭appium
capabilities.setCapability("newCommandTimeout", properties.getProperty("newCommandTimeout"));
String url="http://" + properties.getProperty("appiumsever") + "/wd/hub";
appium = new AndroidDriver<>(new URL(url), capabilities);
int waittime = Integer.parseInt(properties.getProperty("implicitlyWait"));
appium.manage().timeouts().implicitlyWait(waittime, TimeUnit.SECONDS);
return appium;
}
/**
* 初始化IOSAppium
* @param properties 配置文件对象
* @return 返回IOS appium对象
* @throws IOException 抛出IO异常
*/
public static IOSDriver<IOSElement> setIosAppium(Properties properties) throws IOException {
IOSDriver<IOSElement> appium;
DesiredCapabilities capabilities = new DesiredCapabilities();
File directory = new File("");
File app = new File(directory.getCanonicalPath() + File.separator + properties.getProperty("appname"));
capabilities.setCapability("app", app.getAbsolutePath());
// 自动化测试服务
capabilities.setCapability("automationName", properties.getProperty("automationName"));
// 设备名称
capabilities.setCapability("deviceName", properties.getProperty("deviceName"));
// 平台类型
capabilities.setCapability("platformName", properties.getProperty("platformName"));
// 系统版本
capabilities.setCapability("platformVersion", properties.getProperty("platformVersion"));
// 模拟器上的ip地址
capabilities.setCapability("udid", properties.getProperty("udid"));
// 支持中文输入会自动安装Unicode输入
capabilities.setCapability("unicodeKeyboard", Boolean.valueOf(properties.getProperty("unicodeKeyboard")));
// 重置输入法到原有状态
capabilities.setCapability("resetKeyboard", Boolean.valueOf(properties.getProperty("resetKeyboard")));
// 不重新签名apk
capabilities.setCapability("noSign", Boolean.valueOf(properties.getProperty("noSign")));
// 是否避免重新安装APP
capabilities.setCapability("noReset", Boolean.valueOf(properties.getProperty("noReset")));
// 等待超时没接收到命令关闭appium
capabilities.setCapability("newCommandTimeout", properties.getProperty("newCommandTimeout"));
String url="http://" + properties.getProperty("appiumsever") + "/wd/hub";
appium = new IOSDriver<>(new URL(url), capabilities);
int waittime = Integer.parseInt(properties.getProperty("implicitlyWait"));
appium.manage().timeouts().implicitlyWait(waittime, TimeUnit.SECONDS);
return appium;
}
}

View File

@ -1,48 +1,48 @@
package luckyclient.execution.appium;
import java.io.File;
import java.util.Properties;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
import io.appium.java_client.service.local.flags.GeneralServerFlag;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年8月8日
*/
public class AppiumService extends Thread{
@Override
public void run(){
try{
Properties properties = AppiumConfig.getConfiguration();
File mainjsFile = new File(properties.getProperty("mainjsPath"));
String ip=properties.getProperty("appiumsever");
AppiumServiceBuilder builder =
new AppiumServiceBuilder().withArgument(GeneralServerFlag.SESSION_OVERRIDE)
.withIPAddress(ip.split(":")[0].trim())
.withAppiumJS(mainjsFile)
.usingPort(Integer.valueOf(ip.split(":")[1].trim()));
AppiumDriverLocalService service = AppiumDriverLocalService.buildService(builder);
service.start();
if (service == null || !service.isRunning()){
LogUtil.APP.warn("自动启动Appium服务失败请检查");
}else{
LogUtil.APP.info("自动启动Appium服务成功监听IP:{} 监听端口:{}",ip.split(":")[0].trim(),ip.split(":")[1].trim());
}
}catch(Exception e){
LogUtil.APP.error("自动启动Appium服务抛出异常请检查",e);
}
}
}
package luckyclient.execution.appium;
import java.io.File;
import java.util.Properties;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
import io.appium.java_client.service.local.flags.GeneralServerFlag;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年8月8日
*/
public class AppiumService extends Thread{
@Override
public void run(){
try{
Properties properties = AppiumConfig.getConfiguration();
File mainjsFile = new File(properties.getProperty("mainjsPath"));
String ip=properties.getProperty("appiumsever");
AppiumServiceBuilder builder =
new AppiumServiceBuilder().withArgument(GeneralServerFlag.SESSION_OVERRIDE)
.withIPAddress(ip.split(":")[0].trim())
.withAppiumJS(mainjsFile)
.usingPort(Integer.parseInt(ip.split(":")[1].trim()));
AppiumDriverLocalService service = AppiumDriverLocalService.buildService(builder);
service.start();
if (!service.isRunning()){
LogUtil.APP.warn("自动启动Appium服务失败请检查");
}else{
LogUtil.APP.info("自动启动Appium服务成功监听IP:{} 监听端口:{}",ip.split(":")[0].trim(),ip.split(":")[1].trim());
}
}catch(Exception e){
LogUtil.APP.error("自动启动Appium服务抛出异常请检查",e);
}
}
}

View File

@ -1,73 +1,73 @@
package luckyclient.execution.appium;
import java.util.List;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.androidex.AndroidCaseExecution;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class CaseLocalDebug{
/**
* 单个移动端用例调试
* @param appium
* @param testCaseExternalId
* @author Seagull
* @date 2020年1月20日
*/
public static void oneCasedebug(AndroidDriver<AndroidElement> appium,String testCaseExternalId){
//不记录日志到数据库
serverOperation.exetype = 1;
serverOperation caselog = new serverOperation();
try {
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist=GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
LogUtil.APP.info("开始执行用例:【{}】......",testCaseExternalId);
List<ProjectCaseSteps> steps=GetServerApi.getStepsbycaseid(testcase.getCaseId());
AndroidCaseExecution.caseExcution(testcase, steps, "888888", appium, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
//退出
appium.quit();
}
/**
* 多个移动端用例调试
* @param appium
* @param projectname
* @param addtestcase
* @author Seagull
* @date 2020年1月20日
*/
public static void moreCaseDebug(AndroidDriver<AndroidElement> appium,String projectname,List<String> addtestcase){
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try{
LogUtil.APP.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(appium,testCaseExternalId);
}catch(Exception e){
continue;
}
}
}
}
package luckyclient.execution.appium;
import java.util.List;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.androidex.AndroidCaseExecution;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class CaseLocalDebug{
/**
* 单个移动端用例调试
* @param appium appium初始化对象
* @param testCaseExternalId 用例编号
* @author Seagull
* @date 2020年1月20日
*/
public static void oneCasedebug(AndroidDriver<AndroidElement> appium,String testCaseExternalId){
//不记录日志到数据库
serverOperation.exetype = 1;
serverOperation caselog = new serverOperation();
try {
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist=GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
LogUtil.APP.info("开始执行用例:【{}】......",testCaseExternalId);
List<ProjectCaseSteps> steps=GetServerApi.getStepsbycaseid(testcase.getCaseId());
AndroidCaseExecution.caseExcution(testcase, steps, "888888", appium, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
//退出
appium.quit();
}
/**
* 多个移动端用例调试
* @param appium appium对象
* @param projectname 项目名
* @param addtestcase 用例对象集
* @author Seagull
* @date 2020年1月20日
*/
public static void moreCaseDebug(AndroidDriver<AndroidElement> appium,String projectname,List<String> addtestcase){
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try{
LogUtil.APP.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(appium,testCaseExternalId);
}catch(Exception e){
LogUtil.APP.info("运行用例 出现异常,用例编号:{}",testCaseExternalId);
}
}
}
}

View File

@ -23,20 +23,15 @@ import luckyclient.utils.LogUtil;
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class AndroidBaseAppium {
/**
* 安卓手机报错截图
*
* @param appium
* @param imagname
* @throws IOException
* @param appium appium初始化对象
* @param imagname 截图名称
*/
public static void screenShot(AndroidDriver<AndroidElement> appium, String imagname) {
imagname = imagname + ".png";
@ -64,33 +59,31 @@ public class AndroidBaseAppium {
/**
* appium不支持中文输入 参考了robotium的以js方式为元素直接设置value的做法
* 利用Selenium中Webdriver执行js方法实现中文输入
* @param appium
* @param preferences
* @param value
* @param appium appium初始化对象
* @param preferences 对象名称
* @param value 传入值
*/
public static void sendChinese(AndroidDriver<AndroidElement> appium, String preferences, String value) {
org.openqa.selenium.JavascriptExecutor jse = (org.openqa.selenium.JavascriptExecutor) appium;
jse.executeScript("document.getElementByName('" + preferences + "').value='" + value + "'");
((JavascriptExecutor) appium).executeScript("document.getElementByName('" + preferences + "').value='" + value + "'");
}
/**
* js webview 支持4.14.4
* @param appium
* @param sX
* @param sY
* @param eX
* @param eY
* @param duration
* @throws Exception
* js webview 支持4.14.4 页面滑动
* @param appium appium初始化对象
* @param sX 开始X坐标
* @param sY 开始Y坐标
* @param eX 结束X坐标
* @param eY 结束Y坐标
* @param duration 持续时间
*/
public static void webViewSwipe(AndroidDriver<AndroidElement> appium, Double sX, Double sY, Double eX, Double eY,
Double duration) throws Exception {
Double duration) {
JavascriptExecutor js;
HashMap<String, Double> swipeObject;
try {
// 滑动
js = (JavascriptExecutor) appium;
swipeObject = new HashMap<String, Double>(5);
js = appium;
swipeObject = new HashMap<>(5);
swipeObject.put("startX", sX);
swipeObject.put("startY", sY);
swipeObject.put("endX", eX);
@ -100,23 +93,18 @@ public class AndroidBaseAppium {
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("安卓手机滑动出现异常",e);
} finally {
// 释放变量
}
}
/**
* 调用 ADB直接滑动 支持4.14.4
* @param appium
* @param sX
* @param sY
* @param eX
* @param eY
* @throws Exception
* @param appium appium初始化对象
* @param sX 开始X坐标
* @param sY 开始Y坐标
* @param eX 结束X坐标
* @param eY 结束Y坐标
*/
public static void adbSwipe(AndroidDriver<AndroidElement> appium, Double sX, Double sY, Double eX, Double eY)
throws Exception {
public static void adbSwipe(AndroidDriver<AndroidElement> appium, Double sX, Double sY, Double eX, Double eY) {
int xLine;
int yLine;
int sX2;
@ -138,36 +126,30 @@ public class AndroidBaseAppium {
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("安卓手机调用 ADB直接滑动出现异常",e);
} finally {
// 释放变量
}
}
/**
* 屏幕点击事件
* @param drivers
* @param x
* @param y
* @param duration
* @param drivers appium初始化对象
* @param x 点击X坐标
* @param y 点击Y坐标
* @param duration 持续时间
*/
public static void clickScreenForJs(AndroidDriver<AndroidElement> drivers, int x, int y, int duration) {
JavascriptExecutor js = (JavascriptExecutor) drivers;
HashMap<String, Integer> tapObject = new HashMap<String, Integer>(3);
HashMap<String, Integer> tapObject = new HashMap<>(3);
tapObject.put("x", x);
tapObject.put("y", y);
tapObject.put("duration", duration);
js.executeScript("mobile: tap", tapObject);
((JavascriptExecutor) drivers).executeScript("mobile: tap", tapObject);
}
/**
* 拖住页面按屏幕比例向上滑动(手指向下页面向上)
*
* @param driver
* @param second
* 持续时间
* @param num
* 滚动次数
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滚动次数
*/
public static void swipePageUp(AndroidDriver<AndroidElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
@ -184,10 +166,9 @@ public class AndroidBaseAppium {
/**
* 拖住页面按屏幕比例向下滑动(手指向上页面向下)
*
* @param driver
* @param second
* @param num
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滑动次数
*/
public static void swipePageDown(AndroidDriver<AndroidElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
@ -203,10 +184,9 @@ public class AndroidBaseAppium {
/**
* 拖住页面按屏幕比例向左滑动(手指向左页面向左滚动)
*
* @param driver
* @param second
* @param num
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滑动次数
*/
public static void swipePageLeft(AndroidDriver<AndroidElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
@ -222,10 +202,9 @@ public class AndroidBaseAppium {
/**
* 拖住页面按屏幕比例向右滑动(手指向右页面向右)
*
* @param driver
* @param second
* @param num
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滑动次数
*/
public static void swipePageRight(AndroidDriver<AndroidElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);

View File

@ -1,97 +1,95 @@
package luckyclient.execution.appium.androidex;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2018年1月26日 上午15:29:40
*
*/
public class AndroidBatchExecute {
public static void batchCaseExecuteForTast(String projectname, String taskid, String batchcase) throws IOException, InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
AndroidDriver<AndroidElement> ad = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.valueOf(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
ad = AppiumInitialization.setAndroidAppium(properties);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("安卓手机根据配置自动启动Appiume服务出现异常",e);
}
serverOperation caselog = new serverOperation();
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.valueOf(taskid));
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(task.getProjectId().toString());
// 执行全部非成功状态用例
if (batchcase.indexOf("ALLFAIL") > -1) {
List<Integer> caseIdList = caselog.getCaseListForUnSucByTaskId(taskid);
for (int i = 0; i < caseIdList.size(); i++) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseIdList.get(i));
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
AndroidCaseExecution.caseExcution(testcase, steps, taskid, ad, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
} else { // 批量执行用例
String[] temp = batchcase.split("\\#");
for (int i = 0; i < temp.length; i++) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(Integer.valueOf(temp[i]));
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
AndroidCaseExecution.caseExcution(testcase, steps, taskid, ad, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
ad.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}
package luckyclient.execution.appium.androidex;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2018年1月26日 上午15:29:40
*
*/
public class AndroidBatchExecute {
public static void batchCaseExecuteForTast(String taskid, String batchcase) throws IOException, InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
AndroidDriver<AndroidElement> ad = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.parseBoolean(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
ad = AppiumInitialization.setAndroidAppium(properties);
} catch (MalformedURLException e) {
LogUtil.APP.error("安卓手机根据配置自动启动Appiume服务出现异常",e);
}
serverOperation caselog = new serverOperation();
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(task.getProjectId().toString());
// 执行全部非成功状态用例
if (batchcase.contains("ALLFAIL")) {
List<Integer> caseIdList = caselog.getCaseListForUnSucByTaskId(taskid);
for (Integer integer : caseIdList) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(integer);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
AndroidCaseExecution.caseExcution(testcase, steps, taskid, ad, caselog, pcplist);
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
} else { // 批量执行用例
String[] temp = batchcase.split("#");
for (String s : temp) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(Integer.valueOf(s));
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
AndroidCaseExecution.caseExcution(testcase, steps, taskid, ad, caselog, pcplist);
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
assert ad != null;
ad.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}

View File

@ -1,323 +1,319 @@
package luckyclient.execution.appium.androidex;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.AppDriverAnalyticCase;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ChangString;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年1月21日 上午15:12:48
*/
public class AndroidCaseExecution{
static Map<String, String> variable = new HashMap<String, String>();
private static String casenote = "备注初始化";
private static String imagname = "";
public static void caseExcution(ProjectCase testcase, List<ProjectCaseSteps> steps,String taskid, AndroidDriver<AndroidElement> appium,serverOperation caselog,List<ProjectCaseParams> pcplist)
throws InterruptedException, IOException {
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 0通过 1失败 2锁定 3执行中 4未执行
int setcaseresult = 0;
for (ProjectCaseSteps step : steps) {
Map<String, String> params;
String result;
// 根据步骤类型来分析步骤参数
if (3 == step.getStepType()){
params = AppDriverAnalyticCase.analyticCaseStep(testcase, step, taskid,caselog,variable);
}else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog,variable);
}
if(null != params.get("exception") && params.get("exception").contains("解析异常")){
setcaseresult = 2;
break;
}
// 根据步骤类型来执行步骤
if (3 == step.getStepType()){
result = androidRunStep(params, appium, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
}else{
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.runStep(params, taskid, testcase.getCaseSign(), step, caselog);
}
String expectedResults = params.get("ExpectedResults").toString();
expectedResults=ChangString.changparams(expectedResults, variable,"预期结果");
// 判断结果
int stepresult = judgeResult(testcase, step, params, appium, taskid, expectedResults, result, caselog);
// 失败并且不在继续,直接终止
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","");
}
//LogOperation.UpdateTastdetail(taskid, 0);
}
public static String androidRunStep(Map<String, String> params, AndroidDriver<AndroidElement> appium,String taskid,Integer caseId,int stepno,serverOperation caselog) {
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 {
//调用接口用例
if(null != operation&&null != operationValue&&"runcase".equals(operation)){
String[] temp=operationValue.split(",",-1);
TestCaseExecution testCaseExecution=new TestCaseExecution();
String ex = testCaseExecution.oneCaseExecuteForUICase(temp[0], taskid, caselog, appium);
if(!ex.contains("CallCase调用出错") && !ex.contains("解析出错啦!") && !ex.contains("失败")){
return ex;
}else{
return "步骤执行失败:调用接口用例过程失败";
}
}
AndroidElement ae = null;
// 页面元素层
if (null != property && null != propertyValue) {
ae = isElementExist(appium, property, propertyValue);
// 判断此元素是否存在
if (null==ae) {
LogUtil.APP.warn("定位对象失败isElementExist为null!");
return "步骤执行失败isElementExist定位元素过程失败";
}
if (operation.indexOf("select") > -1) {
result = AndroidEncapsulateOperation.selectOperation(ae, operation, operationValue);
} else if (operation.indexOf("get") > -1){
result = AndroidEncapsulateOperation.getOperation(ae, operation,operationValue);
} else {
result = AndroidEncapsulateOperation.objectOperation(appium, ae, operation, operationValue, property, propertyValue);
}
// Driver层操作
} else if (null==property && null != operation) {
// 处理弹出框事件
if (operation.indexOf("alert") > -1){
result = AndroidEncapsulateOperation.alertOperation(appium, operation);
}else{
result = AndroidEncapsulateOperation.driverOperation(appium, operation, operationValue);
}
}else{
LogUtil.APP.warn("元素操作过程失败!");
result = "步骤执行失败:元素操作过程失败!";
}
} catch (Exception e) {
LogUtil.APP.error("元素定位过程或是操作过程失败或异常!",e);
return "步骤执行失败:元素定位过程或是操作过程失败或异常!" + e.getMessage();
}
caselog.insertTaskCaseLog(taskid, caseId, result,"info", String.valueOf(stepno),"");
if(result.indexOf("获取到的值是【")>-1&&result.indexOf("")>-1){
result = result.substring(result.indexOf("获取到的值是【")+7, result.length()-1);
}
return result;
}
public static AndroidElement isElementExist(AndroidDriver<AndroidElement> appium, String property, String propertyValue) {
try {
AndroidElement ae = null;
property=property.toLowerCase();
// 处理WebElement对象定位
switch (property) {
case "id":
ae = appium.findElementById(propertyValue);
break;
case "name":
ae = appium.findElementByAndroidUIAutomator("text(\""+propertyValue+"\")");
break;
case "androiduiautomator":
ae = appium.findElementByAndroidUIAutomator(propertyValue);
break;
case "xpath":
ae = appium.findElementByXPath(propertyValue);
break;
case "linktext":
ae = appium.findElementByLinkText(propertyValue);
break;
case "tagname":
ae = appium.findElementByTagName(propertyValue);
break;
case "cssselector":
ae = appium.findElementByCssSelector(propertyValue);
break;
case "classname":
ae = appium.findElementByClassName(propertyValue);
break;
case "partiallinktext":
ae = appium.findElementByPartialLinkText(propertyValue);
break;
default:
break;
}
return ae;
} catch (Exception e) {
LogUtil.APP.error("当前对象定位失败,出现异常!",e);
return null;
}
}
public static int judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, AndroidDriver<AndroidElement> appium, String taskid, String expect, String result, serverOperation caselog) throws InterruptedException {
int setresult = 0;
java.text.DateFormat timeformat = new java.text.SimpleDateFormat("MMdd-hhmmss");
imagname = timeformat.format(new Date());
result = ActionManageForSteps.actionManage(step.getAction(), result);
if (null != result && !result.contains("步骤执行失败:")) {
// 有预期结果
if (null != expect && !expect.isEmpty()) {
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()), "");
}
// 移动端 UI检查模式
else if (3 == step.getStepType() && params.get("checkproperty") != null && params.get("checkproperty_value") != null) {
String checkproperty = params.get("checkproperty");
String checkPropertyValue = params.get("checkproperty_value");
AndroidElement ae = isElementExist(appium, checkproperty, checkPropertyValue);
if (null != ae) {
LogUtil.APP.info("用例:{} 第{}步,在当前页面中找到预期结果中对象。当前步骤执行成功!",testcase.getCaseSign(),step.getStepSerialNumber());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在当前页面中找到预期结果中对象。当前步骤执行成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,没有在当前页面中找到预期结果中对象。执行失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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() + "步,模糊匹配预期结果失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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() + "步,正则匹配预期结果失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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 {
casenote = "" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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 : "";
setresult = 2;
AndroidBaseAppium.screenShot(appium, imagname);
LogUtil.APP.warn("用例:{} 第{}步,执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),casenote);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "当前步骤在执行过程中解析|定位元素|操作对象失败!" + casenote, "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
return setresult;
}
}
package luckyclient.execution.appium.androidex;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.AppDriverAnalyticCase;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ChangString;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年1月21日 上午15:12:48
*/
public class AndroidCaseExecution{
static Map<String, String> variable = new HashMap<>();
private static String casenote = "备注初始化";
public static void caseExcution(ProjectCase testcase, List<ProjectCaseSteps> steps,String taskid, AndroidDriver<AndroidElement> appium,serverOperation caselog,List<ProjectCaseParams> pcplist) {
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 0通过 1失败 2锁定 3执行中 4未执行
int setcaseresult = 0;
for (ProjectCaseSteps step : steps) {
Map<String, String> params;
String result;
// 根据步骤类型来分析步骤参数
if (3 == step.getStepType()){
params = AppDriverAnalyticCase.analyticCaseStep(testcase, step, taskid,caselog,variable);
}else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog,variable);
}
if(null != params.get("exception") && params.get("exception").contains("解析异常")){
setcaseresult = 2;
break;
}
// 根据步骤类型来执行步骤
if (3 == step.getStepType()){
result = androidRunStep(params, appium, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
}else{
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.runStep(params, taskid, testcase.getCaseSign(), step, caselog);
}
String expectedResults = params.get("ExpectedResults");
expectedResults=ChangString.changparams(expectedResults, variable,"预期结果");
// 判断结果
int stepresult = judgeResult(testcase, step, params, appium, taskid, expectedResults, result, caselog);
// 失败并且不在继续,直接终止
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","");
}
//LogOperation.UpdateTastdetail(taskid, 0);
}
public static String androidRunStep(Map<String, String> params, AndroidDriver<AndroidElement> appium,String taskid,Integer caseId,int stepno,serverOperation caselog) {
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 {
//调用接口用例
if(null != operationValue && "runcase".equals(operation)){
String[] temp=operationValue.split(",",-1);
TestCaseExecution testCaseExecution=new TestCaseExecution();
String ex = testCaseExecution.oneCaseExecuteForUICase(temp[0], taskid, caselog, appium);
if(!ex.contains("CallCase调用出错") && !ex.contains("解析出错啦!") && !ex.contains("失败")){
return ex;
}else{
return "步骤执行失败:调用接口用例过程失败";
}
}
AndroidElement ae;
// 页面元素层
if (null != property && null != propertyValue) {
ae = isElementExist(appium, property, propertyValue);
// 判断此元素是否存在
if (null==ae) {
LogUtil.APP.warn("定位对象失败isElementExist为null!");
return "步骤执行失败isElementExist定位元素过程失败";
}
if (operation.contains("select")) {
result = AndroidEncapsulateOperation.selectOperation(ae, operation, operationValue);
} else if (operation.contains("get")){
result = AndroidEncapsulateOperation.getOperation(ae, operation,operationValue);
} else {
result = AndroidEncapsulateOperation.objectOperation(appium, ae, operation, operationValue, property, propertyValue);
}
// Driver层操作
} else if (null==property && null != operation) {
// 处理弹出框事件
if (operation.contains("alert")){
result = AndroidEncapsulateOperation.alertOperation(appium, operation);
}else{
result = AndroidEncapsulateOperation.driverOperation(appium, operation, operationValue);
}
}else{
LogUtil.APP.warn("元素操作过程失败!");
result = "步骤执行失败:元素操作过程失败!";
}
} catch (Exception e) {
LogUtil.APP.error("元素定位过程或是操作过程失败或异常!",e);
return "步骤执行失败:元素定位过程或是操作过程失败或异常!" + e.getMessage();
}
caselog.insertTaskCaseLog(taskid, caseId, result,"info", String.valueOf(stepno),"");
if(result.contains("获取到的值是【") && result.contains("")){
result = result.substring(result.indexOf("获取到的值是【")+7, result.length()-1);
}
return result;
}
public static AndroidElement isElementExist(AndroidDriver<AndroidElement> appium, String property, String propertyValue) {
try {
AndroidElement ae = null;
property=property.toLowerCase();
// 处理WebElement对象定位
switch (property) {
case "id":
ae = appium.findElementById(propertyValue);
break;
case "name":
ae = appium.findElementByAndroidUIAutomator("text(\""+propertyValue+"\")");
break;
case "androiduiautomator":
ae = appium.findElementByAndroidUIAutomator(propertyValue);
break;
case "xpath":
ae = appium.findElementByXPath(propertyValue);
break;
case "linktext":
ae = appium.findElementByLinkText(propertyValue);
break;
case "tagname":
ae = appium.findElementByTagName(propertyValue);
break;
case "cssselector":
ae = appium.findElementByCssSelector(propertyValue);
break;
case "classname":
ae = appium.findElementByClassName(propertyValue);
break;
case "partiallinktext":
ae = appium.findElementByPartialLinkText(propertyValue);
break;
default:
break;
}
return ae;
} catch (Exception e) {
LogUtil.APP.error("当前对象定位失败,出现异常!",e);
return null;
}
}
public static int judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, AndroidDriver<AndroidElement> appium, String taskid, String expect, String result, serverOperation caselog) {
int setresult = 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()) {
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()), "");
}
// 移动端 UI检查模式
else if (3 == step.getStepType() && params.get("checkproperty") != null && params.get("checkproperty_value") != null) {
String checkproperty = params.get("checkproperty");
String checkPropertyValue = params.get("checkproperty_value");
AndroidElement ae = isElementExist(appium, checkproperty, checkPropertyValue);
if (null != ae) {
LogUtil.APP.info("用例:{} 第{}步,在当前页面中找到预期结果中对象。当前步骤执行成功!",testcase.getCaseSign(),step.getStepSerialNumber());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在当前页面中找到预期结果中对象。当前步骤执行成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,没有在当前页面中找到预期结果中对象。执行失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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() + "步,模糊匹配预期结果失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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() + "步,正则匹配预期结果失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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 {
casenote = "" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
setresult = 1;
AndroidBaseAppium.screenShot(appium, 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 : "";
setresult = 2;
AndroidBaseAppium.screenShot(appium, imagname);
LogUtil.APP.warn("用例:{} 第{}步,执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),casenote);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "当前步骤在执行过程中解析|定位元素|操作对象失败!" + casenote, "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
return setresult;
}
}

View File

@ -1,8 +1,6 @@
package luckyclient.execution.appium.androidex;
import java.io.IOException;
import java.util.List;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.remote.api.GetServerApi;
@ -24,6 +22,11 @@ import luckyclient.utils.LogUtil;
*/
public class AndroidCaseLocalDebug {
/**
* IDEA工具方式调试测试用例
* @param androiddriver 初始化appium对象
* @param testCaseExternalId 用例编号
*/
public static void oneCasedebug(AndroidDriver<AndroidElement> androiddriver, String testCaseExternalId) {
// 不记录日志到数据库
serverOperation.exetype = 1;
@ -45,9 +48,9 @@ public class AndroidCaseLocalDebug {
/**
* 用于做多条用例串行调试
* @param androiddriver
* @param projectname
* @param addtestcase
* @param androiddriver 初始化appium对象
* @param projectname 项目名称
* @param addtestcase 用例集
* @author Seagull
* @date 2019年4月18日
*/
@ -61,7 +64,6 @@ public class AndroidCaseLocalDebug {
oneCasedebug(androiddriver, testCaseExternalId);
} catch (Exception e) {
LogUtil.APP.error("多用例调试过程中抛出异常!", e);
continue;
}
}
// 关闭APP以及appium会话

View File

@ -1,74 +1,75 @@
package luckyclient.execution.appium.androidex;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2018年1月26日 上午9:29:40
*
*/
public class AndroidOneCaseExecute {
public static void oneCaseExecuteForTast(String projectname, Integer caseId, int version, String taskid)
throws IOException, InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
AndroidDriver<AndroidElement> ad = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.valueOf(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
ad = AppiumInitialization.setAndroidAppium(properties);
} catch (IOException e1) {
LogUtil.APP.error("初始化AndroidDriver出错", 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());
AndroidCaseExecution.caseExcution(testcase, steps, taskid, ad, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (InterruptedException e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
ad.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}
package luckyclient.execution.appium.androidex;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2018年1月26日 上午9:29:40
*
*/
public class AndroidOneCaseExecute {
public static void oneCaseExecuteForTast(Integer caseId, String taskid)
throws InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
AndroidDriver<AndroidElement> ad = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.parseBoolean(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
ad = AppiumInitialization.setAndroidAppium(properties);
} catch (IOException e1) {
LogUtil.APP.error("初始化AndroidDriver出错", 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());
AndroidCaseExecution.caseExcution(testcase, steps, taskid, ad, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
assert ad != null;
ad.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}

View File

@ -1,216 +1,220 @@
package luckyclient.execution.appium.iosex;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.remote.Augmenter;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import io.appium.java_client.ios.IOSTouchAction;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年2月2日
*
*/
public class IosBaseAppium {
/**
* @param args
* @throws IOException
* IOS手机报错截图
*/
public static void screenShot(IOSDriver<IOSElement> appium, String imagname){
imagname = imagname + ".png";
String relativelyPath = System.getProperty("user.dir");
String pngpath=relativelyPath +File.separator+ "log"+File.separator+"ScreenShot" +File.separator+ imagname;
try {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("IOS手机报错截图休眠出现异常", e);
}
File imageFile = ((TakesScreenshot) (new Augmenter().augment(appium))).getScreenshotAs(OutputType.FILE);
File screenFile = new File(pngpath);
FileUtils.copyFile(imageFile, screenFile);
imageFile.deleteOnExit();
LogUtil.APP
.info("已对当前界面进行截图操作,可通过用例执行界面的日志明细查看,也可以前往客户端上查看...【{}】",pngpath);
} catch (IOException e) {
LogUtil.APP.error("IOS手机报错截图出现异常", e);
}
}
/**
* @param args
* @throws IOException
* appium不支持中文输入 参考了robotium的以js方式为元素直接设置value的做法
* 利用Selenium中Webdriver执行js方法实现中文输入
*/
public static void sendChinese(IOSDriver<IOSElement> appium, String preferences, String value) {
org.openqa.selenium.JavascriptExecutor jse = (org.openqa.selenium.JavascriptExecutor) appium;
jse.executeScript("document.getElementByName('" + preferences + "').value='" + value + "'");
}
/**
* @param args
* js webview 支持4.14.4
*/
public static void webViewSwipe(IOSDriver<IOSElement> appium, Double sX, Double sY, Double eX, Double eY, Double duration)
throws Exception {
JavascriptExecutor js;
HashMap<String, Double> swipeObject;
try {
// 滑动
js = (JavascriptExecutor) appium;
swipeObject = new HashMap<String, Double>(5);
swipeObject.put("startX", sX);
swipeObject.put("startY", sY);
swipeObject.put("endX", eX);
swipeObject.put("endY", eY);
swipeObject.put("duration", duration);
js.executeScript("mobile: swipe", swipeObject);
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("IOS手机滑动出现异常", e);
} finally {
// 释放变量
}
}
/**
* @param args
* 调用 ADB直接滑动 支持4.14.4
*/
public static void adbSwipe(IOSDriver<IOSElement> appium, Double sX, Double sY, Double eX, Double eY) throws Exception {
int xLine;
int yLine;
int sX2;
int sY2;
int eX2;
int eY2;
try {
// 滑动
xLine = appium.manage().window().getSize().getWidth();
yLine = appium.manage().window().getSize().getHeight();
sX2 = (int) (xLine * sX);
sY2 = (int) (yLine * sY);
eX2 = (int) (xLine * eX);
eY2 = (int) (yLine * eY);
// logger.info("滑动11111111");
Runtime.getRuntime()
.exec("adb -s " + "IOS" + " shell input swipe " + sX2 + " " + sY2 + " " + eX2 + " " + eY2);
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("IOS手机调用 ADB直接滑动出现异常", e);
} finally {
// 释放变量
}
}
/**
* @param args
* 屏幕点击事件
*/
public static void clickScreenForJs(IOSDriver<IOSElement> drivers, int x, int y, int duration) {
JavascriptExecutor js = (JavascriptExecutor) drivers;
HashMap<String, Integer> tapObject = new HashMap<String, Integer>(3);
tapObject.put("x", x);
tapObject.put("y", y);
tapObject.put("duration", duration);
js.executeScript("mobile: tap", tapObject);
}
/**
* 拖住页面按屏幕比例向上滑动(手指向下页面向上)
* @param driver
* @param second 持续时间
* @param num 滚动次数
*/
public static void swipePageUp(IOSDriver<IOSElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(width / 2, 20)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(width / 2, height-20)).release().perform();
}
}
/**
* 拖住页面按屏幕比例向下滑动(手指向上页面向下)
* @param driver
* @param second
* @param num
*/
public static void swipePageDown(IOSDriver<IOSElement> driver,Double second,int num){
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(width / 2, height-20)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(width / 2, 20)).release().perform();
}
}
/**
* 拖住页面按屏幕比例向左滑动(手指向左页面向左滚动)
* @param driver
* @param second
* @param num
*/
public static void swipePageLeft(IOSDriver<IOSElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(width - 10, height / 2)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(10, height / 2)).release().perform();
}
}
/**
* 拖住页面按屏幕比例向右滑动(手指向右页面向右)
* @param driver
* @param second
* @param num
*/
public static void swipePageRight(IOSDriver<IOSElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(10, height / 2)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(width - 10, height / 2)).release().perform();
}
}
}
package luckyclient.execution.appium.iosex;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.remote.Augmenter;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import io.appium.java_client.ios.IOSTouchAction;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年2月2日
*
*/
public class IosBaseAppium {
/**
* IOS手机报错截图
* @param appium appium对象
* @param imagname 截图名称
*/
public static void screenShot(IOSDriver<IOSElement> appium, String imagname){
imagname = imagname + ".png";
String relativelyPath = System.getProperty("user.dir");
String pngpath=relativelyPath +File.separator+ "log"+File.separator+"ScreenShot" +File.separator+ imagname;
try {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("IOS手机报错截图休眠出现异常", e);
}
File imageFile = ((TakesScreenshot) (new Augmenter().augment(appium))).getScreenshotAs(OutputType.FILE);
File screenFile = new File(pngpath);
FileUtils.copyFile(imageFile, screenFile);
imageFile.deleteOnExit();
LogUtil.APP
.info("已对当前界面进行截图操作,可通过用例执行界面的日志明细查看,也可以前往客户端上查看...【{}】",pngpath);
} catch (IOException e) {
LogUtil.APP.error("IOS手机报错截图出现异常", e);
}
}
/**
* appium不支持中文输入 参考了robotium的以js方式为元素直接设置value的做法
* 利用Selenium中Webdriver执行js方法实现中文输入
* @param appium appium对象
* @param preferences 操作对象名称
* @param value 操作值
*/
public static void sendChinese(IOSDriver<IOSElement> appium, String preferences, String value) {
((JavascriptExecutor) appium).executeScript("document.getElementByName('" + preferences + "').value='" + value + "'");
}
/**
* js webview 支持4.14.4 页面滑动
* @param appium appium初始化对象
* @param sX 开始X坐标
* @param sY 开始Y坐标
* @param eX 结束X坐标
* @param eY 结束Y坐标
* @param duration 持续时间
*/
public static void webViewSwipe(IOSDriver<IOSElement> appium, Double sX, Double sY, Double eX, Double eY, Double duration) {
JavascriptExecutor js;
HashMap<String, Double> swipeObject;
try {
// 滑动
js = appium;
swipeObject = new HashMap<>(5);
swipeObject.put("startX", sX);
swipeObject.put("startY", sY);
swipeObject.put("endX", eX);
swipeObject.put("endY", eY);
swipeObject.put("duration", duration);
js.executeScript("mobile: swipe", swipeObject);
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("IOS手机滑动出现异常", e);
}
}
/**
* 调用 ADB直接滑动 支持4.14.4
* @param appium appium初始化对象
* @param sX 开始X坐标
* @param sY 开始Y坐标
* @param eX 结束X坐标
* @param eY 结束Y坐标
*/
public static void adbSwipe(IOSDriver<IOSElement> appium, Double sX, Double sY, Double eX, Double eY) {
int xLine;
int yLine;
int sX2;
int sY2;
int eX2;
int eY2;
try {
// 滑动
xLine = appium.manage().window().getSize().getWidth();
yLine = appium.manage().window().getSize().getHeight();
sX2 = (int) (xLine * sX);
sY2 = (int) (yLine * sY);
eX2 = (int) (xLine * eX);
eY2 = (int) (yLine * eY);
// logger.info("滑动11111111");
Runtime.getRuntime()
.exec("adb -s " + "IOS" + " shell input swipe " + sX2 + " " + sY2 + " " + eX2 + " " + eY2);
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("IOS手机调用 ADB直接滑动出现异常", e);
}
}
/**
* 屏幕点击事件
* @param drivers appium初始化对象
* @param x 点击X坐标
* @param y 点击Y坐标
* @param duration 持续时间
*/
public static void clickScreenForJs(IOSDriver<IOSElement> drivers, int x, int y, int duration) {
HashMap<String, Integer> tapObject = new HashMap<>(3);
tapObject.put("x", x);
tapObject.put("y", y);
tapObject.put("duration", duration);
((JavascriptExecutor) drivers).executeScript("mobile: tap", tapObject);
}
/**
* 拖住页面按屏幕比例向上滑动(手指向下页面向上)
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滚动次数
*/
public static void swipePageUp(IOSDriver<IOSElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(width / 2, 20)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(width / 2, height-20)).release().perform();
}
}
/**
* 拖住页面按屏幕比例向下滑动(手指向上页面向下)
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滑动次数
*/
public static void swipePageDown(IOSDriver<IOSElement> driver,Double second,int num){
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(width / 2, height-20)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(width / 2, 20)).release().perform();
}
}
/**
* 拖住页面按屏幕比例向左滑动(手指向左页面向左滚动)
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滑动次数
*/
public static void swipePageLeft(IOSDriver<IOSElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(width - 10, height / 2)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(10, height / 2)).release().perform();
}
}
/**
* 拖住页面按屏幕比例向右滑动(手指向右页面向右)
* @param driver appium初始化对象
* @param second 持续时间
* @param num 滑动次数
*/
public static void swipePageRight(IOSDriver<IOSElement> driver, Double second, int num) {
int nanos = (int) (second * 1000);
Duration duration = Duration.ofNanos(nanos);
int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
IOSTouchAction action = new IOSTouchAction(driver);
for (int i = 0; i <= num; i++) {
action.press(PointOption.point(10, height / 2)).waitAction(WaitOptions.waitOptions(duration))
.moveTo(PointOption.point(width - 10, height / 2)).release().perform();
}
}
}

View File

@ -1,95 +1,95 @@
package luckyclient.execution.appium.iosex;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年2月2日
*
*/
public class IosBatchExecute {
public static void batchCaseExecuteForTast(String projectname, String taskid, String batchcase) throws IOException, InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
IOSDriver<IOSElement> iosd = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.valueOf(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
iosd = AppiumInitialization.setIosAppium(properties);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("根据配置自动启动Appiume服务中抛出异常", e);
}
serverOperation caselog = new serverOperation();
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.valueOf(taskid));
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(task.getProjectId().toString());
// 执行全部非成功状态用例
if (batchcase.indexOf("ALLFAIL") > -1) {
List<Integer> caseIdList = caselog.getCaseListForUnSucByTaskId(taskid);
for (int i = 0; i < caseIdList.size(); i++) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseIdList.get(i));
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
IosCaseExecution.caseExcution(testcase, steps, taskid, iosd, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
} else { // 批量执行用例
String[] temp = batchcase.split("\\#");
for (int i = 0; i < temp.length; i++) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(Integer.valueOf(temp[i]));
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
IosCaseExecution.caseExcution(testcase, steps, taskid, iosd, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
iosd.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}
package luckyclient.execution.appium.iosex;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年2月2日
*
*/
public class IosBatchExecute {
public static void batchCaseExecuteForTast(String taskid, String batchcase) throws IOException, InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
IOSDriver<IOSElement> iosd = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.parseBoolean(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
iosd = AppiumInitialization.setIosAppium(properties);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("根据配置自动启动Appiume服务中抛出异常", e);
}
serverOperation caselog = new serverOperation();
TaskExecute task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(task.getProjectId().toString());
// 执行全部非成功状态用例
if (batchcase.contains("ALLFAIL")) {
List<Integer> caseIdList = caselog.getCaseListForUnSucByTaskId(taskid);
for (Integer integer : caseIdList) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(integer);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
IosCaseExecution.caseExcution(testcase, steps, taskid, iosd, caselog, pcplist);
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
} else { // 批量执行用例
String[] temp = batchcase.split("#");
for (String s : temp) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(Integer.valueOf(s));
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
IosCaseExecution.caseExcution(testcase, steps, taskid, iosd, caselog, pcplist);
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
assert iosd != null;
iosd.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}

View File

@ -1,334 +1,332 @@
package luckyclient.execution.appium.iosex;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.execution.appium.AppDriverAnalyticCase;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ChangString;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年1月21日 上午15:12:48
*/
public class IosCaseExecution{
static Map<String, String> variable = new HashMap<String, String>();
private static String casenote = "备注初始化";
private static String imagname = "";
public static void caseExcution(ProjectCase testcase, List<ProjectCaseSteps> steps,String taskid, IOSDriver<IOSElement> appium,serverOperation caselog,List<ProjectCaseParams> pcplist)
throws InterruptedException, IOException {
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 0:成功 1:失败 2:锁定 其他锁定
int setcaseresult = 0;
for (ProjectCaseSteps step : steps) {
Map<String, String> params;
String result;
// 根据步骤类型来分析步骤参数
if (3 == step.getStepType()){
params = AppDriverAnalyticCase.analyticCaseStep(testcase, step, taskid,caselog,variable);
}else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog,variable);
}
if(null != params.get("exception") && params.get("exception").contains("解析异常")){
setcaseresult = 2;
break;
}
// 根据步骤类型来执行步骤
if (3 == step.getStepType()){
result = iosRunStep(params, variable, appium, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
}else{
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.runStep(params, taskid, testcase.getCaseSign(), step, caselog);
}
String expectedResults = params.get("ExpectedResults").toString();
expectedResults=ChangString.changparams(expectedResults, variable,"预期结果");
// 判断结果
int stepresult = judgeResult(testcase, step, params, appium, taskid, expectedResults, result, caselog);
// 失败并且不在继续,直接终止
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","");
}
//LogOperation.UpdateTastdetail(taskid, 0);
}
public static String iosRunStep(Map<String, String> params, Map<String, String> variable, IOSDriver<IOSElement> appium,String taskid,Integer caseId,int stepno,serverOperation caselog) {
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");
// 处理值传递
property = ChangString.changparams(property, variable,"定位方式");
propertyValue=ChangString.changparams(propertyValue, variable,"定位路径");
operation=ChangString.changparams(operation, variable,"操作");
operationValue=ChangString.changparams(operationValue, variable,"操作参数");
LogUtil.APP.info("二次解析用例过程完成,等待进行对象操作......");
caselog.insertTaskCaseLog(taskid, caseId, "对象操作:"+operation+"; 操作值:"+operationValue,"info", String.valueOf(stepno),"");
} catch (Exception e) {
LogUtil.APP.error("二次解析用例过程抛出异常!",e);
return "步骤执行失败:解析用例失败!";
}
try {
//调用接口用例
if(null != operation&&null != operationValue&&"runcase".equals(operation)){
String[] temp=operationValue.split(",",-1);
TestCaseExecution testCaseExecution=new TestCaseExecution();
String ex = testCaseExecution.oneCaseExecuteForUICase(temp[0], taskid, caselog, appium);
if(ex.indexOf("CallCase调用出错")<=-1&&ex.indexOf("解析出错啦!")<=-1&&ex.indexOf("匹配失败")<=-1){
return ex;
}else{
return "步骤执行失败:调用接口用例过程失败";
}
}
IOSElement ae = null;
// 页面元素层
if (null != property && null != propertyValue) {
ae = isElementExist(appium, property, propertyValue);
// 判断此元素是否存在
if (null==ae) {
LogUtil.APP.warn("定位对象失败isElementExist为null!");
return "步骤执行失败isElementExist定位元素过程失败";
}
if (operation.indexOf("select") > -1) {
result = IosEncapsulateOperation.selectOperation(ae, operation, operationValue);
} else if (operation.indexOf("get") > -1){
result = IosEncapsulateOperation.getOperation(ae, operation,operationValue);
} else {
result = IosEncapsulateOperation.objectOperation(appium, ae, operation, operationValue, property, propertyValue);
}
// Driver层操作
} else if (null==property && null != operation) {
// 处理弹出框事件
if (operation.indexOf("alert") > -1){
result = IosEncapsulateOperation.alertOperation(appium, operation);
}else{
result = IosEncapsulateOperation.driverOperation(appium, operation, operationValue);
}
}else{
LogUtil.APP.warn("元素操作过程失败!");
result = "步骤执行失败:元素操作过程失败!";
}
} catch (Exception e) {
LogUtil.APP.error("元素定位过程或是操作过程失败或异常!",e);
return "步骤执行失败:元素定位过程或是操作过程失败或异常!" + e.getMessage();
}
caselog.insertTaskCaseLog(taskid, caseId, result,"info", String.valueOf(stepno),"");
if(result.indexOf("获取到的值是【")>-1&&result.indexOf("")>-1){
result = result.substring(result.indexOf("获取到的值是【")+7, result.length()-1);
}
return result;
}
public static IOSElement isElementExist(IOSDriver<IOSElement> appium, String property, String propertyValue) {
try {
IOSElement ae = null;
property=property.toLowerCase();
// 处理WebElement对象定位
switch (property) {
case "id":
ae = appium.findElementById(propertyValue);
break;
case "name":
ae = appium.findElementByName(propertyValue);
break;
case "xpath":
ae = appium.findElementByXPath(propertyValue);
break;
case "linktext":
ae = appium.findElementByLinkText(propertyValue);
break;
case "tagname":
ae = appium.findElementByTagName(propertyValue);
break;
case "cssselector":
ae = appium.findElementByCssSelector(propertyValue);
break;
case "classname":
ae = appium.findElementByClassName(propertyValue);
break;
case "accessibilityid":
ae = appium.findElementByAccessibilityId(propertyValue);
break;
case "iosclasschain":
ae = appium.findElementByIosClassChain(propertyValue);
break;
case "iosnspredicate":
ae = appium.findElementByIosNsPredicate(propertyValue);
break;
default:
break;
}
return ae;
} catch (Exception e) {
LogUtil.APP.error("当前对象定位失败!",e);
return null;
}
}
public static int judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, IOSDriver<IOSElement> appium, String taskid, String expect, String result, serverOperation caselog) throws InterruptedException {
int setresult = 0;
java.text.DateFormat timeformat = new java.text.SimpleDateFormat("MMdd-hhmmss");
imagname = timeformat.format(new Date());
result = ActionManageForSteps.actionManage(step.getAction(), result);
if (null != result && !result.contains("步骤执行失败:")) {
// 有预期结果
if (null != expect && !expect.isEmpty()) {
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()), "");
}
// 移动端 UI检查模式
else if (3 == step.getStepType() && params.get("checkproperty") != null && params.get("checkproperty_value") != null) {
String checkproperty = params.get("checkproperty");
String checkPropertyValue = params.get("checkproperty_value");
IOSElement ae = isElementExist(appium, checkproperty, checkPropertyValue);
if (null != ae) {
LogUtil.APP.info("用例:{} 第{}步,在当前页面中找到预期结果中对象。当前步骤执行成功!",testcase.getCaseSign(),step.getStepSerialNumber());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在当前页面中找到预期结果中对象。当前步骤执行成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,没有在当前页面中找到预期结果中对象。执行失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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() + "步,模糊匹配预期结果失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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() + "步,正则匹配预期结果失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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 {
casenote = "" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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 : "";
setresult = 2;
IosBaseAppium.screenShot(appium, imagname);
LogUtil.APP.warn("用例:{} 第{}步,执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),casenote);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "当前步骤在执行过程中解析|定位元素|操作对象失败!" + casenote, "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
return setresult;
}
}
package luckyclient.execution.appium.iosex;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.execution.appium.AppDriverAnalyticCase;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ChangString;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年1月21日 上午15:12:48
*/
public class IosCaseExecution{
static Map<String, String> variable = new HashMap<>();
private static String casenote = "备注初始化";
public static void caseExcution(ProjectCase testcase, List<ProjectCaseSteps> steps,String taskid, IOSDriver<IOSElement> appium,serverOperation caselog,List<ProjectCaseParams> pcplist) {
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 0:成功 1:失败 2:锁定 其他锁定
int setcaseresult = 0;
for (ProjectCaseSteps step : steps) {
Map<String, String> params;
String result;
// 根据步骤类型来分析步骤参数
if (3 == step.getStepType()){
params = AppDriverAnalyticCase.analyticCaseStep(testcase, step, taskid,caselog,variable);
}else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog,variable);
}
if(null != params.get("exception") && params.get("exception").contains("解析异常")){
setcaseresult = 2;
break;
}
// 根据步骤类型来执行步骤
if (3 == step.getStepType()){
result = iosRunStep(params, variable, appium, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
}else{
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.runStep(params, taskid, testcase.getCaseSign(), step, caselog);
}
String expectedResults = params.get("ExpectedResults");
expectedResults=ChangString.changparams(expectedResults, variable,"预期结果");
// 判断结果
int stepresult = judgeResult(testcase, step, params, appium, taskid, expectedResults, result, caselog);
// 失败并且不在继续,直接终止
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","");
}
//LogOperation.UpdateTastdetail(taskid, 0);
}
public static String iosRunStep(Map<String, String> params, Map<String, String> variable, IOSDriver<IOSElement> appium,String taskid,Integer caseId,int stepno,serverOperation caselog) {
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");
// 处理值传递
property = ChangString.changparams(property, variable,"定位方式");
propertyValue=ChangString.changparams(propertyValue, variable,"定位路径");
operation=ChangString.changparams(operation, variable,"操作");
operationValue=ChangString.changparams(operationValue, variable,"操作参数");
LogUtil.APP.info("二次解析用例过程完成,等待进行对象操作......");
caselog.insertTaskCaseLog(taskid, caseId, "对象操作:"+operation+"; 操作值:"+operationValue,"info", String.valueOf(stepno),"");
} catch (Exception e) {
LogUtil.APP.error("二次解析用例过程抛出异常!",e);
return "步骤执行失败:解析用例失败!";
}
try {
//调用接口用例
if(null != operationValue && "runcase".equals(operation)){
String[] temp=operationValue.split(",",-1);
TestCaseExecution testCaseExecution=new TestCaseExecution();
String ex = testCaseExecution.oneCaseExecuteForUICase(temp[0], taskid, caselog, appium);
if(!ex.contains("CallCase调用出错") && !ex.contains("解析出错啦!") && !ex.contains("匹配失败")){
return ex;
}else{
return "步骤执行失败:调用接口用例过程失败";
}
}
IOSElement ae;
// 页面元素层
if (null != property && null != propertyValue) {
ae = isElementExist(appium, property, propertyValue);
// 判断此元素是否存在
if (null==ae) {
LogUtil.APP.warn("定位对象失败isElementExist为null!");
return "步骤执行失败isElementExist定位元素过程失败";
}
assert operation != null;
if (operation.contains("select")) {
result = IosEncapsulateOperation.selectOperation(ae, operation, operationValue);
} else if (operation.contains("get")){
result = IosEncapsulateOperation.getOperation(ae, operation,operationValue);
} else {
result = IosEncapsulateOperation.objectOperation(appium, ae, operation, operationValue, property, propertyValue);
}
// Driver层操作
} else if (null==property && null != operation) {
// 处理弹出框事件
if (operation.contains("alert")){
result = IosEncapsulateOperation.alertOperation(appium, operation);
}else{
result = IosEncapsulateOperation.driverOperation(appium, operation, operationValue);
}
}else{
LogUtil.APP.warn("元素操作过程失败!");
result = "步骤执行失败:元素操作过程失败!";
}
} catch (Exception e) {
LogUtil.APP.error("元素定位过程或是操作过程失败或异常!",e);
return "步骤执行失败:元素定位过程或是操作过程失败或异常!" + e.getMessage();
}
caselog.insertTaskCaseLog(taskid, caseId, result,"info", String.valueOf(stepno),"");
if(result.contains("获取到的值是【") && result.contains("")){
result = result.substring(result.indexOf("获取到的值是【")+7, result.length()-1);
}
return result;
}
public static IOSElement isElementExist(IOSDriver<IOSElement> appium, String property, String propertyValue) {
try {
IOSElement ae = null;
property=property.toLowerCase();
// 处理WebElement对象定位
switch (property) {
case "id":
ae = appium.findElementById(propertyValue);
break;
case "name":
ae = appium.findElementByName(propertyValue);
break;
case "xpath":
ae = appium.findElementByXPath(propertyValue);
break;
case "linktext":
ae = appium.findElementByLinkText(propertyValue);
break;
case "tagname":
ae = appium.findElementByTagName(propertyValue);
break;
case "cssselector":
ae = appium.findElementByCssSelector(propertyValue);
break;
case "classname":
ae = appium.findElementByClassName(propertyValue);
break;
case "accessibilityid":
ae = appium.findElementByAccessibilityId(propertyValue);
break;
case "iosclasschain":
ae = appium.findElementByIosClassChain(propertyValue);
break;
case "iosnspredicate":
ae = appium.findElementByIosNsPredicate(propertyValue);
break;
default:
break;
}
return ae;
} catch (Exception e) {
LogUtil.APP.error("当前对象定位失败!",e);
return null;
}
}
public static int judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, IOSDriver<IOSElement> appium, String taskid, String expect, String result, serverOperation caselog) {
int setresult = 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()) {
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()), "");
}
// 移动端 UI检查模式
else if (3 == step.getStepType() && params.get("checkproperty") != null && params.get("checkproperty_value") != null) {
String checkproperty = params.get("checkproperty");
String checkPropertyValue = params.get("checkproperty_value");
IOSElement ae = isElementExist(appium, checkproperty, checkPropertyValue);
if (null != ae) {
LogUtil.APP.info("用例:{} 第{}步,在当前页面中找到预期结果中对象。当前步骤执行成功!",testcase.getCaseSign(),step.getStepSerialNumber());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在当前页面中找到预期结果中对象。当前步骤执行成功!", "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
casenote = "" + step.getStepSerialNumber() + "步,没有在当前页面中找到预期结果中对象。执行失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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() + "步,模糊匹配预期结果失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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() + "步,正则匹配预期结果失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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 {
casenote = "" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
setresult = 1;
IosBaseAppium.screenShot(appium, 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 : "";
setresult = 2;
IosBaseAppium.screenShot(appium, imagname);
LogUtil.APP.warn("用例:{} 第{}步,执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),casenote);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "当前步骤在执行过程中解析|定位元素|操作对象失败!" + casenote, "error", String.valueOf(step.getStepSerialNumber()), imagname);
}
return setresult;
}
}

View File

@ -1,73 +1,68 @@
package luckyclient.execution.appium.iosex;
import java.io.IOException;
import java.util.List;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年1月29日
*
*/
public class IosCaseLocalDebug {
public static void oneCasedebug(IOSDriver<IOSElement> iosdriver, String testCaseExternalId) {
// 不记录日志到数据库
serverOperation.exetype = 1;
serverOperation caselog = new serverOperation();
try {
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
LogUtil.APP.info("开始执行用例:【{}】......",testCaseExternalId);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
IosCaseExecution.caseExcution(testcase, steps, "888888", iosdriver, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
/**
* @param 项目名
* @param 用例编号
* @param 用例版本号
* 用于在testlink上配置好用例参数后做多条用例串行调试
*/
public static void moreCaseDebug(IOSDriver<IOSElement> iosdriver, String projectname,
List<String> addtestcase) {
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try {
LogUtil.APP
.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(iosdriver, testCaseExternalId);
} catch (Exception e) {
LogUtil.APP.error("多用例调试过程中抛出异常!", e);
continue;
}
}
// 关闭APP以及appium会话
iosdriver.closeApp();
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
}
}
package luckyclient.execution.appium.iosex;
import java.io.IOException;
import java.util.List;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年1月29日
*
*/
public class IosCaseLocalDebug {
public static void oneCasedebug(IOSDriver<IOSElement> iosdriver, String testCaseExternalId) {
// 不记录日志到数据库
serverOperation.exetype = 1;
serverOperation caselog = new serverOperation();
try {
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
LogUtil.APP.info("开始执行用例:【{}】......",testCaseExternalId);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
IosCaseExecution.caseExcution(testcase, steps, "888888", iosdriver, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
/**
* 用于做多条用例串行调试
* @param iosdriver IOS驱动
* @param projectname 项目名称
* @param addtestcase 用例编号
*/
public static void moreCaseDebug(IOSDriver<IOSElement> iosdriver, String projectname,
List<String> addtestcase) {
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try {
LogUtil.APP
.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(iosdriver, testCaseExternalId);
} catch (Exception e) {
LogUtil.APP.error("多用例调试过程中抛出异常!", e);
}
}
// 关闭APP以及appium会话
iosdriver.closeApp();
}
}

View File

@ -1,73 +1,74 @@
package luckyclient.execution.appium.iosex;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年2月2日
*
*/
public class IosOneCaseExecute {
public static void oneCaseExecuteForTast(String projectname, Integer caseId, int version, String taskid)
throws IOException, InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
IOSDriver<IOSElement> iosd = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.valueOf(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
iosd = AppiumInitialization.setIosAppium(properties);
} catch (IOException e1) {
LogUtil.APP.error("初始化IOSDriver出错", 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());
IosCaseExecution.caseExcution(testcase, steps, taskid, iosd, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (InterruptedException e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
iosd.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}
package luckyclient.execution.appium.iosex;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.execution.appium.AppiumInitialization;
import luckyclient.execution.appium.AppiumService;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年2月2日
*
*/
public class IosOneCaseExecute {
public static void oneCaseExecuteForTast(Integer caseId, String taskid)
throws InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
IOSDriver<IOSElement> iosd = null;
AppiumService as=null;
try {
Properties properties = AppiumConfig.getConfiguration();
//根据配置自动启动Appiume服务
if(Boolean.parseBoolean(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
iosd = AppiumInitialization.setIosAppium(properties);
} catch (IOException e1) {
LogUtil.APP.error("初始化IOSDriver出错", 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());
IosCaseExecution.caseExcution(testcase, steps, taskid, iosd, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
assert iosd != null;
iosd.closeApp();
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
}

View File

@ -1,63 +1,63 @@
package luckyclient.execution.dispose;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.reflections.Reflections;
import luckyclient.execution.dispose.actionkeyword.Action;
import luckyclient.execution.dispose.actionkeyword.ActionKeyWordParser;
import luckyclient.utils.LogUtil;
/**
* 步骤动作容器根据参数生成不同的动作关键字类型执行相应的解析
* @author: sunshaoyan@
* @date: Created on 2019/4/13
*/
@SuppressWarnings("rawtypes")
public class ActionContext {
private static Map<String, Class> allActions;
static {
Reflections reflections = new Reflections("luckyclient.execution.dispose.actionkeyword");
Set<Class<?>> annotatedClasses =
reflections.getTypesAnnotatedWith(Action.class);
allActions = new ConcurrentHashMap<String, Class>();
for (Class<?> classObject : annotatedClasses) {
Action action = (Action) classObject
.getAnnotation(Action.class);
allActions.put(action.name(), classObject);
}
allActions = Collections.unmodifiableMap(allActions);
}
private ActionKeyWordParser action;
public ActionContext(String name){
if (allActions.containsKey(name)) {
LogUtil.APP.info("Created Action name is {}", name);
try {
action = (ActionKeyWordParser) allActions.get(name).newInstance();
} catch (InstantiationException | IllegalAccessException ex) {
LogUtil.APP.error("Instantiate Action failed", ex);
}
} else {
LogUtil.APP.warn("Specified Action name {} does not exist", name);
}
}
public String parse(String actionParams,String testResult,String actionKeyWord) {
if(null != action){
testResult = action.parse(actionParams, testResult);
}else {
testResult="未检索到对应动作关键字,直接跳过此动作,请检查关键字:"+actionKeyWord;
LogUtil.APP.warn("未检索到对应动作关键字,直接跳过此动作,请检查关键字:{}",actionKeyWord);
}
return testResult;
}
}
package luckyclient.execution.dispose;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.reflections.Reflections;
import luckyclient.execution.dispose.actionkeyword.Action;
import luckyclient.execution.dispose.actionkeyword.ActionKeyWordParser;
import luckyclient.utils.LogUtil;
/**
* 步骤动作容器根据参数生成不同的动作关键字类型执行相应的解析
* @author: sunshaoyan@
* @date: Created on 2019/4/13
*/
@SuppressWarnings("rawtypes")
public class ActionContext {
private static Map<String, Class> allActions;
static {
Reflections reflections = new Reflections("luckyclient.execution.dispose.actionkeyword");
Set<Class<?>> annotatedClasses =
reflections.getTypesAnnotatedWith(Action.class);
allActions = new ConcurrentHashMap<>();
for (Class<?> classObject : annotatedClasses) {
Action action = classObject
.getAnnotation(Action.class);
allActions.put(action.name(), classObject);
}
allActions = Collections.unmodifiableMap(allActions);
}
private ActionKeyWordParser action;
public ActionContext(String name){
if (allActions.containsKey(name)) {
LogUtil.APP.info("Created Action name is {}", name);
try {
action = (ActionKeyWordParser) allActions.get(name).newInstance();
} catch (InstantiationException | IllegalAccessException ex) {
LogUtil.APP.error("Instantiate Action failed", ex);
}
} else {
LogUtil.APP.warn("Specified Action name {} does not exist", name);
}
}
public String parse(String actionParams,String testResult,String actionKeyWord) {
if(null != action){
testResult = action.parse(actionParams, testResult);
}else {
testResult="未检索到对应动作关键字,直接跳过此动作,请检查关键字:"+actionKeyWord;
LogUtil.APP.warn("未检索到对应动作关键字,直接跳过此动作,请检查关键字:{}",actionKeyWord);
}
return testResult;
}
}

View File

@ -1,90 +1,90 @@
package luckyclient.execution.dispose;
import cn.hutool.core.util.StrUtil;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* 动作关键字处理
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull
* =================================================================
* @author Seagull
* @date 2019年1月15日
*/
public class ActionManageForSteps {
/**
* 解析用例步骤
* @param stepsaction
* @param testresult
* @return
*/
public static String actionManage(String stepsaction,String testresult){
LogUtil.APP.info("Action(动作)处理前,测试结果是:{}",testresult);
LogUtil.APP.info("现在进入到Action(动作)处理......ACTION值{}",stepsaction);
if(null==stepsaction||"".equals(stepsaction.trim())){
LogUtil.APP.info("Action(动作)无需处理......");
return testresult;
}
String responseHead="";
String responseCode="";
//去除测试响应头域消息
if(testresult.startsWith(Constants.RESPONSE_HEAD)){
responseHead = testresult.substring(0,testresult.indexOf(Constants.RESPONSE_END)+1);
testresult = testresult.substring(testresult.indexOf(responseHead)+responseHead.length()+1);
responseHead = responseHead+" ";
}
//去除测试响应头域消息
if(testresult.startsWith(Constants.RESPONSE_CODE)){
responseCode = testresult.substring(0,testresult.indexOf(Constants.RESPONSE_END)+1);
testresult = testresult.substring(testresult.indexOf(responseCode)+responseCode.length()+1);
responseCode = responseCode+" ";
}
stepsaction=stepsaction.trim();
String[] temp=stepsaction.split("\\|",-1);
for(String actionorder:temp){
if(null!=actionorder&&!"".equals(actionorder.trim())){
testresult=actionExecute(actionorder,testresult);
}
}
//返回处理结果时再把响应头以及响应码加上
return responseHead+responseCode+testresult;
}
/**
* 动作关键字执行
* @param actionKeyWord
* @param testResult
* @return
*/
private static String actionExecute(String actionKeyWord,String testResult){
try{
String keyWord = "";
String actionParams = "";
if(actionKeyWord.contains("#")){
keyWord = actionKeyWord.substring(actionKeyWord.lastIndexOf("#")+1, actionKeyWord.length());
actionParams = actionKeyWord.substring(0, actionKeyWord.lastIndexOf("#"));
}
if(StrUtil.isNotEmpty(keyWord)&& keyWord.length()>0){
ActionContext actionContext = new ActionContext(keyWord.toLowerCase());
testResult = actionContext.parse(actionParams, testResult, actionKeyWord);
}else {
testResult="关键字语法书写有误,请检查关键字:"+actionKeyWord;
LogUtil.APP.warn("关键字语法书写有误,请检查关键字:{}",actionKeyWord);
}
return testResult;
}catch(Exception e){
testResult="处理步骤动作事件过程中出现异常,直接返回测试结果:"+actionKeyWord;
LogUtil.APP.error("处理步骤动作事件过程中出现异常,直接返回测试结果!" ,e);
return testResult;
}
}
}
package luckyclient.execution.dispose;
import cn.hutool.core.util.StrUtil;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* 动作关键字处理
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull
* =================================================================
* @author Seagull
* @date 2019年1月15日
*/
public class ActionManageForSteps {
/**
* 解析用例步骤
* @param stepsaction 步骤关键字
* @param testresult 待处理测试结果
* @return 返回处理后结果
*/
public static String actionManage(String stepsaction,String testresult){
LogUtil.APP.info("Action(动作)处理前,测试结果是:{}",testresult);
LogUtil.APP.info("现在进入到Action(动作)处理......ACTION值{}",stepsaction);
if(null==stepsaction||"".equals(stepsaction.trim())){
LogUtil.APP.info("Action(动作)无需处理......");
return testresult;
}
String responseHead="";
String responseCode="";
//去除测试响应头域消息
if(testresult.startsWith(Constants.RESPONSE_HEAD)){
responseHead = testresult.substring(0,testresult.indexOf(Constants.RESPONSE_END)+1);
testresult = testresult.substring(testresult.indexOf(responseHead)+responseHead.length()+1);
responseHead = responseHead+" ";
}
//去除测试响应头域消息
if(testresult.startsWith(Constants.RESPONSE_CODE)){
responseCode = testresult.substring(0,testresult.indexOf(Constants.RESPONSE_END)+1);
testresult = testresult.substring(testresult.indexOf(responseCode)+responseCode.length()+1);
responseCode = responseCode+" ";
}
stepsaction=stepsaction.trim();
String[] temp=stepsaction.split("\\|",-1);
for(String actionorder:temp){
if(null!=actionorder&&!"".equals(actionorder.trim())){
testresult=actionExecute(actionorder,testresult);
}
}
//返回处理结果时再把响应头以及响应码加上
return responseHead+responseCode+testresult;
}
/**
* 动作关键字执行
* @param actionKeyWord 步骤关键字
* @param testResult 待处理测试结果
* @return 关键字处理后返回结果
*/
private static String actionExecute(String actionKeyWord,String testResult){
try{
String keyWord = "";
String actionParams = "";
if(actionKeyWord.contains("#")){
keyWord = actionKeyWord.substring(actionKeyWord.lastIndexOf("#")+1);
actionParams = actionKeyWord.substring(0, actionKeyWord.lastIndexOf("#"));
}
if(StrUtil.isNotEmpty(keyWord)&& keyWord.length()>0){
ActionContext actionContext = new ActionContext(keyWord.toLowerCase());
testResult = actionContext.parse(actionParams, testResult, actionKeyWord);
}else {
testResult="关键字语法书写有误,请检查关键字:"+actionKeyWord;
LogUtil.APP.warn("关键字语法书写有误,请检查关键字:{}",actionKeyWord);
}
return testResult;
}catch(Exception e){
testResult="处理步骤动作事件过程中出现异常,直接返回测试结果:"+actionKeyWord;
LogUtil.APP.error("处理步骤动作事件过程中出现异常,直接返回测试结果!" ,e);
return testResult;
}
}
}

View File

@ -2,13 +2,7 @@ package luckyclient.execution.dispose;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
@ -34,10 +28,10 @@ public class ChangString {
/**
* 替换变量中的字符
*
* @param str
* @param variable
* @param changname
* @return
* @param str 待处理字符串
* @param variable 变量集公共变量全局变量局部变量
* @param changname 变量key
* @return 返回替换后的字符串
*/
public static String changparams(String str, Map<String, String> variable, String changname) {
try {
@ -45,7 +39,7 @@ public class ChangString {
return null;
}
str = str.replace("&quot;", "\"");
str = str.replace("&#39;", "\'");
str = str.replace("&#39;", "'");
// @@用来注释@的引用作用
int varcount = counter(str, "@") - counter(str, "@@") * 2;
@ -55,17 +49,14 @@ public class ChangString {
int changcount = 0;
// 准备将HASHMAP换成LINKMAP对KEY进行排序解决要先替换最长KEY的问题
List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(variable.entrySet());
List<Map.Entry<String, String>> list = new ArrayList<>(variable.entrySet());
// 然后通过比较器来实现排序
Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
// °´KEY³¤È½µÐòÅÅÐò
@Override
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
return o2.getKey().length() - o1.getKey().length();
}
});
// 按KEY长度降序排序
// 然后通过比较器来实现排序
// 按KEY长度降序排序
list.sort((o1, o2) -> o2.getKey().length() - o1.getKey().length());
Map<String, String> aMap2 = new LinkedHashMap<String, String>();
Map<String, String> aMap2 = new LinkedHashMap<>();
for (Map.Entry<String, String> mapping : list) {
aMap2.put(mapping.getKey(), mapping.getValue());
}
@ -105,10 +96,9 @@ public class ChangString {
/**
* 统计字符
*
* @param str1
* @param str2
* @return
* @param str1 原始字符串
* @param str2 待统计字符串
* @return 返回个数
*/
public static int counter(String str1, String str2) {
int total = 0;
@ -125,9 +115,8 @@ public class ChangString {
/**
* 判断是否是数字
*
* @param str
* @return
* @param str 数字字符
* @return 返回布尔值
*/
public static boolean isNumeric(String str) {
for (int i = 0; i < str.length(); i++) {
@ -140,22 +129,20 @@ public class ChangString {
/**
* 判断是否是整数
*
* @param str
* @return
* @param str 数字字符
* @return 返回布尔值
*/
public static boolean isInteger(String str) {
String patternStr="^[-\\+]?[\\d]*$";
String patternStr="^[-+]?[\\d]*$";
Pattern pattern = Pattern.compile(patternStr);
return pattern.matcher(str).matches();
}
/**
* 替换变量类型
*
* @param object
* @param str
* @return
* @param object 替换对象
* @param str 替换字符串
* @return 返回对象
*/
public static Object settype(Object object, String str) {
if (object instanceof Integer) {
@ -185,11 +172,11 @@ public class ChangString {
private static Boolean BCHANG=false;
/**
* 遍历JSON对象
* @param json
* @param key
* @param value
* @param keyindex
* @return
* @param json 原始json
* @param key 替换key
* @param value 替换值
* @param keyindex 替换key索引
* @return 返回json对象
*/
public static JSONObject parseJsonString(String json,String key,String value,int keyindex){
LinkedHashMap<String, Object> jsonMap = JSON.parseObject(json, new TypeReference<LinkedHashMap<String, Object>>(){});
@ -201,14 +188,13 @@ public class ChangString {
/**
* 替换遍历后JSON对象中的KEY
* @param entry
* @param key
* @param value
* @param keyindex
* @return
* @param entry json对象转换成MAP
* @param key 待替换key
* @param value 替换值
* @param keyindex 替换key索引
*/
@SuppressWarnings("unchecked")
public static Map.Entry<String, Object> parseJsonMap(Map.Entry<String, Object> entry,String key,String value,int keyindex){
public static void parseJsonMap(Entry<String, Object> entry, String key, String value, int keyindex){
//如果是字符串型的null直接把对象设置为对象null
if("NULL".equals(value)){
value = null;
@ -273,6 +259,7 @@ public class ChangString {
if(key.equals(entry.getKey())){
if(keyindex==COUNTER){
LogUtil.APP.info("对象原始Integer值:【{}】",entry.getValue());
assert value != null;
entry.setValue(Integer.valueOf(value));
LogUtil.APP.info("对象替换后Integer值:【{}】",entry.getValue());
BCHANG=true;
@ -285,6 +272,7 @@ public class ChangString {
if(key.equals(entry.getKey())){
if(keyindex==COUNTER){
LogUtil.APP.info("对象原始Long值:【{}】",entry.getValue());
assert value != null;
entry.setValue(Long.valueOf(value));
LogUtil.APP.info("对象替换后Long值:【{}】",entry.getValue());
BCHANG=true;
@ -297,6 +285,7 @@ public class ChangString {
if(key.equals(entry.getKey())){
if(keyindex==COUNTER){
LogUtil.APP.info("对象原始BigDecimal值:【{}】",entry.getValue());
assert value != null;
BigDecimal bd = new BigDecimal(value);
entry.setValue(bd);
LogUtil.APP.info("对象替换后BigDecimal值:【{}】",entry.getValue());
@ -317,28 +306,27 @@ public class ChangString {
COUNTER++;
}
}
return entry;
}
}
/**
* 替换json对象中指定KEY入口方法
* @param json
* @param key
* @param value
* @param index
* @return
* @param json 待替换原始json
* @param key 替换key
* @param value 替换值
* @param index 替换key索引
* @return 返回替换后的MAP对象
*/
public static Map<String, String> changjson(String json, String key, String value,int index) {
json=json.trim();
LogUtil.APP.info("原始JSON:【{}】待替换JSON KEY:【{}】待替换JSON VALUE:【{}】待替换JSON KEY序号:【{}】",json,key,value,index);
Map<String, String> map = new HashMap<String, String>(0);
Map<String, String> map = new HashMap<>(0);
map.put("json", json);
map.put("boolean", BCHANG.toString().toLowerCase());
if (json.startsWith("{") && json.endsWith("}")) {
try {
JSONObject jsonStr = JSONObject.parseObject(json);
JSONObject jsonStr;
jsonStr=parseJsonString(json,key,value,index);
if (BCHANG) {
LogUtil.APP.info("JSON字符串替换成功新JSON:【{}】",jsonStr.toJSONString());

View File

@ -1,113 +1,113 @@
package luckyclient.execution.dispose;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.utils.LogUtil;
/**
* 对内置参数进行处理
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull
* =================================================================
* @author Seagull
* @date 2019年1月15日
*/
public class ParamsManageForSteps {
public static Map<String, String> GLOBAL_VARIABLE = new HashMap<>(0);
/**
* 进内置参数管理
* @param params
* @return
* @author Seagull
* @date 2019年1月15日
*/
public static String paramsManage(String params) {
ParamsManageForSteps pmfs = new ParamsManageForSteps();
params = pmfs.replaceRandomInt(params);
params = pmfs.replaceTimeNow(params);
return params;
}
/**
* 内置参数生成替换(生成随机整数)
* @param params
* @return
* @author Seagull
* @date 2019年1月15日
*/
private String replaceRandomInt(String params) {
try {
String str="(?i)@\\{random\\[(\\d+)\\]\\[(\\d+)\\]\\}";
Pattern pattern = Pattern.compile(str);
Matcher m = pattern.matcher(params);
while (m.find()) {
String matcherstr = m.group(0);
int startnum = Integer
.valueOf(matcherstr.substring(matcherstr.indexOf("[") + 1, matcherstr.indexOf("]")).trim());
int endnum = Integer
.valueOf(matcherstr.substring(matcherstr.lastIndexOf("[") + 1, matcherstr.lastIndexOf("]")).trim());
Random random = new Random();
String replacement = String.valueOf(random.nextInt(endnum - startnum + 1) + startnum);
params = m.replaceFirst(replacement);
LogUtil.APP.info("Params({}):替换成随机数后,字符串:{}",matcherstr,params);
m = pattern.matcher(params);
}
return params;
} catch (IllegalArgumentException iae) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查数字区间是否正常!",iae);
return params;
} catch (Exception e) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查你的格式是否正确!",e);
return params;
}
}
/**
* 内置参数生成替换(生成当时时间指定格式)
* @param params
* @return
* @author Seagull
* @date 2019年1月15日
*/
private String replaceTimeNow(String params) {
try {
String str="(?i)@\\{timenow\\[(.*?)\\]\\}";
Pattern pattern = Pattern.compile(str);
Matcher m = pattern.matcher(params);
while (m.find()) {
String matcherstr = m.group(0);
String formart = matcherstr.substring(matcherstr.indexOf("[") + 1, matcherstr.indexOf("]")).trim();
SimpleDateFormat df = null;
try {
if("".equals(formart)||"timestamp".equals(formart.toLowerCase())){
long time = System.currentTimeMillis();
matcherstr=String.valueOf(time);
}else{
df = new SimpleDateFormat(formart);
matcherstr=df.format(new Date());
}
} catch (IllegalArgumentException iae) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查你的格式是否正确!",iae);
df = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
matcherstr=df.format(new Date());
} finally {
params = m.replaceFirst(matcherstr);
LogUtil.APP.info("Params({}):替换成随机数后,字符串:{}",matcherstr,params);
m = pattern.matcher(params);
}
}
return params;
} catch (Exception e) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查你的格式是否正确!",e);
return params;
}
}
}
package luckyclient.execution.dispose;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.utils.LogUtil;
/**
* 对内置参数进行处理
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull
* =================================================================
* @author Seagull
* @date 2019年1月15日
*/
public class ParamsManageForSteps {
public static Map<String, String> GLOBAL_VARIABLE = new HashMap<>(0);
/**
* 进内置参数管理
* @param params 内置参数关键字
* @return 返回参数处理结果
* @author Seagull
* @date 2019年1月15日
*/
public static String paramsManage(String params) {
ParamsManageForSteps pmfs = new ParamsManageForSteps();
params = pmfs.replaceRandomInt(params);
params = pmfs.replaceTimeNow(params);
return params;
}
/**
* 内置参数生成替换(生成随机整数)
* @param params 参数关键字
* @return 返回随机数
* @author Seagull
* @date 2019年1月15日
*/
private String replaceRandomInt(String params) {
try {
String str="(?i)@\\{random\\[(\\d+)]\\[(\\d+)]}";
Pattern pattern = Pattern.compile(str);
Matcher m = pattern.matcher(params);
while (m.find()) {
String matcherstr = m.group(0);
int startnum = Integer
.parseInt(matcherstr.substring(matcherstr.indexOf("[") + 1, matcherstr.indexOf("]")).trim());
int endnum = Integer
.parseInt(matcherstr.substring(matcherstr.lastIndexOf("[") + 1, matcherstr.lastIndexOf("]")).trim());
Random random = new Random();
String replacement = String.valueOf(random.nextInt(endnum - startnum + 1) + startnum);
params = m.replaceFirst(replacement);
LogUtil.APP.info("Params({}):替换成随机数后,字符串:{}",matcherstr,params);
m = pattern.matcher(params);
}
return params;
} catch (IllegalArgumentException iae) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查数字区间是否正常!",iae);
return params;
} catch (Exception e) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查你的格式是否正确!",e);
return params;
}
}
/**
* 内置参数生成替换(生成当时时间指定格式)
* @param params 参数关键字
* @return 返回生成的参数
* @author Seagull
* @date 2019年1月15日
*/
private String replaceTimeNow(String params) {
try {
String str="(?i)@\\{timenow\\[(.*?)]}";
Pattern pattern = Pattern.compile(str);
Matcher m = pattern.matcher(params);
while (m.find()) {
String matcherstr = m.group(0);
String formart = matcherstr.substring(matcherstr.indexOf("[") + 1, matcherstr.indexOf("]")).trim();
SimpleDateFormat df;
try {
if("".equals(formart)||"timestamp".equals(formart.toLowerCase())){
long time = System.currentTimeMillis();
matcherstr=String.valueOf(time);
}else{
df = new SimpleDateFormat(formart);
matcherstr=df.format(new Date());
}
} catch (IllegalArgumentException iae) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查你的格式是否正确!",iae);
df = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
matcherstr=df.format(new Date());
} finally {
params = m.replaceFirst(matcherstr);
LogUtil.APP.info("Params({}):替换成随机数后,字符串:{}",matcherstr,params);
m = pattern.matcher(params);
}
}
return params;
} catch (Exception e) {
LogUtil.APP.error("处理随机数字参数过程中出现异常,请检查你的格式是否正确!",e);
return params;
}
}
}

View File

@ -1,17 +1,17 @@
package luckyclient.execution.dispose.actionkeyword;
/**
* 动作关键字注解定义
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Action {
String name() default "";
}
package luckyclient.execution.dispose.actionkeyword;
import java.lang.annotation.*;
/**
* 动作关键字注解定义
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Action {
String name() default "";
}

View File

@ -1,19 +1,19 @@
package luckyclient.execution.dispose.actionkeyword;
/**
* 动作关键字的处理接口
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
public interface ActionKeyWordParser {
/**
* 针对关键字的抽象方法
* @param actionParams
* @param testResult
* @return
* @author Seagull
* @date 2019年8月8日
*/
String parse(String actionParams, String testResult);
}
package luckyclient.execution.dispose.actionkeyword;
/**
* 动作关键字的处理接口
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
public interface ActionKeyWordParser {
/**
* 针对关键字的抽象方法
* @param actionParams 关键字
* @param testResult 待处理的测试结果
* @return 返回处理结果
* @author Seagull
* @date 2019年8月8日
*/
String parse(String actionParams, String testResult);
}

View File

@ -19,7 +19,7 @@ public class GetJsonActionParser implements ActionKeyWordParser {
*/
@Override
public String parse(String actionParams, String testResult) {
String key="";
String key;
String index="1";
if(actionParams.endsWith("]")&&actionParams.contains("[")){
key=actionParams.substring(0,actionParams.indexOf("["));

View File

@ -16,9 +16,9 @@ public class HeaderParser implements ActionKeyWordParser {
/**
* 动作关键字
* @param actionParams
* @param testResult
* @return
* @param actionParams 关键字参数
* @param testResult 待处理的测试结果
* @return 返回处理结果
*/
@Override
public String parse(String actionParams, String testResult) {

View File

@ -19,8 +19,8 @@ public class SubCentresStrActionParser implements ActionKeyWordParser {
*/
@Override
public String parse(String actionParams, String testResult) {
String startstr="";
String endstr="";
String startstr;
String endstr;
if(actionParams.startsWith("[")&&actionParams.endsWith("]")){
startstr=actionParams.substring(actionParams.indexOf("[")+1, actionParams.indexOf("]"));
endstr=actionParams.substring(actionParams.lastIndexOf("[")+1, actionParams.lastIndexOf("]"));

View File

@ -19,7 +19,7 @@ public class SubStrRegxActionParser implements ActionKeyWordParser {
*/
@Override
public String parse(String actionParams, String testResult) {
String key="";
String key;
String index="1";
if(actionParams.endsWith("]")&&actionParams.contains("[")){
key=actionParams.substring(0,actionParams.lastIndexOf("["));

View File

@ -15,9 +15,9 @@ public class ThreadWaitAction implements ActionKeyWordParser {
/**
* 动作关键字
* @param actionParams
* @param testResult
* @return
* @param actionParams 关键字参数
* @param testResult 待处理测试结果
* @return 返回处理后结果
*/
@Override
public String parse(String actionParams, String testResult) {

View File

@ -1,239 +1,230 @@
package luckyclient.execution.httpinterface;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.InvokeMethod;
import luckyclient.utils.LogUtil;
import luckyclient.utils.httputils.HttpRequest;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: TestCaseDebug
* @Description: 针对自动化用例在编写过程中对用例脚本进行调试 @author seagull
* @date 2018年3月1日
*
*/
public class ApiTestCaseDebug {
private static final String ASSIGNMENT_SIGN = "$=";
private static final String FUZZY_MATCHING_SIGN = "%=";
private static final String REGULAR_MATCHING_SIGN = "~=";
/**
* 用于在本地做单条用例调试
*
* @param projectname
* @param testCaseExternalId
*/
public static void oneCaseDebug(String projectname, String testCaseExternalId) {
Map<String, String> variable = new HashMap<String, String>(0);
String packagename = null;
String functionname = null;
String expectedresults = null;
Integer setcaseresult = 0;
Object[] getParameterValues = null;
String testnote = "初始化测试结果";
int k = 0;
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
setcaseresult = 2;
LogUtil.APP.warn("用例中未找到步骤,请检查!");
testnote = "用例中未找到步骤,请检查!";
}
// 进入循环解析用例所有步骤
for (int i = 0; i < steps.size(); i++) {
Map<String, String> casescript = InterfaceAnalyticCase.analyticCaseStep(testcase, steps.get(i), "888888",
null,variable);
try {
packagename = casescript.get("PackageName").toString();
functionname = casescript.get("FunctionName").toString();
} catch (Exception e) {
k = 0;
LogUtil.APP.error("用例:{} 解析包名或是方法名失败,请检查!",testcase.getCaseSign(),e);
break; // 某一步骤失败后此条用例置为失败退出
}
// 用例名称解析出现异常或是单个步骤参数解析异常
if (functionname.indexOf("解析异常") > -1 || k == 1) {
k = 0;
testnote = "用例第" + (i + 1) + "步解析出错啦!";
break;
}
expectedresults = casescript.get("ExpectedResults").toString();
// 判断方法是否带参数
if (casescript.size() > 4) {
// 获取传入参数放入对象中初始化参数对象个数
getParameterValues = new Object[casescript.size() - 4];
for (int j = 0; j < casescript.size() - 4; j++) {
if (casescript.get("FunctionParams" + (j + 1)) == null) {
k = 1;
break;
}
String parameterValues = casescript.get("FunctionParams" + (j + 1));
LogUtil.APP.info("用例:{} 解析包名:{} 方法名:{} 第{}个参数:{}",testcase.getCaseSign(),packagename,functionname,(j+1),parameterValues);
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
// 调用动态方法执行测试用例
try {
LogUtil.APP.info("开始调用方法:{} .....",functionname);
testnote = InvokeMethod.callCase(packagename, functionname, getParameterValues,
steps.get(i).getStepType(), steps.get(i).getExtend());
testnote = ActionManageForSteps.actionManage(casescript.get("Action"), testnote);
if (null != expectedresults && !expectedresults.isEmpty()) {
LogUtil.APP.info("expectedResults=【{}】",expectedresults);
// 赋值传参
if (expectedresults.length() > ASSIGNMENT_SIGN.length()
&& expectedresults.startsWith(ASSIGNMENT_SIGN)) {
variable.put(expectedresults.substring(ASSIGNMENT_SIGN.length()), testnote);
LogUtil.APP
.info("用例:{} 第{}步,将测试结果【{}】赋值给变量【{}】",testcase.getCaseSign(),(i+1),testnote,expectedresults.substring(ASSIGNMENT_SIGN.length()));
}
// 模糊匹配
else if (expectedresults.length() > FUZZY_MATCHING_SIGN.length()
&& expectedresults.startsWith(FUZZY_MATCHING_SIGN)) {
if (testnote.contains(expectedresults.substring(FUZZY_MATCHING_SIGN.length()))) {
LogUtil.APP.info(
"用例:{} 第{}步,模糊匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,模糊匹配预期结果失败!预期结果{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(FUZZY_MATCHING_SIGN.length()),testnote);
testnote = "用例第" + (i + 1) + "步,模糊匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 正则匹配
else if (expectedresults.length() > REGULAR_MATCHING_SIGN.length()
&& expectedresults.startsWith(REGULAR_MATCHING_SIGN)) {
Pattern pattern = Pattern.compile(expectedresults.substring(REGULAR_MATCHING_SIGN.length()));
Matcher matcher = pattern.matcher(testnote);
if (matcher.find()) {
LogUtil.APP.info(
"用例:{} 第{}步,正则匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,正则匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(REGULAR_MATCHING_SIGN.length()),testnote);
testnote = "用例第" + (i + 1) + "步,正则匹配预期结果失败!";
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)) {
LogUtil.APP.info(
"用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,精确匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults,testnote);
testnote = "用例第" + (i + 1) + "步,精确匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
}
} catch (Exception e) {
setcaseresult = 1;
LogUtil.APP.error("调用方法过程出错,方法名:{} 请重新检查脚本方法名称以及参数!",functionname,e);
testnote = "CallCase调用出错";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
variable.clear(); // 清空传参MAP
// 如果调用方法过程中未出错进入设置测试结果流程
if (testnote.indexOf("CallCase调用出错") <= -1 && testnote.indexOf("解析出错啦!") <= -1) {
LogUtil.APP.info("用例{}解析成功,并成功调用用例中方法,请继续查看执行结果!",testCaseExternalId);
} else {
LogUtil.APP.warn("用例{}解析或是调用步骤中的方法出错!",testCaseExternalId);
}
if (0 == setcaseresult) {
LogUtil.APP.info("用例{}步骤全部执行成功!",testCaseExternalId);
} else {
LogUtil.APP.warn("用例{}在执行过程中失败,请检查日志!",testCaseExternalId);
}
}
/**
* 用于在本地做多条用例串行调试
*
* @param projectname
* @param addtestcase
*/
public static void moreCaseDebug(String projectname, List<String> addtestcase) {
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try {
LogUtil.APP
.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCaseDebug(projectname, testCaseExternalId);
} catch (Exception e) {
LogUtil.APP.error("批量Debug用例出现异常",e);
continue;
}
}
}
/**
* 更新系统中用例指定步骤的预期结果
*/
public static String setExpectedResults(String testCaseSign, int steps, String expectedResults) {
String results = "设置结果失败";
String params = "";
try {
expectedResults = expectedResults.replace("%", "BBFFHH");
expectedResults = expectedResults.replace("=", "DHDHDH");
expectedResults = expectedResults.replace("&", "ANDAND");
params = "caseno=" + testCaseSign;
params += "&stepnum=" + steps;
params += "&expectedresults=" + expectedResults;
results = HttpRequest.sendPost("/projectCasesteps/cUpdateStepExpectedResults.do", params);
} catch (Exception e) {
LogUtil.APP.error("更新系统中用例指定步骤的预期结果出现异常!",e);
return "更新系统中用例指定步骤的预期结果出现异常!";
}
return results;
}
public static void main(String[] args) throws Exception {
}
}
package luckyclient.execution.httpinterface;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.InvokeMethod;
import luckyclient.utils.LogUtil;
import luckyclient.utils.httputils.HttpRequest;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: TestCaseDebug
* @Description: 针对自动化用例在编写过程中对用例脚本进行调试 @author seagull
* @date 2018年3月1日
*
*/
public class ApiTestCaseDebug {
private static final String ASSIGNMENT_SIGN = "$=";
private static final String FUZZY_MATCHING_SIGN = "%=";
private static final String REGULAR_MATCHING_SIGN = "~=";
/**
* 用于在本地做单条用例调试
* @param testCaseExternalId 用例编号
*/
public static void oneCaseDebug(String testCaseExternalId) {
Map<String, String> variable = new HashMap<>(0);
String packagename;
String functionname;
String expectedresults;
int setcaseresult = 0;
Object[] getParameterValues;
String testnote = "初始化测试结果";
int k = 0;
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
setcaseresult = 2;
LogUtil.APP.warn("用例中未找到步骤,请检查!");
testnote = "用例中未找到步骤,请检查!";
}
// 进入循环解析用例所有步骤
for (int i = 0; i < steps.size(); i++) {
Map<String, String> casescript = InterfaceAnalyticCase.analyticCaseStep(testcase, steps.get(i), "888888",
null,variable);
try {
packagename = casescript.get("PackageName");
functionname = casescript.get("FunctionName");
} catch (Exception e) {
LogUtil.APP.error("用例:{} 解析包名或是方法名失败,请检查!",testcase.getCaseSign(),e);
break; // 某一步骤失败后此条用例置为失败退出
}
// 用例名称解析出现异常或是单个步骤参数解析异常
if (functionname.contains("解析异常") || k == 1) {
testnote = "用例第" + (i + 1) + "步解析出错啦!";
break;
}
expectedresults = casescript.get("ExpectedResults");
// 判断方法是否带参数
if (casescript.size() > 4) {
// 获取传入参数放入对象中初始化参数对象个数
getParameterValues = new Object[casescript.size() - 4];
for (int j = 0; j < casescript.size() - 4; j++) {
if (casescript.get("FunctionParams" + (j + 1)) == null) {
k = 1;
break;
}
String parameterValues = casescript.get("FunctionParams" + (j + 1));
LogUtil.APP.info("用例:{} 解析包名:{} 方法名:{} 第{}个参数:{}",testcase.getCaseSign(),packagename,functionname,(j+1),parameterValues);
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
// 调用动态方法执行测试用例
try {
LogUtil.APP.info("开始调用方法:{} .....",functionname);
testnote = InvokeMethod.callCase(packagename, functionname, getParameterValues,
steps.get(i).getStepType(), steps.get(i).getExtend());
testnote = ActionManageForSteps.actionManage(casescript.get("Action"), testnote);
if (null != expectedresults && !expectedresults.isEmpty()) {
LogUtil.APP.info("expectedResults=【{}】",expectedresults);
// 赋值传参
if (expectedresults.length() > ASSIGNMENT_SIGN.length()
&& expectedresults.startsWith(ASSIGNMENT_SIGN)) {
variable.put(expectedresults.substring(ASSIGNMENT_SIGN.length()), testnote);
LogUtil.APP
.info("用例:{} 第{}步,将测试结果【{}】赋值给变量【{}】",testcase.getCaseSign(),(i+1),testnote,expectedresults.substring(ASSIGNMENT_SIGN.length()));
}
// 模糊匹配
else if (expectedresults.length() > FUZZY_MATCHING_SIGN.length()
&& expectedresults.startsWith(FUZZY_MATCHING_SIGN)) {
if (testnote.contains(expectedresults.substring(FUZZY_MATCHING_SIGN.length()))) {
LogUtil.APP.info(
"用例:{} 第{}步,模糊匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,模糊匹配预期结果失败!预期结果{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(FUZZY_MATCHING_SIGN.length()),testnote);
testnote = "用例第" + (i + 1) + "步,模糊匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 正则匹配
else if (expectedresults.length() > REGULAR_MATCHING_SIGN.length()
&& expectedresults.startsWith(REGULAR_MATCHING_SIGN)) {
Pattern pattern = Pattern.compile(expectedresults.substring(REGULAR_MATCHING_SIGN.length()));
Matcher matcher = pattern.matcher(testnote);
if (matcher.find()) {
LogUtil.APP.info(
"用例:{} 第{}步,正则匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,正则匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(REGULAR_MATCHING_SIGN.length()),testnote);
testnote = "用例第" + (i + 1) + "步,正则匹配预期结果失败!";
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)) {
LogUtil.APP.info(
"用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,精确匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults,testnote);
testnote = "用例第" + (i + 1) + "步,精确匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
}
} catch (Exception e) {
setcaseresult = 1;
LogUtil.APP.error("调用方法过程出错,方法名:{} 请重新检查脚本方法名称以及参数!",functionname,e);
testnote = "CallCase调用出错";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
variable.clear(); // 清空传参MAP
// 如果调用方法过程中未出错进入设置测试结果流程
if (!testnote.contains("CallCase调用出错") && !testnote.contains("解析出错啦!")) {
LogUtil.APP.info("用例{}解析成功,并成功调用用例中方法,请继续查看执行结果!",testCaseExternalId);
} else {
LogUtil.APP.warn("用例{}解析或是调用步骤中的方法出错!",testCaseExternalId);
}
if (0 == setcaseresult) {
LogUtil.APP.info("用例{}步骤全部执行成功!",testCaseExternalId);
} else {
LogUtil.APP.warn("用例{}在执行过程中失败,请检查日志!",testCaseExternalId);
}
}
/**
* 用于在本地做多条用例串行调试
* @param projectname 项目名称
* @param addtestcase 用例集
*/
public static void moreCaseDebug(String projectname, List<String> addtestcase) {
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try {
LogUtil.APP
.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCaseDebug(testCaseExternalId);
} catch (Exception e) {
LogUtil.APP.error("批量Debug用例出现异常",e);
}
}
}
/**
* 更新系统中用例指定步骤的预期结果
*/
public static String setExpectedResults(String testCaseSign, int steps, String expectedResults) {
String results;
String params;
try {
expectedResults = expectedResults.replace("%", "BBFFHH");
expectedResults = expectedResults.replace("=", "DHDHDH");
expectedResults = expectedResults.replace("&", "ANDAND");
params = "caseno=" + testCaseSign;
params += "&stepnum=" + steps;
params += "&expectedresults=" + expectedResults;
results = HttpRequest.sendPost("/projectCasesteps/cUpdateStepExpectedResults.do", params);
} catch (Exception e) {
LogUtil.APP.error("更新系统中用例指定步骤的预期结果出现异常!",e);
return "更新系统中用例指定步骤的预期结果出现异常!";
}
return results;
}
}

View File

@ -25,33 +25,32 @@ public class BatchTestCaseExecution {
/**
* 创建线程池多线程执行用例
* @param projectname
* @param taskid
* @param batchcase
* @throws Exception
* @param taskid 任务ID
* @param batchcase 批量用例字符串#隔断
* @throws Exception 抛异常
*/
public static void batchCaseExecuteForTast(String projectname,String taskid,String batchcase) throws Exception{
int threadcount = GetServerApi.cGetTaskSchedulingByTaskId(Integer.valueOf(taskid)).getExThreadCount();
public static void batchCaseExecuteForTast(String taskid, String batchcase) throws Exception{
int threadcount = GetServerApi.cGetTaskSchedulingByTaskId(Integer.parseInt(taskid)).getExThreadCount();
ThreadPoolExecutor threadExecute = new ThreadPoolExecutor(threadcount, 30, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000),
new ArrayBlockingQueue<>(1000),
new ThreadPoolExecutor.CallerRunsPolicy());
//执行全部非成功状态用例
if(batchcase.indexOf("ALLFAIL")>-1){
if(batchcase.contains("ALLFAIL")){
//初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
List<Integer> caseIdList = caselog.getCaseListForUnSucByTaskId(taskid);
for(int i=0;i<caseIdList.size();i++){
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseIdList.get(i));
TestControl.THREAD_COUNT++; //多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForBatchCase(projectname,testcase.getCaseId(),taskid));
for (Integer integer : caseIdList) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(integer);
TestControl.THREAD_COUNT++; //多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForBatchCase(testcase.getCaseId(), taskid));
}
}else{ //批量执行用例
String[] temp=batchcase.split("\\#");
String[] temp=batchcase.split("#");
LogUtil.APP.info("当前批量执行任务中共有【{}】条待测试用例...",temp.length);
for(int i=0;i<temp.length;i++){
for (String s : temp) {
TestControl.THREAD_COUNT++; //多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForBatchCase(projectname,Integer.valueOf(temp[i]),taskid));
threadExecute.execute(new ThreadForBatchCase(Integer.valueOf(s), taskid));
}
}
//多线程计数用于检测线程是否全部执行完

View File

@ -1,413 +1,401 @@
package luckyclient.execution.httpinterface;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openqa.selenium.WebDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.driven.SubString;
import luckyclient.execution.appium.AppDriverAnalyticCase;
import luckyclient.execution.appium.androidex.AndroidCaseExecution;
import luckyclient.execution.appium.iosex.IosCaseExecution;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.execution.webdriver.ex.WebCaseExecution;
import luckyclient.execution.webdriver.ex.WebDriverAnalyticCase;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.InvokeMethod;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年3月1日
*/
public class TestCaseExecution {
private Map<String, String> VARIABLE = new HashMap<String, String>(0);
/**
* @param projectname 项目名
* @param testCaseExternalId 用例编号
* @param version 用例版本号
* 用于单条用例调试并通过日志框架写日志到UTP上用做UTP上单条用例运行
*/
public void oneCaseExecuteForTask(String projectname, Integer caseId, String taskid) {
TestControl.TASKID = taskid;
serverOperation.exetype = 0;
// 初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
String packagename = null;
String functionname = null;
String expectedresults = null;
Integer setcaseresult = 0;
Object[] getParameterValues = null;
String testnote = "初始化测试结果";
int k = 0;
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseId);
//更新用例状态
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
VARIABLE.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
VARIABLE.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
setcaseresult = 2;
LogUtil.APP.warn("用例中未找到步骤,请检查!");
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "用例中未找到步骤,请检查!", "error", "1", "");
testnote = "用例中未找到步骤,请检查!";
}
// 进入循环解析用例所有步骤
for (int i = 0; i < steps.size(); i++) {
Map<String, String> casescript = InterfaceAnalyticCase.analyticCaseStep(testcase, steps.get(i), taskid, caselog,VARIABLE);
try {
packagename = casescript.get("PackageName");
functionname = casescript.get("FunctionName");
} catch (Exception e) {
k = 0;
LogUtil.APP.error("用例:{} 解析包名或是方法名失败,请检查!",testcase.getCaseSign(),e);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析包名或是方法名失败,请检查!", "error", String.valueOf(i + 1), "");
break; // 某一步骤失败后此条用例置为失败退出
}
// 用例名称解析出现异常或是单个步骤参数解析异常
if ((null != functionname && functionname.contains("解析异常")) || k == 1) {
k = 0;
testnote = "用例第" + (i + 1) + "步解析出错啦!";
break;
}
expectedresults = casescript.get("ExpectedResults");
// 判断方法是否带参数
if (casescript.size() > 4) {
// 获取传入参数放入对象中初始化参数对象个数
getParameterValues = new Object[casescript.size() - 4];
for (int j = 0; j < casescript.size() - 4; j++) {
if (casescript.get("FunctionParams" + (j + 1)) == null) {
k = 1;
break;
}
String parameterValues = casescript.get("FunctionParams" + (j + 1));
LogUtil.APP.info("用例:{} 解析包名:{} 方法名:{} 第{}个参数:{}",testcase.getCaseSign(),packagename,functionname,(j+1),parameterValues);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析包名:" + packagename + " 方法名:" + functionname + "" + (j + 1) + "个参数:" + parameterValues, "info", String.valueOf(i + 1), "");
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
// 调用动态方法执行测试用例
try {
LogUtil.APP.info("开始调用方法:{} .....",functionname);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "开始调用方法:" + functionname + " .....", "info", String.valueOf(i + 1), "");
testnote = InvokeMethod.callCase(packagename, functionname, getParameterValues, steps.get(i).getStepType(), steps.get(i).getExtend());
testnote = ActionManageForSteps.actionManage(casescript.get("Action"), testnote);
// 判断结果
int stepresult = interfaceJudgeResult(testcase, steps.get(i), taskid, expectedresults, testnote, caselog);
// 失败并且不在继续,直接终止
if (0 != stepresult) {
setcaseresult = stepresult;
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),steps.get(i).getStepSerialNumber());
break;
} else {
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);
testnote = "CallCase调用出错";
setcaseresult = 1;
e.printStackTrace();
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
VARIABLE.clear(); // 清空传参MAP
// 如果调用方法过程中未出错进入设置测试结果流程
if (!testnote.contains("CallCase调用出错") && !testnote.contains("解析出错啦!")) {
LogUtil.APP.info("用例{}解析成功,并成功调用用例中方法,请继续查看执行结果!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析成功,并成功调用用例中方法,请继续查看执行结果!", "info", "SETCASERESULT...", "");
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), setcaseresult);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例{}解析或是调用步骤中的方法出错!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析或是调用步骤中的方法出错!", "error", "SETCASERESULT...", "");
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 2);
}
if (0 == setcaseresult) {
LogUtil.APP.info("用例{}步骤全部执行成功!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "步骤全部执行成功!", "info", "EXECUTECASESUC...", "");
} else {
LogUtil.APP.warn("用例{}在执行过程中失败,请检查日志!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在执行过程中失败,请检查日志!", "error", "EXECUTECASESUC...", "");
}
serverOperation.updateTaskExecuteData(taskid, 0, 2);
}
/**
*
* @param testCaseExternalId
* @param taskid
* @param caselog
* @param driver
* @return
* @throws InterruptedException
* 提供给Web用例中runcase的时候使用
*/
@SuppressWarnings("unchecked")
public String oneCaseExecuteForUICase(String testCaseExternalId, String taskid, serverOperation caselog, Object driver) throws InterruptedException {
String expectedresults = null;
Integer setresult = 1;
String testnote = "初始化测试结果";
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
VARIABLE.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
VARIABLE.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
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 (ProjectCaseSteps step : steps) {
Map<String, String> params;
// 根据步骤类型来分析步骤参数
if (1 == step.getStepType()){
params = WebDriverAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog,VARIABLE);
}else if (3 == step.getStepType()){
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("解析异常")) {
setresult = 2;
break;
}
expectedresults = params.get("ExpectedResults");
// 根据步骤类型来执行步骤
if (1 == step.getStepType()){
WebDriver wd=(WebDriver)driver;
testnote = WebCaseExecution.runWebStep(params, wd, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
// 判断结果
setresult = WebCaseExecution.judgeResult(testcase, step, params, wd, taskid, expectedresults, testnote, caselog);
}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);
// 判断结果
setresult = AndroidCaseExecution.judgeResult(testcase, step, params, ad, taskid, expectedresults, testnote, caselog);
}else{
IOSDriver<IOSElement> ios=(IOSDriver<IOSElement>)driver;
testnote = IosCaseExecution.iosRunStep(params, VARIABLE, ios, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
// 判断结果
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){
testnote = "【调用用例:"+testcase.getCaseSign()+""+step.getStepSerialNumber()+"步在执行过程中失败】";
LogUtil.APP.warn("调用用例:{} 第{}步在执行过程中失败,请检查日志!{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
break;
}
}
VARIABLE.clear(); // 清空传参MAP
if (0 == setresult) {
LogUtil.APP.info("调用用例:{}步骤全部执行成功!",testcase.getCaseSign());
}
return testnote;
}
/**
* 其他类型测试用例中调用接口测试步骤
* @param params
* @param variable
* @param taskid
* @param casenum
* @param step
* @param caselog
* @return
*/
public String runStep(Map<String, String> params, String taskid, String casenum, ProjectCaseSteps step, serverOperation caselog) {
String result = "";
String packagename = "";
String functionname = "";
Object[] getParameterValues = null;
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()), "");
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 int interfaceJudgeResult(ProjectCase testcase, ProjectCaseSteps step, String taskid, String expectedresults, String testnote, serverOperation caselog){
int setresult = 0;
try{
if (null != expectedresults && !expectedresults.isEmpty()) {
LogUtil.APP.info("expectedResults=【{}】",expectedresults);
// 赋值传参
if (expectedresults.length() > Constants.ASSIGNMENT_SIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_SIGN)) {
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)) {
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 {
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()), "");
testnote = "用例第" + 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 {
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()), "");
testnote = "用例第" + 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)) {
setresult = 0;
LogUtil.APP.info("用例:{} 第{}步jsonpath断言预期结果成功预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),step.getStepSerialNumber(),exceptResult,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)) {
LogUtil.APP.info("用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(step.getStepSerialNumber()), "");
} else {
setresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,精确匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),step.getStepSerialNumber(),expectedresults,testnote);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "精确匹配预期结果失败!预期结果:" + expectedresults + ",测试结果:" + testnote, "error", String.valueOf(step.getStepSerialNumber()), "");
testnote = "用例第" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
}
}
}
}catch(Exception e){
LogUtil.APP.error("匹配接口预期结果出现异常!",e);
setresult = 2;
return setresult;
}
return setresult;
}
}
package luckyclient.execution.httpinterface;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openqa.selenium.WebDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import luckyclient.driven.SubString;
import luckyclient.execution.appium.AppDriverAnalyticCase;
import luckyclient.execution.appium.androidex.AndroidCaseExecution;
import luckyclient.execution.appium.iosex.IosCaseExecution;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.execution.webdriver.ex.WebCaseExecution;
import luckyclient.execution.webdriver.ex.WebDriverAnalyticCase;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.InvokeMethod;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年3月1日
*/
public class TestCaseExecution {
private Map<String, String> VARIABLE = new HashMap<>(0);
/**
* 用于单条用例调试并通过日志框架写日志到UTP上用做UTP上单条用例运行
*/
public void oneCaseExecuteForTask(Integer caseId, String taskid) {
TestControl.TASKID = taskid;
serverOperation.exetype = 0;
// 初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
String packagename;
String functionname;
String expectedresults;
int setcaseresult = 0;
Object[] getParameterValues;
String testnote = "初始化测试结果";
int k = 0;
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseId);
//更新用例状态
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
VARIABLE.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
VARIABLE.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
setcaseresult = 2;
LogUtil.APP.warn("用例中未找到步骤,请检查!");
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "用例中未找到步骤,请检查!", "error", "1", "");
testnote = "用例中未找到步骤,请检查!";
}
// 进入循环解析用例所有步骤
for (int i = 0; i < steps.size(); i++) {
Map<String, String> casescript = InterfaceAnalyticCase.analyticCaseStep(testcase, steps.get(i), taskid, caselog,VARIABLE);
try {
packagename = casescript.get("PackageName");
functionname = casescript.get("FunctionName");
} catch (Exception e) {
LogUtil.APP.error("用例:{} 解析包名或是方法名失败,请检查!",testcase.getCaseSign(),e);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析包名或是方法名失败,请检查!", "error", String.valueOf(i + 1), "");
break; // 某一步骤失败后此条用例置为失败退出
}
// 用例名称解析出现异常或是单个步骤参数解析异常
if ((null != functionname && functionname.contains("解析异常")) || k == 1) {
testnote = "用例第" + (i + 1) + "步解析出错啦!";
break;
}
expectedresults = casescript.get("ExpectedResults");
// 判断方法是否带参数
if (casescript.size() > 4) {
// 获取传入参数放入对象中初始化参数对象个数
getParameterValues = new Object[casescript.size() - 4];
for (int j = 0; j < casescript.size() - 4; j++) {
if (casescript.get("FunctionParams" + (j + 1)) == null) {
k = 1;
break;
}
String parameterValues = casescript.get("FunctionParams" + (j + 1));
LogUtil.APP.info("用例:{} 解析包名:{} 方法名:{} 第{}个参数:{}",testcase.getCaseSign(),packagename,functionname,(j+1),parameterValues);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析包名:" + packagename + " 方法名:" + functionname + "" + (j + 1) + "个参数:" + parameterValues, "info", String.valueOf(i + 1), "");
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
// 调用动态方法执行测试用例
try {
LogUtil.APP.info("开始调用方法:{} .....",functionname);
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "开始调用方法:" + functionname + " .....", "info", String.valueOf(i + 1), "");
testnote = InvokeMethod.callCase(packagename, functionname, getParameterValues, steps.get(i).getStepType(), steps.get(i).getExtend());
testnote = ActionManageForSteps.actionManage(casescript.get("Action"), testnote);
// 判断结果
int stepresult = interfaceJudgeResult(testcase, steps.get(i), taskid, expectedresults, testnote, caselog);
// 失败并且不在继续,直接终止
if (0 != stepresult) {
setcaseresult = stepresult;
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),steps.get(i).getStepSerialNumber());
break;
} else {
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);
testnote = "CallCase调用出错";
setcaseresult = 1;
e.printStackTrace();
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
VARIABLE.clear(); // 清空传参MAP
// 如果调用方法过程中未出错进入设置测试结果流程
if (!testnote.contains("CallCase调用出错") && !testnote.contains("解析出错啦!")) {
LogUtil.APP.info("用例{}解析成功,并成功调用用例中方法,请继续查看执行结果!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析成功,并成功调用用例中方法,请继续查看执行结果!", "info", "SETCASERESULT...", "");
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), setcaseresult);
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例{}解析或是调用步骤中的方法出错!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "解析或是调用步骤中的方法出错!", "error", "SETCASERESULT...", "");
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 2);
}
if (0 == setcaseresult) {
LogUtil.APP.info("用例{}步骤全部执行成功!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "步骤全部执行成功!", "info", "EXECUTECASESUC...", "");
} else {
LogUtil.APP.warn("用例{}在执行过程中失败,请检查日志!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在执行过程中失败,请检查日志!", "error", "EXECUTECASESUC...", "");
}
serverOperation.updateTaskExecuteData(taskid, 0, 2);
}
/**
* 提供给Web用例中runcase的时候使用
* @param testCaseExternalId 用例编号
* @param taskid 任务ID
* @param caselog 用例日志对象
* @param driver UI驱动
* @return 返回执行结果
*/
@SuppressWarnings("unchecked")
public String oneCaseExecuteForUICase(String testCaseExternalId, String taskid, serverOperation caselog, Object driver) throws InterruptedException {
String expectedresults;
int setresult = 1;
String testnote = "初始化测试结果";
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
VARIABLE.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
VARIABLE.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
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 (ProjectCaseSteps step : steps) {
Map<String, String> params;
// 根据步骤类型来分析步骤参数
if (1 == step.getStepType()){
params = WebDriverAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog,VARIABLE);
}else if (3 == step.getStepType()){
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("解析异常")) {
setresult = 2;
break;
}
expectedresults = params.get("ExpectedResults");
// 根据步骤类型来执行步骤
if (1 == step.getStepType()){
WebDriver wd=(WebDriver)driver;
testnote = WebCaseExecution.runWebStep(params, wd, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
// 判断结果
setresult = WebCaseExecution.judgeResult(testcase, step, params, wd, taskid, expectedresults, testnote, caselog);
}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);
// 判断结果
setresult = AndroidCaseExecution.judgeResult(testcase, step, params, ad, taskid, expectedresults, testnote, caselog);
}else{
IOSDriver<IOSElement> ios=(IOSDriver<IOSElement>)driver;
testnote = IosCaseExecution.iosRunStep(params, VARIABLE, ios, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
// 判断结果
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){
testnote = "【调用用例:"+testcase.getCaseSign()+""+step.getStepSerialNumber()+"步在执行过程中失败】";
LogUtil.APP.warn("调用用例:{} 第{}步在执行过程中失败,请检查日志!{}",testcase.getCaseSign(),step.getStepSerialNumber(),testnote);
break;
}
}
VARIABLE.clear(); // 清空传参MAP
if (0 == setresult) {
LogUtil.APP.info("调用用例:{}步骤全部执行成功!",testcase.getCaseSign());
}
return testnote;
}
/**
* 其他类型测试用例中调用接口测试步骤
* @param params 参数
* @param taskid 任务ID
* @param casenum 用例编号
* @param step 步骤对象
* @param caselog 日志对象
* @return 返回执行结果
*/
public String runStep(Map<String, String> params, String taskid, String casenum, ProjectCaseSteps step, serverOperation caselog) {
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()), "");
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 int interfaceJudgeResult(ProjectCase testcase, ProjectCaseSteps step, String taskid, String expectedresults, String testnote, serverOperation caselog){
int setresult = 0;
try{
if (null != expectedresults && !expectedresults.isEmpty()) {
LogUtil.APP.info("expectedResults=【{}】",expectedresults);
// 赋值传参
if (expectedresults.length() > Constants.ASSIGNMENT_SIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_SIGN)) {
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)) {
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 {
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 {
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)) {
setresult = 0;
LogUtil.APP.info("用例:{} 第{}步jsonpath断言预期结果成功预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),step.getStepSerialNumber(),exceptResult,result);
} else {
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 {
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);
setresult = 2;
return setresult;
}
return setresult;
}
}

View File

@ -38,18 +38,17 @@ public class TestControl {
/**
* 控制台模式调度计划执行用例
* @param planname
* @throws Exception
* @param planname 计划名称
*/
public static void manualExecutionPlan(String planname) throws Exception {
serverOperation.exetype = 1;
int threadcount = 10;
// 创建线程池多线程执行用例
ThreadPoolExecutor threadExecute = new ThreadPoolExecutor(threadcount, 20, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000), new ThreadPoolExecutor.CallerRunsPolicy());
new ArrayBlockingQueue<>(1000), new ThreadPoolExecutor.CallerRunsPolicy());
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
List<ProjectCaseParams> pcplist = new ArrayList<>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
@ -82,8 +81,7 @@ public class TestControl {
/**
* 计划任务模式调度计划执行用例
* @param task
* @throws Exception
* @param task 任务对象
*/
public static void taskExecutionPlan(TaskExecute task) throws Exception {
serverOperation.exetype = 0;
@ -99,13 +97,13 @@ public class TestControl {
// 初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
if (restartstatus.contains("Status:true")) {
// 判断是否构建是否成功
if (BuildResult.SUCCESS.equals(buildResult)) {
int threadcount = taskScheduling.getExThreadCount();
// 创建线程池多线程执行用例
ThreadPoolExecutor threadExecute = new ThreadPoolExecutor(threadcount, 20, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000), new ThreadPoolExecutor.CallerRunsPolicy());
new ArrayBlockingQueue<>(1000), new ThreadPoolExecutor.CallerRunsPolicy());
List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
LogUtil.APP.info("当前测试任务 {} 中共有【{}】条待测试用例...",task.getTaskName(),cases.size());

View File

@ -1,33 +1,31 @@
package luckyclient.execution.httpinterface;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class ThreadForBatchCase extends Thread{
private String projectname;
private Integer caseId;
private String taskid;
public ThreadForBatchCase(String projectname,Integer caseId,String taskid){
this.projectname = projectname;
this.caseId = caseId;
this.taskid = taskid;
}
@Override
public void run(){
TestCaseExecution testCaseExecution=new TestCaseExecution();
testCaseExecution.oneCaseExecuteForTask(projectname, caseId, taskid);
TestControl.THREAD_COUNT--; //多线程计数--用于检测线程是否全部执行完
}
}
package luckyclient.execution.httpinterface;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class ThreadForBatchCase extends Thread{
private Integer caseId;
private String taskid;
public ThreadForBatchCase(Integer caseId,String taskid){
this.caseId = caseId;
this.taskid = taskid;
}
@Override
public void run(){
TestCaseExecution testCaseExecution=new TestCaseExecution();
testCaseExecution.oneCaseExecuteForTask(caseId, taskid);
TestControl.THREAD_COUNT--; //多线程计数--用于检测线程是否全部执行完
}
}

View File

@ -1,263 +1,261 @@
package luckyclient.execution.httpinterface;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.driven.SubString;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.InvokeMethod;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: ThreadForExecuteCase
* @Description: 线程池方式执行用例
* @author seagull
* @date 2018年3月1日
*/
public class ThreadForExecuteCase extends Thread {
private Integer caseId;
private String caseSign;
private ProjectCase testcase;
private String taskid;
private Integer projectId;
private List<ProjectCaseSteps> steps;
private List<ProjectCaseParams> pcplist;
private serverOperation caselog;
public ThreadForExecuteCase(ProjectCase projectcase, List<ProjectCaseSteps> steps, String taskid, List<ProjectCaseParams> pcplist, serverOperation caselog) {
this.caseId = projectcase.getCaseId();
this.testcase = projectcase;
this.projectId = projectcase.getProjectId();
this.caseSign = projectcase.getCaseSign();
this.taskid = taskid;
this.steps = steps;
this.pcplist = pcplist;
this.caselog = caselog;
}
@Override
public void run() {
Map<String, String> variable = new HashMap<>(0);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
String functionname = null;
String packagename = null;
String expectedresults = null;
Integer setcaseresult = 0;
Object[] getParameterValues = null;
String testnote = "初始化测试结果";
int k = 0;
// 进入循环解析单个用例所有步骤
// 插入开始执行的用例
caselog.insertTaskCaseExecute(taskid, projectId, caseId, caseSign, testcase.getCaseName(), 3);
for (int i = 0; i < steps.size(); i++) {
// 解析单个步骤中的脚本
Map<String, String> casescript = InterfaceAnalyticCase.analyticCaseStep(testcase, steps.get(i), taskid, caselog,variable);
try {
packagename = casescript.get("PackageName");
functionname = casescript.get("FunctionName");
} catch (Exception e) {
k = 0;
LogUtil.APP.error("用例:{} 解析包名或是方法名出现异常,请检查!",testcase.getCaseSign(),e);
caselog.insertTaskCaseLog(taskid, caseId, "解析包名或是方法名失败,请检查!", "error", String.valueOf(i + 1), "");
break; // 某一步骤失败后此条用例置为失败退出
}
// 用例名称解析出现异常或是单个步骤参数解析异常
if ((null != functionname && functionname.contains("解析异常")) || k == 1) {
k = 0;
testnote = "用例第" + (i + 1) + "步解析出错啦!";
break;
}
expectedresults = casescript.get("ExpectedResults");
// 判断方法是否带参数
if (casescript.size() > 4) {
// 获取传入参数放入对象中
getParameterValues = new Object[casescript.size() - 4];
for (int j = 0; j < casescript.size() - 4; j++) {
if (casescript.get("FunctionParams" + (j + 1)) == null) {
k = 1;
break;
}
String parameterValues = casescript.get("FunctionParams" + (j + 1));
LogUtil.APP.info("用例:{} 解析包名:{} 方法名:{} 第{}个参数:{}",testcase.getCaseSign(),packagename,functionname,(j+1),parameterValues);
caselog.insertTaskCaseLog(taskid, caseId, "解析包名:" + packagename + " 方法名:" + functionname + "" + (j + 1) + "个参数:" + parameterValues, "info", String.valueOf(i + 1), "");
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
// 调用动态方法执行测试用例
try {
LogUtil.APP.info("用例:{}开始调用方法:{} .....",testcase.getCaseSign(),functionname);
caselog.insertTaskCaseLog(taskid, caseId, "开始调用方法:" + functionname + " .....", "info", String.valueOf(i + 1), "");
testnote = InvokeMethod.callCase(packagename, functionname, getParameterValues, steps.get(i).getStepType(), steps.get(i).getExtend());
testnote = ActionManageForSteps.actionManage(casescript.get("Action"), testnote);
if (null != expectedresults && !expectedresults.isEmpty()) {
LogUtil.APP.info("expectedResults=【{}】",expectedresults);
// 赋值传参
if (expectedresults.length() > Constants.ASSIGNMENT_SIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_SIGN)) {
variable.put(expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()), testnote);
LogUtil.APP.info("用例:{} 第{}步,将测试结果【{}】赋值给变量【{}】",testcase.getCaseSign(),(i+1),testnote,expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()));
caselog.insertTaskCaseLog(taskid, caseId, "将测试结果【" + testnote + "】赋值给变量【" + expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()) + "", "info", String.valueOf(i + 1), "");
}
// 赋值全局变量
else if (expectedresults.length() > Constants.ASSIGNMENT_GLOBALSIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_GLOBALSIGN)) {
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(),(i+1),testnote,expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()));
caselog.insertTaskCaseLog(taskid, caseId, "将测试结果【" + testnote + "】赋值给全局变量【" + expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()) + "", "info", String.valueOf(i + 1), "");
}
// 模糊匹配
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(),(i+1),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "模糊匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(i + 1), "");
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,模糊匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "" + (i + 1) + "步,模糊匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()) + ",测试结果:" + testnote, "error", String.valueOf(i + 1), "");
testnote = "用例第" + (i + 1) + "步,模糊匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 正则匹配
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(),(i+1),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "正则匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(i + 1), "");
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,正则匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "" + (i + 1) + "步,正则匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()) + ",测试结果:" + testnote, "error", String.valueOf(i + 1), "");
testnote = "用例第" + (i + 1) + "步,正则匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
//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)) {
setcaseresult = 0;
LogUtil.APP.info("用例【{}】 第【{}】步jsonpath断言预期结果成功预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),(i+1),exceptResult,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) + "步,正则匹配预期结果失败!预期结果:" + exceptResult + ",测试结果:" + 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)) {
LogUtil.APP.info("用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "精确匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(i + 1), "");
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,精确匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults,testnote);
caselog.insertTaskCaseLog(taskid, caseId, "" + (i + 1) + "步,精确匹配预期结果失败!预期结果:" + expectedresults + ",测试结果:" + testnote, "error", String.valueOf(i + 1), "");
testnote = "用例第" + (i + 1) + "步,精确匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
}
} catch (Exception e) {
LogUtil.APP.error("用例:{}调用方法过程出错,方法名:{} 请重新检查脚本方法名称以及参数!",testcase.getCaseSign(),functionname,e);
caselog.insertTaskCaseLog(taskid, caseId, "调用方法过程出错,方法名:" + functionname + " 请重新检查脚本方法名称以及参数!", "error", String.valueOf(i + 1), "");
testnote = "CallCase调用出错调用方法过程出错方法名" + functionname + " 请重新检查脚本方法名称以及参数!";
setcaseresult = 1;
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 如果调用方法过程中未出错进入设置测试结果流程
try {
// 成功跟失败的用例走此流程
if (!testnote.contains("CallCase调用出错") && !testnote.contains("解析出错啦!")) {
caselog.updateTaskCaseExecuteStatus(taskid, caseId, setcaseresult);
} else {
// 解析用例或是调用方法出错全部把用例置为锁定
LogUtil.APP.warn("用例:{} 设置执行结果为锁定,请参考错误日志查找锁定用例的原因.....",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, caseId, "设置执行结果为锁定,请参考错误日志查找锁定用例的原因.....","error", "SETCASERESULT...", "");
setcaseresult = 2;
caselog.updateTaskCaseExecuteStatus(taskid, caseId, setcaseresult);
}
if (0 == setcaseresult) {
LogUtil.APP.info("用例:{}执行结果成功......",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, caseId, "用例步骤执行全部成功......", "info", "ending", "");
LogUtil.APP.info("*********用例【{}】执行完成,测试结果:成功*********",testcase.getCaseSign());
} else if (1 == setcaseresult) {
LogUtil.APP.warn("用例:{}执行结果失败......",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, caseId, "用例执行结果失败......", "error", "ending", "");
LogUtil.APP.warn("*********用例【{}】执行完成,测试结果:失败*********",testcase.getCaseSign());
} else {
LogUtil.APP.warn("用例:" + testcase.getCaseSign() + "执行结果锁定......");
caselog.insertTaskCaseLog(taskid, caseId, "用例执行结果锁定......", "error", "ending", "");
LogUtil.APP.warn("*********用例【{}】执行完成,测试结果:锁定*********",testcase.getCaseSign());
}
} catch (Exception e) {
LogUtil.APP.error("用例:{}设置执行结果过程出错......",testcase.getCaseSign(),e);
caselog.insertTaskCaseLog(taskid, caseId, "设置执行结果过程出错......", "error", "ending", "");
} finally {
variable.clear(); // 一条用例结束后清空变量存储空间
TestControl.THREAD_COUNT--; // 多线程计数--用于检测线程是否全部执行完
}
}
}
package luckyclient.execution.httpinterface;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.driven.SubString;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.InvokeMethod;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: ThreadForExecuteCase
* @Description: 线程池方式执行用例
* @author seagull
* @date 2018年3月1日
*/
public class ThreadForExecuteCase extends Thread {
private Integer caseId;
private String caseSign;
private ProjectCase testcase;
private String taskid;
private Integer projectId;
private List<ProjectCaseSteps> steps;
private List<ProjectCaseParams> pcplist;
private serverOperation caselog;
public ThreadForExecuteCase(ProjectCase projectcase, List<ProjectCaseSteps> steps, String taskid, List<ProjectCaseParams> pcplist, serverOperation caselog) {
this.caseId = projectcase.getCaseId();
this.testcase = projectcase;
this.projectId = projectcase.getProjectId();
this.caseSign = projectcase.getCaseSign();
this.taskid = taskid;
this.steps = steps;
this.pcplist = pcplist;
this.caselog = caselog;
}
@Override
public void run() {
Map<String, String> variable = new HashMap<>(0);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
String functionname;
String packagename;
String expectedresults;
int setcaseresult = 0;
Object[] getParameterValues;
String testnote = "初始化测试结果";
int k = 0;
// 进入循环解析单个用例所有步骤
// 插入开始执行的用例
caselog.insertTaskCaseExecute(taskid, projectId, caseId, caseSign, testcase.getCaseName(), 3);
for (int i = 0; i < steps.size(); i++) {
// 解析单个步骤中的脚本
Map<String, String> casescript = InterfaceAnalyticCase.analyticCaseStep(testcase, steps.get(i), taskid, caselog,variable);
try {
packagename = casescript.get("PackageName");
functionname = casescript.get("FunctionName");
} catch (Exception e) {
LogUtil.APP.error("用例:{} 解析包名或是方法名出现异常,请检查!",testcase.getCaseSign(),e);
caselog.insertTaskCaseLog(taskid, caseId, "解析包名或是方法名失败,请检查!", "error", String.valueOf(i + 1), "");
break; // 某一步骤失败后此条用例置为失败退出
}
// 用例名称解析出现异常或是单个步骤参数解析异常
if ((null != functionname && functionname.contains("解析异常")) || k == 1) {
testnote = "用例第" + (i + 1) + "步解析出错啦!";
break;
}
expectedresults = casescript.get("ExpectedResults");
// 判断方法是否带参数
if (casescript.size() > 4) {
// 获取传入参数放入对象中
getParameterValues = new Object[casescript.size() - 4];
for (int j = 0; j < casescript.size() - 4; j++) {
if (casescript.get("FunctionParams" + (j + 1)) == null) {
k = 1;
break;
}
String parameterValues = casescript.get("FunctionParams" + (j + 1));
LogUtil.APP.info("用例:{} 解析包名:{} 方法名:{} 第{}个参数:{}",testcase.getCaseSign(),packagename,functionname,(j+1),parameterValues);
caselog.insertTaskCaseLog(taskid, caseId, "解析包名:" + packagename + " 方法名:" + functionname + "" + (j + 1) + "个参数:" + parameterValues, "info", String.valueOf(i + 1), "");
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
// 调用动态方法执行测试用例
try {
LogUtil.APP.info("用例:{}开始调用方法:{} .....",testcase.getCaseSign(),functionname);
caselog.insertTaskCaseLog(taskid, caseId, "开始调用方法:" + functionname + " .....", "info", String.valueOf(i + 1), "");
testnote = InvokeMethod.callCase(packagename, functionname, getParameterValues, steps.get(i).getStepType(), steps.get(i).getExtend());
testnote = ActionManageForSteps.actionManage(casescript.get("Action"), testnote);
if (null != expectedresults && !expectedresults.isEmpty()) {
LogUtil.APP.info("expectedResults=【{}】",expectedresults);
// 赋值传参
if (expectedresults.length() > Constants.ASSIGNMENT_SIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_SIGN)) {
variable.put(expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()), testnote);
LogUtil.APP.info("用例:{} 第{}步,将测试结果【{}】赋值给变量【{}】",testcase.getCaseSign(),(i+1),testnote,expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()));
caselog.insertTaskCaseLog(taskid, caseId, "将测试结果【" + testnote + "】赋值给变量【" + expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()) + "", "info", String.valueOf(i + 1), "");
}
// 赋值全局变量
else if (expectedresults.length() > Constants.ASSIGNMENT_GLOBALSIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_GLOBALSIGN)) {
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(),(i+1),testnote,expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()));
caselog.insertTaskCaseLog(taskid, caseId, "将测试结果【" + testnote + "】赋值给全局变量【" + expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()) + "", "info", String.valueOf(i + 1), "");
}
// 模糊匹配
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(),(i+1),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "模糊匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(i + 1), "");
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,模糊匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "" + (i + 1) + "步,模糊匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()) + ",测试结果:" + testnote, "error", String.valueOf(i + 1), "");
testnote = "用例第" + (i + 1) + "步,模糊匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 正则匹配
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(),(i+1),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "正则匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(i + 1), "");
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,正则匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "" + (i + 1) + "步,正则匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()) + ",测试结果:" + testnote, "error", String.valueOf(i + 1), "");
testnote = "用例第" + (i + 1) + "步,正则匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
//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)) {
setcaseresult = 0;
LogUtil.APP.info("用例【{}】 第【{}】步jsonpath断言预期结果成功预期结果:{} 测试结果: {} 执行结果:true",testcase.getCaseSign(),(i+1),exceptResult,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) + "步,正则匹配预期结果失败!预期结果:" + exceptResult + ",测试结果:" + 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)) {
LogUtil.APP.info("用例:{} 第{}步,精确匹配预期结果成功!执行结果:{}",testcase.getCaseSign(),(i+1),testnote);
caselog.insertTaskCaseLog(taskid, caseId, "精确匹配预期结果成功!执行结果:" + testnote, "info", String.valueOf(i + 1), "");
} else {
setcaseresult = 1;
LogUtil.APP.warn("用例:{} 第{}步,精确匹配预期结果失败!预期结果:{},测试结果:{}",testcase.getCaseSign(),(i+1),expectedresults,testnote);
caselog.insertTaskCaseLog(taskid, caseId, "" + (i + 1) + "步,精确匹配预期结果失败!预期结果:" + expectedresults + ",测试结果:" + testnote, "error", String.valueOf(i + 1), "");
testnote = "用例第" + (i + 1) + "步,精确匹配预期结果失败!";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
}
} catch (Exception e) {
LogUtil.APP.error("用例:{}调用方法过程出错,方法名:{} 请重新检查脚本方法名称以及参数!",testcase.getCaseSign(),functionname,e);
caselog.insertTaskCaseLog(taskid, caseId, "调用方法过程出错,方法名:" + functionname + " 请重新检查脚本方法名称以及参数!", "error", String.valueOf(i + 1), "");
testnote = "CallCase调用出错调用方法过程出错方法名" + functionname + " 请重新检查脚本方法名称以及参数!";
setcaseresult = 1;
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.error("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 如果调用方法过程中未出错进入设置测试结果流程
try {
// 成功跟失败的用例走此流程
if (!testnote.contains("CallCase调用出错") && !testnote.contains("解析出错啦!")) {
caselog.updateTaskCaseExecuteStatus(taskid, caseId, setcaseresult);
} else {
// 解析用例或是调用方法出错全部把用例置为锁定
LogUtil.APP.warn("用例:{} 设置执行结果为锁定,请参考错误日志查找锁定用例的原因.....",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, caseId, "设置执行结果为锁定,请参考错误日志查找锁定用例的原因.....","error", "SETCASERESULT...", "");
setcaseresult = 2;
caselog.updateTaskCaseExecuteStatus(taskid, caseId, setcaseresult);
}
if (0 == setcaseresult) {
LogUtil.APP.info("用例:{}执行结果成功......",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, caseId, "用例步骤执行全部成功......", "info", "ending", "");
LogUtil.APP.info("*********用例【{}】执行完成,测试结果:成功*********",testcase.getCaseSign());
} else if (1 == setcaseresult) {
LogUtil.APP.warn("用例:{}执行结果失败......",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, caseId, "用例执行结果失败......", "error", "ending", "");
LogUtil.APP.warn("*********用例【{}】执行完成,测试结果:失败*********",testcase.getCaseSign());
} else {
LogUtil.APP.warn("用例:" + testcase.getCaseSign() + "执行结果锁定......");
caselog.insertTaskCaseLog(taskid, caseId, "用例执行结果锁定......", "error", "ending", "");
LogUtil.APP.warn("*********用例【{}】执行完成,测试结果:锁定*********",testcase.getCaseSign());
}
} catch (Exception e) {
LogUtil.APP.error("用例:{}设置执行结果过程出错......",testcase.getCaseSign(),e);
caselog.insertTaskCaseLog(taskid, caseId, "设置执行结果过程出错......", "error", "ending", "");
} finally {
variable.clear(); // 一条用例结束后清空变量存储空间
TestControl.THREAD_COUNT--; // 多线程计数--用于检测线程是否全部执行完
}
}
}

View File

@ -34,16 +34,16 @@ import luckyclient.utils.LogUtil;
public class WebTestCaseDebug {
/**
* 用于在WEB页面上调试用例时提供的接口
* @param caseIdStr
* @param userIdStr
* @param caseIdStr 用例ID
* @param userIdStr 用户ID
*/
public static void oneCaseDebug(String caseIdStr, String userIdStr) {
Map<String, String> variable = new HashMap<>(0);
String packagename = null;
String functionname = null;
String expectedresults = null;
Integer setcaseresult = 0;
Object[] getParameterValues = null;
String packagename;
String functionname;
String expectedresults;
int setcaseresult = 0;
Object[] getParameterValues;
String testnote = "初始化测试结果";
int k = 0;
Integer caseId = Integer.valueOf(caseIdStr);
@ -64,14 +64,12 @@ public class WebTestCaseDebug {
packagename = casescript.get("PackageName");
functionname = casescript.get("FunctionName");
} catch (Exception e) {
k = 0;
LogUtil.APP.error("解析包名或是方法名出现异常!",e);
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "解析包名或是方法名失败,请检查!",2);
break; //某一步骤失败后此条用例置为失败退出
}
//用例名称解析出现异常或是单个步骤参数解析异常
if ((null != functionname && functionname.contains("解析异常")) || k == 1) {
k = 0;
testnote = "用例第" + (i + 1) + "步解析出错啦!";
break;
}
@ -156,10 +154,10 @@ public class WebTestCaseDebug {
if (exceptResult.equals(result)) {
setcaseresult = 0;
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "jsonpath断言预期结果成功预期结果" + exceptResult + " 测试结果: " + result.toString() + "校验结果: true", 0);
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "jsonpath断言预期结果成功预期结果" + exceptResult + " 测试结果: " + result + "校验结果: true", 0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "jsonpath断言预期结果失败预期结果" + exceptResult + ",测试结果:" + result.toString(),0);
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "jsonpath断言预期结果失败预期结果" + exceptResult + ",测试结果:" + result,0);
testnote = "用例第" + (i + 1) + "jsonpath断言预期结果失败";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
@ -211,7 +209,4 @@ public class WebTestCaseDebug {
}
}
public static void main(String[] args) throws Exception {
}
}

View File

@ -1,186 +1,187 @@
package luckyclient.execution.httpinterface.analyticsteps;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.execution.dispose.ChangString;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: AnalyticCase
* @Description: 解析单个用例中描述部分的脚本
* @author seagull
* @date 2017年7月14日 上午9:29:40
*
*/
public class InterfaceAnalyticCase{
/**
* 解析用例步骤
* @param projectcase
* @param step
* @param taskid
* @param caselog
* @return
*/
public static Map<String,String> analyticCaseStep(ProjectCase projectcase,ProjectCaseSteps step,String taskid,serverOperation caselog, Map<String, String> variable){
Map<String,String> params = new HashMap<String,String>(0);
try {
String resultstr = step.getExpectedResult();
params.put("Action", step.getAction());
// 处理值传递
String packageName = ChangString.changparams(step.getStepPath().trim(), variable, "包路径");
params.put("PackageName", packageName);
// 处理值传递
String functionName = ChangString.changparams(step.getStepOperation().trim(), 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) throws InterruptedException{
// 定义script的正则表达式
String regExscript = "<script[^>]*?>[\\s\\S]*?<\\/script>";
// 定义style的正则表达式
String regExstyle = "<style[^>]*?>[\\s\\S]*?<\\/style>";
// 定义HTML标签的正则表达式
String regExhtml = "<[^>]+>";
//定义空格回车换行符
String regExspace = "\t|\r|\n";
String scriptstr = null;
if (htmlStr!=null) {
Pattern pScript = Pattern.compile(regExscript, Pattern.CASE_INSENSITIVE);
Matcher mScript = pScript.matcher(htmlStr);
// 过滤script标签
htmlStr = mScript.replaceAll("");
Pattern pStyle = Pattern.compile(regExstyle, Pattern.CASE_INSENSITIVE);
Matcher mStyle = pStyle.matcher(htmlStr);
// 过滤style标签
htmlStr = mStyle.replaceAll("");
Pattern pHtml = Pattern.compile(regExhtml, Pattern.CASE_INSENSITIVE);
Matcher mHtml = pHtml.matcher(htmlStr);
// 过滤html标签
htmlStr = mHtml.replaceAll("");
Pattern pSpace = Pattern.compile(regExspace, Pattern.CASE_INSENSITIVE);
Matcher mSpace = pSpace.matcher(htmlStr);
// 过滤空格回车标签
htmlStr = mSpace.replaceAll("");
}
if(htmlStr.indexOf("/*")>-1&&htmlStr.indexOf("*/")>-1){
String commentstr = htmlStr.substring(htmlStr.trim().indexOf("/*"),htmlStr.indexOf("*/")+2);
//去注释
scriptstr = htmlStr.replace(commentstr, "");
}else{
scriptstr = htmlStr;
}
//去掉字符串前后的空格
scriptstr = trimInnerSpaceStr(scriptstr);
//替换空格转义
scriptstr = scriptstr.replaceAll("&nbsp;", " ");
//转义双引号
scriptstr = scriptstr.replaceAll("&quot;", "\"");
//转义单引号
scriptstr = scriptstr.replaceAll("&#39;", "\'");
//转义链接符
scriptstr = scriptstr.replaceAll("&amp;", "&");
scriptstr = scriptstr.replaceAll("&lt;", "<");
scriptstr = scriptstr.replaceAll("&gt;", ">");
return scriptstr;
}
/***
* 去掉字符串前后的空格中间的空格保留
* @param str
* @return
*/
public static String trimInnerSpaceStr(String str){
str = str.trim();
while(str.startsWith(" ")){
str = str.substring(1,str.length()).trim();
}
while(str.startsWith("&nbsp;")){
str = str.substring(6,str.length()).trim();
}
while(str.endsWith(" ")){
str = str.substring(0,str.length()-1).trim();
}
while(str.endsWith("&nbsp;")){
str = str.substring(0,str.length()-6).trim();
}
return str;
}
/**
* 当遇到参数中带了|字符串时在界面\\|进行转义
* @param str
* @param flag
* @return
*/
private static String replaceSpi(String str,int flag){
String replacestr="&brvbar_rep;";
if(null==str){
str = "";
}
String result=str;
if(str.contains("\\\\|")&&flag==0){
result=str.replace("\\\\|", replacestr);
}
if(str.contains(replacestr)&&flag==1){
result=str.replace(replacestr,"|");
}
return result;
}
public static void main(String[] args){
// TODO Auto-generated method stub
}
}
package luckyclient.execution.httpinterface.analyticsteps;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import luckyclient.execution.dispose.ChangString;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: AnalyticCase
* @Description: 解析单个用例中描述部分的脚本
* @author seagull
* @date 2017年7月14日 上午9:29:40
*
*/
public class InterfaceAnalyticCase{
/**
* 解析用例步骤
* @param projectcase 待解析用例对象
* @param step 用例步骤对象
* @param taskid 任务ID
* @param caselog 日志对象
* @return 返回解析的用例MAP
*/
public static Map<String,String> analyticCaseStep(ProjectCase projectcase,ProjectCaseSteps step,String taskid,serverOperation caselog, 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().trim(), variable, "包路径");
params.put("PackageName", packageName);
// 处理值传递
String functionName = ChangString.changparams(step.getStepOperation().trim(), 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) {
// 定义script的正则表达式
String regExscript = "<script[^>]*?>[\\s\\S]*?</script>";
// 定义style的正则表达式
String regExstyle = "<style[^>]*?>[\\s\\S]*?</style>";
// 定义HTML标签的正则表达式
String regExhtml = "<[^>]+>";
//定义空格回车换行符
String regExspace = "[\t\r\n]";
String scriptstr;
if (htmlStr!=null) {
Pattern pScript = Pattern.compile(regExscript, Pattern.CASE_INSENSITIVE);
Matcher mScript = pScript.matcher(htmlStr);
// 过滤script标签
htmlStr = mScript.replaceAll("");
Pattern pStyle = Pattern.compile(regExstyle, Pattern.CASE_INSENSITIVE);
Matcher mStyle = pStyle.matcher(htmlStr);
// 过滤style标签
htmlStr = mStyle.replaceAll("");
Pattern pHtml = Pattern.compile(regExhtml, Pattern.CASE_INSENSITIVE);
Matcher mHtml = pHtml.matcher(htmlStr);
// 过滤html标签
htmlStr = mHtml.replaceAll("");
Pattern pSpace = Pattern.compile(regExspace, Pattern.CASE_INSENSITIVE);
Matcher mSpace = pSpace.matcher(htmlStr);
// 过滤空格回车标签
htmlStr = mSpace.replaceAll("");
}
assert htmlStr != null;
if(htmlStr.contains("/*") && htmlStr.contains("*/")){
String commentstr = htmlStr.substring(htmlStr.trim().indexOf("/*"),htmlStr.indexOf("*/")+2);
//去注释
scriptstr = htmlStr.replace(commentstr, "");
}else{
scriptstr = htmlStr;
}
//去掉字符串前后的空格
scriptstr = trimInnerSpaceStr(scriptstr);
//替换空格转义
scriptstr = scriptstr.replaceAll("&nbsp;", " ");
//转义双引号
scriptstr = scriptstr.replaceAll("&quot;", "\"");
//转义单引号
scriptstr = scriptstr.replaceAll("&#39;", "'");
//转义链接符
scriptstr = scriptstr.replaceAll("&amp;", "&");
scriptstr = scriptstr.replaceAll("&lt;", "<");
scriptstr = scriptstr.replaceAll("&gt;", ">");
return scriptstr;
}
/***
* 去掉字符串前后的空格中间的空格保留
* @param str 待处理字符串
* @return 返回去掉空格后的结果
*/
public static String trimInnerSpaceStr(String str){
str = str.trim();
while(str.startsWith(" ")){
str = str.substring(1).trim();
}
while(str.startsWith("&nbsp;")){
str = str.substring(6).trim();
}
while(str.endsWith(" ")){
str = str.substring(0,str.length()-1).trim();
}
while(str.endsWith("&nbsp;")){
str = str.substring(0,str.length()-6).trim();
}
return str;
}
/**
* 当遇到参数中带了|字符串时在界面\\|进行转义
* @param str 待处理字符串
* @param flag 处理标识
* @return 返回处理后结果
*/
private static String replaceSpi(String str,int flag){
String replacestr="&brvbar_rep;";
if(null==str){
str = "";
}
String result=str;
if(str.contains("\\\\|")&&flag==0){
result=str.replace("\\\\|", replacestr);
}
if(str.contains(replacestr)&&flag==1){
result=str.replace(replacestr,"|");
}
return result;
}
public static void main(String[] args){
// TODO Auto-generated method stub
}
}

View File

@ -31,12 +31,10 @@ public class BaseWebDrive {
/**
* 进测试结果进行截图
* @param driver
* @param imgname
* @return
* @param driver 驱动
* @param imgname 图片名称
*/
public static Boolean webScreenShot(WebDriver driver,String imgname) {
Boolean result = false;
public static void webScreenShot(WebDriver driver, String imgname) {
String relativelyPath = System.getProperty("user.dir");
String pngpath=relativelyPath +File.separator+ "log"+File.separator+"ScreenShot" +File.separator+ imgname + ".png";
@ -51,19 +49,18 @@ public class BaseWebDrive {
scrFile.deleteOnExit();
LogUtil.APP
.info("已对当前界面进行截图操作,可通过用例执行界面的日志明细查看,也可以前往客户端上查看...【{}】",pngpath);
return result;
}
/**
* 在自动化过程中加入点击显示效果
* @param driver
* @param element
* @param driver 驱动
* @param element 定位元素
* @author Seagull
* @date 2019年9月6日
*/
public static void highLightElement(WebDriver driver, WebElement element){
Properties properties = SysConfig.getConfiguration();
Boolean highLight = BooleanUtil.toBoolean(properties.getProperty("webdriver.highlight"));
boolean highLight = BooleanUtil.toBoolean(properties.getProperty("webdriver.highlight"));
if(highLight){
JavascriptExecutor js = (JavascriptExecutor) driver;

View File

@ -1,73 +1,73 @@
package luckyclient.execution.webdriver;
import java.util.List;
import org.openqa.selenium.WebDriver;
import luckyclient.execution.webdriver.ex.WebCaseExecution;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class CaseLocalDebug{
/**
* 单个用例Web UI调试
* @param wd
* @param testCaseExternalId
* @author Seagull
* @date 2020年1月20日
*/
public static void oneCasedebug(WebDriver wd,String testCaseExternalId){
//不记录日志到数据库
serverOperation.exetype = 1;
serverOperation caselog = new serverOperation();
try {
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist=GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
LogUtil.APP.info("开始执行用例:【{}】......",testCaseExternalId);
List<ProjectCaseSteps> steps=GetServerApi.getStepsbycaseid(testcase.getCaseId());
WebCaseExecution.caseExcution(testcase,steps, "888888",wd,caselog,pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
//关闭浏览器
wd.quit();
}
/**
* 多个用例串行Web UI调试
* @param wd
* @param projectname
* @param addtestcase
* @author Seagull
* @date 2020年1月20日
*/
public static void moreCaseDebug(WebDriver wd,String projectname,List<String> addtestcase){
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try{
LogUtil.APP.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(wd,testCaseExternalId);
}catch(Exception e){
continue;
}
}
}
}
package luckyclient.execution.webdriver;
import java.util.List;
import org.openqa.selenium.WebDriver;
import luckyclient.execution.webdriver.ex.WebCaseExecution;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class CaseLocalDebug{
/**
* 单个用例Web UI调试
* @param wd 驱动
* @param testCaseExternalId 用例编号
* @author Seagull
* @date 2020年1月20日
*/
public static void oneCasedebug(WebDriver wd,String testCaseExternalId){
//不记录日志到数据库
serverOperation.exetype = 1;
serverOperation caselog = new serverOperation();
try {
ProjectCase testcase = GetServerApi.cgetCaseBysign(testCaseExternalId);
List<ProjectCaseParams> pcplist=GetServerApi.cgetParamsByProjectid(String.valueOf(testcase.getProjectId()));
LogUtil.APP.info("开始执行用例:【{}】......",testCaseExternalId);
List<ProjectCaseSteps> steps=GetServerApi.getStepsbycaseid(testcase.getCaseId());
WebCaseExecution.caseExcution(testcase,steps, "888888",wd,caselog,pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
//关闭浏览器
wd.quit();
}
/**
* 多个用例串行Web UI调试
* @param wd 驱动
* @param projectname 项目名称
* @param addtestcase 用例集
* @author Seagull
* @date 2020年1月20日
*/
public static void moreCaseDebug(WebDriver wd,String projectname,List<String> addtestcase){
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try{
LogUtil.APP.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(wd,testCaseExternalId);
}catch(Exception e){
LogUtil.APP.error("用例运行出现异常,用例编号:{}",testCaseExternalId);
}
}
}
}

View File

@ -1,21 +0,0 @@
package luckyclient.execution.webdriver;
import java.io.IOException;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年8月8日
*/
public class TestGoogle {
public static void main(String[] args) throws InterruptedException, IOException {
// TODO Auto-generated method stub
}
}

View File

@ -1,132 +1,134 @@
package luckyclient.execution.webdriver;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerDriver;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebDriverInitialization{
private static final String OS=System.getProperty("os.name").toLowerCase();
/**
* 初始化WebDriver
* @param drivertype
* @return
* @throws WebDriverException
* @throws IOException
*/
public static WebDriver setWebDriverForTask(int drivertype) throws WebDriverException,IOException{
// 参数为空
File directory = new File("");
String drivenpath=directory.getCanonicalPath()+File.separator+"BrowserDriven"+File.separator;
WebDriver webDriver = null;
LogUtil.APP.info("准备初始化WebDriver对象...检查到当前操作系统是:{}",OS);
if(drivertype==0){
if(OS.startsWith("win")){
System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
webDriver = new InternetExplorerDriver();
}else{
LogUtil.APP.warn("当前操作系统无法进行IE浏览器的Web UI测试请选择火狐或是谷歌浏览器");
}
}else if(drivertype==1){
FirefoxOptions options = new FirefoxOptions();
if(OS.startsWith("win")){
System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver.exe");
}else if(OS.contains("mac")){
options.addArguments("start-maximized");
System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver_mac");
}else{
LogUtil.APP.info("检测到当前系统环境是Linux,默认使用headless方式运行Firefox浏览器的Web UI自动化...");
//无界面参数
options.setHeadless(true);
//禁用沙盒
options.addArguments("no-sandbox");
options.addArguments("start-maximized");
System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver_linux64");
}
webDriver = new FirefoxDriver(options);
}else if(drivertype==2){
ChromeOptions options = new ChromeOptions();
if(OS.startsWith("win")){
System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver.exe");
}else if(OS.contains("mac")){
options.addArguments("start-maximized");
System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver_mac");
}else{
LogUtil.APP.info("检测到当前系统环境是Linux,默认使用headless方式运行Chrome浏览器的Web UI自动化...");
//无界面参数
options.setHeadless(true);
//禁用沙盒
options.addArguments("no-sandbox");
options.addArguments("start-maximized");
System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver_linux64");
}
webDriver = new ChromeDriver(options);
}else if(drivertype==3){
if(OS.startsWith("win")){
System.setProperty("webdriver.edge.driver",drivenpath+"msedgedriver.exe");
webDriver = new EdgeDriver();
}else if(OS.contains("mac")){
System.setProperty("webdriver.edge.driver",drivenpath+"msedgedriver_mac");
webDriver = new EdgeDriver();
}else{
LogUtil.APP.warn("当前操作系统无法进行Edge浏览器的Web UI测试请选择火狐或是谷歌浏览器");
}
}else{
LogUtil.APP.warn("浏览器类型标识:{}获取到的浏览器类型标识未定义默认IE浏览器进行执行....",drivertype);
System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
webDriver = new InternetExplorerDriver();
}
//解决webdriver在unix环境中最大化会出现异常的bugunix最大化在options中单独设置
if(OS.startsWith("win")){
webDriver.manage().window().maximize();
}
//设置页面加载最大时长30秒
webDriver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
//设置元素出现最大时长30秒
webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return webDriver;
}
/**
* 初始化WebDriver
* @return
* @throws IOException
*/
public static WebDriver setWebDriverForLocal() throws IOException{
File directory = new File("");
String drivenpath=directory.getCanonicalPath()+File.separator+"BrowserDriven"+File.separator;
System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
WebDriver webDriver = new InternetExplorerDriver();
webDriver.manage().window().maximize();
//设置页面加载最大时长30秒
webDriver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
//设置元素出现最大时长30秒
webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return webDriver;
}
}
package luckyclient.execution.webdriver;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerDriver;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebDriverInitialization{
private static final String OS=System.getProperty("os.name").toLowerCase();
/**
* 初始化WebDriver
* @param drivertype 浏览器类型
* @return 返回初始化结果
* @throws WebDriverException 驱动抛出异常
* @throws IOException 读取配置文件异常
*/
public static WebDriver setWebDriverForTask(int drivertype) throws WebDriverException,IOException{
// 参数为空
File directory = new File("");
String drivenpath=directory.getCanonicalPath()+File.separator+"BrowserDriven"+File.separator;
WebDriver webDriver = null;
LogUtil.APP.info("准备初始化WebDriver对象...检查到当前操作系统是:{}",OS);
if(drivertype==0){
if(OS.startsWith("win")){
System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
webDriver = new InternetExplorerDriver();
}else{
LogUtil.APP.warn("当前操作系统无法进行IE浏览器的Web UI测试请选择火狐或是谷歌浏览器");
}
}else if(drivertype==1){
FirefoxOptions options = new FirefoxOptions();
if(OS.startsWith("win")){
System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver.exe");
}else if(OS.contains("mac")){
options.addArguments("start-maximized");
System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver_mac");
}else{
LogUtil.APP.info("检测到当前系统环境是Linux,默认使用headless方式运行Firefox浏览器的Web UI自动化...");
//无界面参数
options.setHeadless(true);
//禁用沙盒
options.addArguments("no-sandbox");
options.addArguments("start-maximized");
System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver_linux64");
}
webDriver = new FirefoxDriver(options);
}else if(drivertype==2){
ChromeOptions options = new ChromeOptions();
if(OS.startsWith("win")){
System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver.exe");
}else if(OS.contains("mac")){
options.addArguments("start-maximized");
System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver_mac");
}else{
LogUtil.APP.info("检测到当前系统环境是Linux,默认使用headless方式运行Chrome浏览器的Web UI自动化...");
//无界面参数
options.setHeadless(true);
//禁用沙盒
options.addArguments("no-sandbox");
options.addArguments("start-maximized");
System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver_linux64");
}
webDriver = new ChromeDriver(options);
}else if(drivertype==3){
if(OS.startsWith("win")){
System.setProperty("webdriver.edge.driver",drivenpath+"msedgedriver.exe");
webDriver = new EdgeDriver();
}else if(OS.contains("mac")){
System.setProperty("webdriver.edge.driver",drivenpath+"msedgedriver_mac");
webDriver = new EdgeDriver();
}else{
LogUtil.APP.warn("当前操作系统无法进行Edge浏览器的Web UI测试请选择火狐或是谷歌浏览器");
}
}else{
LogUtil.APP.warn("浏览器类型标识:{}获取到的浏览器类型标识未定义默认IE浏览器进行执行....",drivertype);
System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
webDriver = new InternetExplorerDriver();
}
//解决webdriver在unix环境中最大化会出现异常的bugunix最大化在options中单独设置
if(OS.startsWith("win")){
assert webDriver != null;
webDriver.manage().window().maximize();
}
//设置页面加载最大时长30秒
assert webDriver != null;
webDriver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
//设置元素出现最大时长30秒
webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return webDriver;
}
/**
* 初始化WebDriver
* @return 返回初始化结果
* @throws IOException 读取配置文件异常
*/
public static WebDriver setWebDriverForLocal() throws IOException{
File directory = new File("");
String drivenpath=directory.getCanonicalPath()+File.separator+"BrowserDriven"+File.separator;
System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
WebDriver webDriver = new InternetExplorerDriver();
webDriver.manage().window().maximize();
//设置页面加载最大时长30秒
webDriver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
//设置元素出现最大时长30秒
webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return webDriver;
}
}

View File

@ -39,7 +39,7 @@ public class WebTestControl {
/**
* 控制台模式调度计划执行用例
* @param planname
* @param planname ¼Æ»®Ãû³Æ
*/
public static void manualExecutionPlan(String planname) {
// 不记日志到数据库
@ -54,7 +54,7 @@ public class WebTestControl {
}
serverOperation caselog = new serverOperation();
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
List<ProjectCaseParams> pcplist = new ArrayList<>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
@ -69,14 +69,14 @@ public class WebTestControl {
LogUtil.APP.info("开始执行第{}条用例:【{}】......",i,testcase.getCaseSign());
try {
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
}
LogUtil.APP.info("当前项目测试计划中的用例已经全部执行完成...");
// 关闭浏览器
assert wd != null;
wd.quit();
}
@ -90,12 +90,12 @@ public class WebTestControl {
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(task.getProjectId().toString());
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId());
String projectname = taskScheduling.getProject().getProjectName();
task = GetServerApi.cgetTaskbyid(Integer.valueOf(taskid));
task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
String jobname = taskScheduling.getSchedulingName();
int drivertype = serverOperation.querydrivertype(taskid);
int[] tastcount = null;
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
if (restartstatus.contains("Status:true")) {
// 判断是否构建是否成功
if (BuildResult.SUCCESS.equals(buildResult)) {
WebDriver wd = null;
@ -123,7 +123,7 @@ public class WebTestControl {
// 插入开始执行的用例
caselog.insertTaskCaseExecute(taskid, taskScheduling.getProjectId(),testcase.getCaseId(),testcase.getCaseSign(), testcase.getCaseName(), 4);
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (InterruptedException e) {
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
@ -137,6 +137,7 @@ public class WebTestControl {
HtmlMail.htmlContentFormat(tastcount, taskid, buildResult.toString(), restartstatus, testtime, jobname),
taskid, taskScheduling, tastcount);
// 关闭浏览器
assert wd != null;
wd.quit();
} else {
LogUtil.APP.warn("项目构建失败自动化测试自动退出请前往JENKINS中检查项目构建情况。");

View File

@ -1,82 +1,80 @@
package luckyclient.execution.webdriver.ex;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import org.openqa.selenium.WebDriver;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.WebDriverInitialization;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebBatchExecute{
public static void batchCaseExecuteForTast(String projectname,String taskid,String batchcase) throws IOException{
//记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
int drivertype = serverOperation.querydrivertype(taskid);
WebDriver wd = null;
try {
wd = WebDriverInitialization.setWebDriverForTask(drivertype);
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
LogUtil.APP.error("初始化WebDriver出现异常", e1);
}
serverOperation caselog = new serverOperation();
TaskExecute task=GetServerApi.cgetTaskbyid(Integer.valueOf(taskid));
List<ProjectCaseParams> pcplist=GetServerApi.cgetParamsByProjectid(task.getProjectId().toString());
//执行全部非成功状态用例
if(batchcase.indexOf("ALLFAIL")>-1){
List<Integer> caseIdList = caselog.getCaseListForUnSucByTaskId(taskid);
for(int i=0;i<caseIdList.size();i++){
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseIdList.get(i));
List<ProjectCaseSteps> steps=GetServerApi.getStepsbycaseid(testcase.getCaseId());
//删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
WebCaseExecution.caseExcution(testcase, steps, taskid,wd,caselog,pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}else{ //批量执行用例
String[] temp=batchcase.split("\\#");
for(int i=0;i<temp.length;i++){
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(Integer.valueOf(temp[i]));
List<ProjectCaseSteps> steps=GetServerApi.getStepsbycaseid(testcase.getCaseId());
//删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
WebCaseExecution.caseExcution(testcase, steps,taskid,wd,caselog,pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
//关闭浏览器
wd.quit();
}
}
package luckyclient.execution.webdriver.ex;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import org.openqa.selenium.WebDriver;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.WebDriverInitialization;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebBatchExecute{
public static void batchCaseExecuteForTast(String taskid, String batchcase) throws IOException{
//记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
int drivertype = serverOperation.querydrivertype(taskid);
WebDriver wd = null;
try {
wd = WebDriverInitialization.setWebDriverForTask(drivertype);
} catch (MalformedURLException e1) {
LogUtil.APP.error("初始化WebDriver出现异常", e1);
}
serverOperation caselog = new serverOperation();
TaskExecute task=GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
List<ProjectCaseParams> pcplist=GetServerApi.cgetParamsByProjectid(task.getProjectId().toString());
//执行全部非成功状态用例
if(batchcase.contains("ALLFAIL")){
List<Integer> caseIdList = caselog.getCaseListForUnSucByTaskId(taskid);
for (Integer integer : caseIdList) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(integer);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
//删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}else{ //批量执行用例
String[] temp=batchcase.split("#");
for (String s : temp) {
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(Integer.valueOf(s));
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
//删除旧的日志
serverOperation.deleteTaskCaseLog(testcase.getCaseId(), taskid);
try {
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
//关闭浏览器
assert wd != null;
wd.quit();
}
}

View File

@ -1,336 +1,335 @@
package luckyclient.execution.webdriver.ex;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.execution.webdriver.BaseWebDrive;
import luckyclient.execution.webdriver.EncapsulateOperation;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年3月1日
*/
public class WebCaseExecution{
private static Map<String, String> variable = new HashMap<>();
private static String casenote = "备注初始化";
private static String imagname = "";
public static void caseExcution(ProjectCase testcase, List<ProjectCaseSteps> steps, String taskid, WebDriver wd, serverOperation caselog, List<ProjectCaseParams> pcplist) throws InterruptedException {
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 0:成功 1:失败 2:锁定 其他锁定
int setcaseresult = 0;
for (ProjectCaseSteps step : steps) {
Map<String, String> params;
String result;
// 根据步骤类型来分析步骤参数
if (1 == step.getStepType()){
params = WebDriverAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog, variable);
}else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog, variable);
}
// 判断分析步骤参数是否有异常
if (null != params.get("exception") && params.get("exception").contains("解析异常")) {
setcaseresult = 2;
break;
}
// 根据步骤类型来执行步骤
if (1 == step.getStepType()){
result = runWebStep(params, wd, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
}else{
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.runStep(params, taskid, testcase.getCaseSign(), step, caselog);
}
String expectedResults = params.get("ExpectedResults");
// 判断结果
int stepresult = judgeResult(testcase, step, params, wd, taskid, expectedResults, result, caselog);
// 失败并且不在继续,直接终止
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) {
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 != operation && null != operationValue && "runcase".equals(operation)) {
String[] temp = operationValue.split(",", -1);
TestCaseExecution testCaseExecution=new TestCaseExecution();
String ex = testCaseExecution.oneCaseExecuteForUICase(temp[0], taskid, caselog, wd);
if (!ex.contains("CallCase调用出错") && !ex.contains("解析出错啦!") && !ex.contains("失败")) {
return ex;
} else {
return "步骤执行失败:"+ex;
}
}
// 页面元素层
if (null != property && null != propertyValue && null != operation) {
WebElement we = isElementExist(wd, property, propertyValue);
//判断元素是否存在关键字
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) {
try {
WebElement we = null;
property = property.toLowerCase();
// 处理WebElement对象定位
switch (property) {
case "id":
we = wd.findElement(By.id(propertyValue));
break;
case "name":
we = wd.findElement(By.name(propertyValue));
break;
case "xpath":
we = wd.findElement(By.xpath(propertyValue));
break;
case "linktext":
we = wd.findElement(By.linkText(propertyValue));
break;
case "tagname":
we = wd.findElement(By.tagName(propertyValue));
break;
case "cssselector":
we = wd.findElement(By.cssSelector(propertyValue));
break;
default:
break;
}
return we;
} catch (Exception e) {
LogUtil.APP.error("当前对象定位失败!",e);
return null;
}
}
public static int judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, WebDriver driver, String taskid, String expect, String result, serverOperation caselog) throws InterruptedException {
int setresult = 0;
java.text.DateFormat timeformat = new java.text.SimpleDateFormat("MMdd-hhmmss");
imagname = timeformat.format(new Date());
result = ActionManageForSteps.actionManage(step.getAction(), result);
if (null != result && !result.contains("步骤执行失败:")) {
// 有预期结果
if (null != expect && !expect.isEmpty()) {
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() + "步,没有在当前页面中找到预期结果中对象。执行失败!";
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() + "步,模糊匹配预期结果失败!";
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() + "步,正则匹配预期结果失败!";
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 {
casenote = "" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
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 : "";
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 setresult;
}
package luckyclient.execution.webdriver.ex;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.TestCaseExecution;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.execution.webdriver.BaseWebDrive;
import luckyclient.execution.webdriver.EncapsulateOperation;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.Constants;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2018年3月1日
*/
public class WebCaseExecution{
private static Map<String, String> variable = new HashMap<>();
private static String casenote = "备注初始化";
public static void caseExcution(ProjectCase testcase, List<ProjectCaseSteps> steps, String taskid, WebDriver wd, serverOperation caselog, List<ProjectCaseParams> pcplist) {
caselog.updateTaskCaseExecuteStatus(taskid, testcase.getCaseId(), 3);
// 把公共参数加入到MAP中
for (ProjectCaseParams pcp : pcplist) {
variable.put(pcp.getParamsName(), pcp.getParamsValue());
}
// 加入全局变量
variable.putAll(ParamsManageForSteps.GLOBAL_VARIABLE);
// 0:成功 1:失败 2:锁定 其他锁定
int setcaseresult = 0;
for (ProjectCaseSteps step : steps) {
Map<String, String> params;
String result;
// 根据步骤类型来分析步骤参数
if (1 == step.getStepType()){
params = WebDriverAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog, variable);
}else{
params = InterfaceAnalyticCase.analyticCaseStep(testcase, step, taskid, caselog, variable);
}
// 判断分析步骤参数是否有异常
if (null != params.get("exception") && params.get("exception").contains("解析异常")) {
setcaseresult = 2;
break;
}
// 根据步骤类型来执行步骤
if (1 == step.getStepType()){
result = runWebStep(params, wd, taskid, testcase.getCaseId(), step.getStepSerialNumber(), caselog);
}else{
TestCaseExecution testCaseExecution=new TestCaseExecution();
result = testCaseExecution.runStep(params, taskid, testcase.getCaseSign(), step, caselog);
}
String expectedResults = params.get("ExpectedResults");
// 判断结果
int stepresult = judgeResult(testcase, step, params, wd, taskid, expectedResults, result, caselog);
// 失败并且不在继续,直接终止
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) {
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.oneCaseExecuteForUICase(temp[0], taskid, caselog, wd);
if (!ex.contains("CallCase调用出错") && !ex.contains("解析出错啦!") && !ex.contains("失败")) {
return ex;
} else {
return "步骤执行失败:"+ex;
}
}
// 页面元素层
if (null != property && null != propertyValue && null != operation) {
WebElement we = isElementExist(wd, property, propertyValue);
//判断元素是否存在关键字
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) {
try {
WebElement we = null;
property = property.toLowerCase();
// 处理WebElement对象定位
switch (property) {
case "id":
we = wd.findElement(By.id(propertyValue));
break;
case "name":
we = wd.findElement(By.name(propertyValue));
break;
case "xpath":
we = wd.findElement(By.xpath(propertyValue));
break;
case "linktext":
we = wd.findElement(By.linkText(propertyValue));
break;
case "tagname":
we = wd.findElement(By.tagName(propertyValue));
break;
case "cssselector":
we = wd.findElement(By.cssSelector(propertyValue));
break;
default:
break;
}
return we;
} catch (Exception e) {
LogUtil.APP.error("当前对象定位失败!",e);
return null;
}
}
public static int judgeResult(ProjectCase testcase, ProjectCaseSteps step, Map<String, String> params, WebDriver driver, String taskid, String expect, String result, serverOperation caselog) {
int setresult = 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()) {
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() + "步,没有在当前页面中找到预期结果中对象。执行失败!";
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() + "步,模糊匹配预期结果失败!";
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() + "步,正则匹配预期结果失败!";
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 {
casenote = "" + step.getStepSerialNumber() + "步,精确匹配预期结果失败!";
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 : "";
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 setresult;
}
}

View File

@ -1,193 +1,194 @@
package luckyclient.execution.webdriver.ex;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import luckyclient.execution.dispose.ChangString;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: AnalyticCase
* @Description: 解析单个用例中描述部分的脚本 @author seagull
* @date 2016年9月18日
*
*/
public class WebDriverAnalyticCase {
// private static String splitFlag = "\\|";
/**
* Web UI类型的步骤解析
*
* @param projectcase
* @param step
* @param taskid
* @param caselog
* @return
* @author Seagull
* @date 2019年1月17日
*/
public static Map<String, String> analyticCaseStep(ProjectCase projectcase, ProjectCaseSteps step, String taskid,
serverOperation caselog, Map<String, String> variable) {
Map<String, String> params = new HashMap<String, String>(0);
String resultstr = null;
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, path.length()).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 if (null != resultstr) {
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) throws InterruptedException {
// 定义script的正则表达式
String regExScript = "<script[^>]*?>[\\s\\S]*?<\\/script>";
// 定义style的正则表达式
String regExStyle = "<style[^>]*?>[\\s\\S]*?<\\/style>";
// 定义HTML标签的正则表达式
String regExHtml = "<[^>]+>";
// 定义空格回车换行符
String regExSpace = "\t|\r|\n";
String scriptstr = null;
if (htmlStr != null) {
Pattern pScript = Pattern.compile(regExScript, Pattern.CASE_INSENSITIVE);
Matcher mScript = pScript.matcher(htmlStr);
// 过滤script标签
htmlStr = mScript.replaceAll("");
Pattern pStyle = Pattern.compile(regExStyle, Pattern.CASE_INSENSITIVE);
Matcher mStyle = pStyle.matcher(htmlStr);
// 过滤style标签
htmlStr = mStyle.replaceAll("");
Pattern pHtml = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE);
Matcher mHtml = pHtml.matcher(htmlStr);
// 过滤html标签
htmlStr = mHtml.replaceAll("");
Pattern pSpace = Pattern.compile(regExSpace, Pattern.CASE_INSENSITIVE);
Matcher mSpace = pSpace.matcher(htmlStr);
// 过滤空格回车标签
htmlStr = mSpace.replaceAll("");
}
if (htmlStr.indexOf("/*") > -1 && htmlStr.indexOf("*/") > -1) {
String commentstr = htmlStr.substring(htmlStr.trim().indexOf("/*"), htmlStr.indexOf("*/") + 2);
// 去注释
scriptstr = htmlStr.replace(commentstr, "");
} else {
scriptstr = htmlStr;
}
// 去掉字符串前后的空格
scriptstr = trimInnerSpaceStr(scriptstr);
// 替换空格转义
scriptstr = scriptstr.replaceAll("&nbsp;", " ");
// 转义双引号
scriptstr = scriptstr.replaceAll("&quot;", "\"");
// 转义单引号
scriptstr = scriptstr.replaceAll("&#39;", "\'");
// 转义链接符
scriptstr = scriptstr.replaceAll("&amp;", "&");
scriptstr = scriptstr.replaceAll("&lt;", "<");
scriptstr = scriptstr.replaceAll("&gt;", ">");
return scriptstr;
}
/***
* 去掉字符串前后的空格中间的空格保留
*
* @param str
* @return
*/
public static String trimInnerSpaceStr(String str) {
str = str.trim();
while (str.startsWith(" ")) {
str = str.substring(1, str.length()).trim();
}
while (str.startsWith("&nbsp;")) {
str = str.substring(6, str.length()).trim();
}
while (str.endsWith(" ")) {
str = str.substring(0, str.length() - 1).trim();
}
while (str.endsWith("&nbsp;")) {
str = str.substring(0, str.length() - 6).trim();
}
return str;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package luckyclient.execution.webdriver.ex;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import luckyclient.execution.dispose.ChangString;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: AnalyticCase
* @Description: 解析单个用例中描述部分的脚本 @author seagull
* @date 2016年9月18日
*
*/
public class WebDriverAnalyticCase {
// private static String splitFlag = "\\|";
/**
* Web UI类型的步骤解析
*
* @param projectcase 用例对象
* @param step 用例步骤对象
* @param taskid 任务ID
* @param caselog 日志对象
* @return 返回解析结果MAP
* @author Seagull
* @date 2019年1月17日
*/
public static Map<String, String> analyticCaseStep(ProjectCase projectcase, ProjectCaseSteps step, String taskid,
serverOperation caselog, 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) {
// 定义script的正则表达式
String regExScript = "<script[^>]*?>[\\s\\S]*?</script>";
// 定义style的正则表达式
String regExStyle = "<style[^>]*?>[\\s\\S]*?</style>";
// 定义HTML标签的正则表达式
String regExHtml = "<[^>]+>";
// 定义空格回车换行符
String regExSpace = "[\t\r\n]";
String scriptstr;
if (htmlStr != null) {
Pattern pScript = Pattern.compile(regExScript, Pattern.CASE_INSENSITIVE);
Matcher mScript = pScript.matcher(htmlStr);
// 过滤script标签
htmlStr = mScript.replaceAll("");
Pattern pStyle = Pattern.compile(regExStyle, Pattern.CASE_INSENSITIVE);
Matcher mStyle = pStyle.matcher(htmlStr);
// 过滤style标签
htmlStr = mStyle.replaceAll("");
Pattern pHtml = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE);
Matcher mHtml = pHtml.matcher(htmlStr);
// 过滤html标签
htmlStr = mHtml.replaceAll("");
Pattern pSpace = Pattern.compile(regExSpace, Pattern.CASE_INSENSITIVE);
Matcher mSpace = pSpace.matcher(htmlStr);
// 过滤空格回车标签
htmlStr = mSpace.replaceAll("");
}
assert htmlStr != null;
if (htmlStr.contains("/*") && htmlStr.contains("*/")) {
String commentstr = htmlStr.substring(htmlStr.trim().indexOf("/*"), htmlStr.indexOf("*/") + 2);
// 去注释
scriptstr = htmlStr.replace(commentstr, "");
} else {
scriptstr = htmlStr;
}
// 去掉字符串前后的空格
scriptstr = trimInnerSpaceStr(scriptstr);
// 替换空格转义
scriptstr = scriptstr.replaceAll("&nbsp;", " ");
// 转义双引号
scriptstr = scriptstr.replaceAll("&quot;", "\"");
// 转义单引号
scriptstr = scriptstr.replaceAll("&#39;", "'");
// 转义链接符
scriptstr = scriptstr.replaceAll("&amp;", "&");
scriptstr = scriptstr.replaceAll("&lt;", "<");
scriptstr = scriptstr.replaceAll("&gt;", ">");
return scriptstr;
}
/***
* 去掉字符串前后的空格中间的空格保留
*
* @param str 原始字符串
* @return 返回去除结果
*/
public static String trimInnerSpaceStr(String str) {
str = str.trim();
while (str.startsWith(" ")) {
str = str.substring(1).trim();
}
while (str.startsWith("&nbsp;")) {
str = str.substring(6).trim();
}
while (str.endsWith(" ")) {
str = str.substring(0, str.length() - 1).trim();
}
while (str.endsWith("&nbsp;")) {
str = str.substring(0, str.length() - 6).trim();
}
return str;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}

View File

@ -1,60 +1,61 @@
package luckyclient.execution.webdriver.ex;
import java.io.IOException;
import java.util.List;
import org.openqa.selenium.WebDriver;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.WebDriverInitialization;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebOneCaseExecute{
public static void oneCaseExecuteForTast(String projectname,Integer caseId,int version,String taskid){
//记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
int drivertype = serverOperation.querydrivertype(taskid);
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, taskid,wd,caselog,pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (InterruptedException e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
serverOperation.updateTaskExecuteData(taskid, 0,2);
//关闭浏览器
wd.quit();
}
}
package luckyclient.execution.webdriver.ex;
import java.io.IOException;
import java.util.List;
import org.openqa.selenium.WebDriver;
import luckyclient.execution.httpinterface.TestControl;
import luckyclient.execution.webdriver.WebDriverInitialization;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebOneCaseExecute{
public static void oneCaseExecuteForTast(Integer caseId, String taskid){
//记录日志到数据库
serverOperation.exetype = 0;
TestControl.TASKID = taskid;
int drivertype = serverOperation.querydrivertype(taskid);
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, taskid,wd,caselog,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

@ -41,18 +41,14 @@ public class Ocr {
/**
* 批处理文件路径
*/
private static String cmdpath = System.getProperty("user.dir");
/**
* 默认把截图放在C盘根目录
*/
private static String cmdname = "handlingCAPTCHA.bat";
private static String cmdpath = System.getProperty("user.dir");
/**
* 读取生成的TXT文件中的验证码
* @return
* @return 返回结果
*/
private static String readTextFile() {
String lineTxt = "";
String lineTxt;
try {
String encoding = "GBK";
File file = new File(readtextpath);
@ -77,8 +73,8 @@ public class Ocr {
/**
* 截取验证码位置的图片
*
* @param
* @param driver webDriver驱动
* @param element 对象定位
*/
private static void screenShotForElement(WebDriver driver, WebElement element){
driver = new Augmenter().augment(driver);
@ -106,10 +102,12 @@ public class Ocr {
public static String getCAPTCHA(WebDriver driver, WebElement element) {
String code = "";
String code;
screenShotForElement(driver, element);
Runtime run = Runtime.getRuntime();
try {
//默认把截图放在C盘根目录
String cmdname = "handlingCAPTCHA.bat";
run.exec("cmd.exe /k start " + cmdname, null, new File(cmdpath));
Thread.sleep(1000);
} catch (IOException | InterruptedException e) {
@ -125,9 +123,5 @@ public class Ocr {
}*/
return code;
}
public static void main(String[] args) throws IOException, InterruptedException {
}
}

View File

@ -51,8 +51,6 @@ public class ClientHandler extends ChannelHandlerAdapter {
private static final String SERVER_PORT = SysConfig.getConfiguration().getProperty("server.web.port");
private int byteRead;
private volatile int lastLength = 0;
@ -61,15 +59,15 @@ public class ClientHandler extends ChannelHandlerAdapter {
private static ChannelHandlerContext ctx;
public ClientHandler() throws IOException {
public ClientHandler() {
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException, InterruptedException {
public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
//统一转编码
String jsonStr = URLDecoder.decode(msg.toString(), "GBK");
//服务端消息处理,如果接收到测试任务方法则直接产生一个http请求并发送请求到本地
JSONObject json = new JSONObject();
JSONObject json;
try {
json = JSON.parseObject(jsonStr);
@ -80,41 +78,37 @@ public class ClientHandler extends ChannelHandlerAdapter {
log.info("收到服务端消息:" + json.toString());
//解析消息
if ("run".equals(json.get("method"))) {
try {
//返回请求
JSONObject re = new JSONObject();
re.put("method", "return");
Result result = new Result(1, "同步等待消息返回", json.get("uuid").toString(), null);
//如果是调度请求则发起一个HTTP请求
//获取是get方法还是post方法
String getOrPost = json.get("getOrPost").toString();
String urlParam = "http://127.0.0.1:" + port + "/" + json.get("url").toString();
Integer socketTimeout = Integer.valueOf(json.get("socketTimeout").toString());
String tmpResult = "";
if ("get".equals(getOrPost)) {
@SuppressWarnings("unchecked")
Map<String, Object> jsonparams = (Map<String, Object>) json.get("data");
//get方法
try {
tmpResult = HttpRequest.httpClientGet(urlParam, jsonparams, socketTimeout);
} catch (Exception e) {
log.error("转发服务端GET请求出错");
}
} else {
String jsonparams = json.get("data").toString();
//post方法
try {
tmpResult = HttpRequest.httpClientPost(urlParam, jsonparams, socketTimeout);
} catch (Exception e) {
log.error("转发服务端POST请求出错");
}
//返回请求
JSONObject re = new JSONObject();
re.put("method", "return");
Result result = new Result(1, "同步等待消息返回", json.get("uuid").toString(), null);
//如果是调度请求则发起一个HTTP请求
//获取是get方法还是post方法
String getOrPost = json.get("getOrPost").toString();
String urlParam = "http://127.0.0.1:" + port + "/" + json.get("url").toString();
Integer socketTimeout = Integer.valueOf(json.get("socketTimeout").toString());
String tmpResult = "";
if ("get".equals(getOrPost)) {
@SuppressWarnings("unchecked")
Map<String, Object> jsonparams = (Map<String, Object>) json.get("data");
//get方法
try {
tmpResult = HttpRequest.httpClientGet(urlParam, jsonparams, socketTimeout);
} catch (Exception e) {
log.error("转发服务端GET请求出错");
}
} else {
String jsonparams = json.get("data").toString();
//post方法
try {
tmpResult = HttpRequest.httpClientPost(urlParam, jsonparams, socketTimeout);
} catch (Exception e) {
log.error("转发服务端POST请求出错");
}
result.setMessage(tmpResult);
re.put("data", result);
sendMessage(re.toString());
} catch (InterruptedException e) {
e.printStackTrace();
}
result.setMessage(tmpResult);
re.put("data", result);
sendMessage(re.toString());
} else if ("download".equals(json.get("method"))) {
String loadpath = json.get("path").toString();
String path = System.getProperty("user.dir") + loadpath;
@ -147,7 +141,7 @@ public class ClientHandler extends ChannelHandlerAdapter {
String fileName = jsonparams.get("imgName").toString();
String ctxPath = System.getProperty("user.dir") + File.separator + "log" + File.separator + "ScreenShot" + File.separator + fileName;
File file = new File(ctxPath);
int start = Integer.valueOf(json.get("start").toString());
int start = Integer.parseInt(json.get("start").toString());
FileUploadFile fileUploadFile = new FileUploadFile();
fileUploadFile.setFile(file);
if (start != -1) {
@ -164,6 +158,7 @@ public class ClientHandler extends ChannelHandlerAdapter {
log.info("文件长度:" + (randomAccessFile.length()) + ",start:" + start + ",a:" + a + ",b:" + b + ",lastLength:" + lastLength);
byte[] bytes = new byte[lastLength];
log.info("bytes的长度是=" + bytes.length);
int byteRead;
if ((byteRead = randomAccessFile.read(bytes)) != -1 && (randomAccessFile.length() - start) > 0) {
log.info("byteRead = " + byteRead);
fileUploadFile.setEndPos(byteRead);
@ -209,7 +204,7 @@ public class ClientHandler extends ChannelHandlerAdapter {
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
public void channelActive(ChannelHandlerContext ctx) {
//发送客户端登录消息
JSONObject json = new JSONObject();
json.put("hostName", NETTY_HOST);
@ -226,14 +221,11 @@ public class ClientHandler extends ChannelHandlerAdapter {
log.info("连接已断开,正在尝试重连...");
//使用过程中断线重连
final EventLoop eventLoop = ctx.channel().eventLoop();
eventLoop.schedule(new Runnable() {
@Override
public void run() {
try {
NettyClient.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
eventLoop.schedule(() -> {
try {
NettyClient.start();
} catch (Exception e) {
log.error("链接出现异常,正在尝试重连...",e);
}
}, 1, TimeUnit.SECONDS);
@ -252,7 +244,7 @@ public class ClientHandler extends ChannelHandlerAdapter {
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
if (event.state().equals(IdleState.READER_IDLE)) {
/**发送心跳,保持长连接*/
//发送心跳,保持长连接
JSONObject json = new JSONObject();
json.put("method", "ping");
json.put("hostName", NETTY_HOST);
@ -264,7 +256,7 @@ public class ClientHandler extends ChannelHandlerAdapter {
super.userEventTriggered(ctx, evt);
}
public static void sendMessage(String json) throws InterruptedException {
public static void sendMessage(String json) {
ctx.channel().writeAndFlush(Unpooled.copiedBuffer((json + "$_").getBytes()));
}

View File

@ -1,12 +1,10 @@
package luckyclient.netty;
import org.apache.http.HttpEntity;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
@ -19,9 +17,7 @@ import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Map.Entry;
@ -29,19 +25,15 @@ public class HttpRequest {
private static final Logger log = LoggerFactory.getLogger(HttpRequest.class);
/**
* 使用HttpClient以JSON格式发送post请求
* @param urlParam
* @param jsonparams
* @param socketTimeout
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws UnsupportedEncodingException
* @throws IOException
* @param urlParam 请求地址
* @param jsonparams 请求参数
* @param socketTimeout 超时时间
* @return 返回请求结果
* @author Seagull
* @date 2019年5月14日
*/
public static String httpClientPost(String urlParam,String jsonparams,Integer socketTimeout) throws NoSuchAlgorithmException, KeyManagementException, UnsupportedEncodingException, IOException{
StringBuffer resultBuffer = null;
public static String httpClientPost(String urlParam,String jsonparams,Integer socketTimeout) throws IOException{
StringBuffer resultBuffer;
CloseableHttpClient httpclient= HttpClients.createDefault();
HttpPost httpPost = new HttpPost(urlParam);
RequestConfig requestConfig = RequestConfig.custom()
@ -62,7 +54,7 @@ public class HttpRequest {
// 读取服务器响应数据
resultBuffer = new StringBuffer();
if(null!=response.getEntity()){
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8));
String temp;
while ((temp = br.readLine()) != null) {
resultBuffer.append(temp);
@ -79,8 +71,7 @@ public class HttpRequest {
try {
br.close();
} catch (IOException e) {
br = null;
throw new RuntimeException(e);
log.error("关闭流出现异常...",e);
}
}
}
@ -89,22 +80,19 @@ public class HttpRequest {
/**
* 使用HttpClient以JSON格式发送get请求
* @param urlParam
* @param params
* @param socketTimeout
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws NoHttpResponseException
* @param urlParam 请求地址
* @param params 请求参数
* @param socketTimeout 超时时间
* @return 返回请求结果
* @author Seagull
* @date 2019年5月14日
*/
public static String httpClientGet(String urlParam, Map<String, Object> params,Integer socketTimeout) throws NoSuchAlgorithmException, KeyManagementException, NoHttpResponseException {
StringBuffer resultBuffer = null;
public static String httpClientGet(String urlParam, Map<String, Object> params,Integer socketTimeout) {
StringBuffer resultBuffer;
CloseableHttpClient httpclient= HttpClients.createDefault();
BufferedReader br = null;
// 构建请求参数
StringBuffer sbParams = new StringBuffer();
StringBuilder sbParams = new StringBuilder();
if (params != null && params.size() > 0) {
for (Entry<String, Object> entry : params.entrySet()) {
sbParams.append(entry.getKey());
@ -117,7 +105,7 @@ public class HttpRequest {
sbParams.append("&");
}
}
if (sbParams != null && sbParams.length() > 0) {
if (sbParams.length() > 0) {
urlParam = urlParam + "?" + sbParams.substring(0, sbParams.length() - 1);
}
HttpGet httpGet = new HttpGet(urlParam);
@ -129,7 +117,7 @@ public class HttpRequest {
CloseableHttpResponse response = httpclient.execute(httpGet);
// 读取服务器响应数据
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8));
String temp;
resultBuffer = new StringBuffer();
while ((temp = br.readLine()) != null) {
@ -142,8 +130,7 @@ public class HttpRequest {
try {
br.close();
} catch (IOException e) {
br = null;
throw new RuntimeException(e);
log.error("关闭流出现异常...",e);
}
}
}
@ -153,18 +140,15 @@ public class HttpRequest {
/**
* 上传文件
* @param urlParam
* @param loadpath
* @param file
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws HttpHostConnectException
* @param urlParam 请求地址
* @param loadpath 文件加载路径
* @param file 文件对象
* @return 返回上传结果
* @author Seagull
* @date 2019年3月15日
*/
public static String httpClientUploadFile(String urlParam, String loadpath, File file) throws NoSuchAlgorithmException, KeyManagementException, HttpHostConnectException {
StringBuffer resultBuffer = null;
public static String httpClientUploadFile(String urlParam, String loadpath, File file) {
StringBuffer resultBuffer;
CloseableHttpClient httpclient= HttpClients.createDefault();
HttpPost httpPost = new HttpPost(urlParam);
// 构建请求参数
@ -172,7 +156,7 @@ public class HttpRequest {
try {
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
//设置请求的编码格式
entityBuilder.setCharset(Charset.forName("utf-8"));
entityBuilder.setCharset(StandardCharsets.UTF_8);
entityBuilder.addBinaryBody("jarfile", file);
entityBuilder.addTextBody("loadpath", loadpath);
HttpEntity reqEntity =entityBuilder.build();
@ -184,13 +168,13 @@ public class HttpRequest {
// 读取服务器响应数据
resultBuffer = new StringBuffer();
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8));
String temp;
while ((temp = br.readLine()) != null) {
resultBuffer.append(temp);
}
if(resultBuffer.length()==0){
resultBuffer.append("上传文件异常,响应码:"+responsecode);
resultBuffer.append("上传文件异常,响应码:").append(responsecode);
}
} catch (Exception e) {
throw new RuntimeException(e);
@ -199,8 +183,7 @@ public class HttpRequest {
try {
br.close();
} catch (IOException e) {
br = null;
throw new RuntimeException(e);
log.error("关闭流出现异常...",e);
}
}
}
@ -209,17 +192,15 @@ public class HttpRequest {
/**
* 获取文件流
* @param urlParam
* @param params
* @return
* @throws IOException
* @throws HttpHostConnectException
* @param urlParam 请求地址
* @param params 请求参数
* @return 返回获取到的文件流
* @author Seagull
* @date 2019年3月15日
*/
public static byte[] getFile(String urlParam, Map<String, Object> params) throws IOException, HttpHostConnectException {
public static byte[] getFile(String urlParam, Map<String, Object> params) throws IOException {
// 构建请求参数
StringBuffer sbParams = new StringBuffer();
StringBuilder sbParams = new StringBuilder();
if (params != null && params.size() > 0) {
for (Entry<String, Object> entry : params.entrySet()) {
sbParams.append(entry.getKey());
@ -232,7 +213,7 @@ public class HttpRequest {
sbParams.append("&");
}
}
if (sbParams != null && sbParams.length() > 0) {
if (sbParams.length() > 0) {
urlParam = urlParam + "?" + sbParams.substring(0, sbParams.length() - 1);
}
URL urlConet = new URL(urlParam);
@ -242,23 +223,21 @@ public class HttpRequest {
InputStream inStream = con .getInputStream(); //通过输入流获取图片数据
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int len = 0;
int len;
while( (len=inStream.read(buffer)) != -1 ){
outStream.write(buffer, 0, len);
}
inStream.close();
byte[] data = outStream.toByteArray();
return data;
return outStream.toByteArray();
}
/**
* 从网络Url中下载文件
* @param urlStr
* @param fileName
* @param savePath
* @throws IOException
* @param urlStr 请求地址
* @param fileName 文件名
* @param savePath 保存路径
*/
public static boolean downLoadFromUrl(String urlStr,String fileName,String savePath) throws IOException{
public static void downLoadFromUrl(String urlStr, String fileName, String savePath) {
try
{
URL url = new URL(urlStr);
@ -281,28 +260,21 @@ public class HttpRequest {
File file = new File(saveDir+File.separator+fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(getData);
if(fos!=null){
fos.close();
}
if(inputStream!=null){
inputStream.close();
}
return true;
fos.close();
inputStream.close();
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 从输入流中获取字节数组
* @param inputStream
* @return
* @throws IOException
* @param inputStream 字节流
* @return 返回字节
*/
public static byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
int len;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);

View File

@ -1,23 +1,9 @@
package luckyclient.netty;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
@ -26,6 +12,12 @@ import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import luckyclient.utils.config.SysConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
public class NettyClient {
private static final String NETTY_SERVER_IP= SysConfig.getConfiguration().getProperty("server.web.ip");
@ -34,61 +26,46 @@ public class NettyClient {
protected static Channel channel;
private static ChannelFuture connect;
private static final Logger log = LoggerFactory.getLogger(NettyClient.class);
private static ClientHandler clientHandler;
public static void start() throws InterruptedException{
public static void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
clientHandler=new ClientHandler();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE,true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
ChannelPipeline p = ch.pipeline();
p.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
p.addLast("decoder", new StringDecoder(Charset.forName("UTF-8")));
p.addLast("encoder", new StringEncoder(Charset.forName("GBK")));
p.addLast(new IdleStateHandler(1,0,0,TimeUnit.SECONDS));
p.addLast(clientHandler);
}
});
//连接服务端
connect = b.connect(NETTY_SERVER_IP, NETTY_SERVER_PORT);
//断线重连
connect.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (!channelFuture.isSuccess()) {
final EventLoop loop = channelFuture.channel().eventLoop();
loop.schedule(new Runnable() {
@Override
public void run() {
try {
log.error("服务端链接不上,开始重连操作...");
start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 1L, TimeUnit.SECONDS);
} else {
channel = channelFuture.channel();
log.info("服务端链接成功...");
Bootstrap b = new Bootstrap();
clientHandler=new ClientHandler();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE,true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
ChannelPipeline p = ch.pipeline();
p.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
p.addLast("decoder", new StringDecoder(StandardCharsets.UTF_8));
p.addLast("encoder", new StringEncoder(Charset.forName("GBK")));
p.addLast(new IdleStateHandler(1,0,0,TimeUnit.SECONDS));
p.addLast(clientHandler);
}
}
});
} catch (IOException e) {
e.printStackTrace();
} finally {
//不关闭通道
//group.shutdownGracefully();
}
});
//连接服务端
ChannelFuture connect = b.connect(NETTY_SERVER_IP, NETTY_SERVER_PORT);
//断线重连
connect.addListener((ChannelFutureListener) channelFuture -> {
if (!channelFuture.isSuccess()) {
final EventLoop loop = channelFuture.channel().eventLoop();
loop.schedule(() -> {
try {
log.error("服务端链接不上,开始重连操作...");
start();
} catch (Exception ignored) {
}
}, 1L, TimeUnit.SECONDS);
} else {
channel = channelFuture.channel();
log.info("服务端链接成功...");
}
});
}
}

View File

@ -1,20 +1,12 @@
package luckyclient.remote.api;
import java.io.UnsupportedEncodingException;
import java.util.List;
import com.alibaba.fastjson.JSONObject;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.remote.entity.ProjectCaseParams;
import luckyclient.remote.entity.ProjectCaseSteps;
import luckyclient.remote.entity.ProjectProtocolTemplate;
import luckyclient.remote.entity.ProjectTemplateParams;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.remote.entity.*;
import luckyclient.utils.httputils.HttpRequest;
import java.util.List;
/**
* =================================================================
@ -33,85 +25,78 @@ public class GetServerApi {
/**
* 通过计划ID获取测试用例对象集
* @param planId
* @return
* @param planId 测试计划ID
* @return 返回用例List
*/
public static List<ProjectCase> getCasesbyplanId(int planId) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetCaseListByPlanId.do?planId=" + planId);
List<ProjectCase> caseList = JSONObject.parseArray(result, ProjectCase.class);
return caseList;
String result = HttpRequest.loadJSON(PREFIX+"/clientGetCaseListByPlanId.do?planId=" + planId);
return JSONObject.parseArray(result, ProjectCase.class);
}
/**
* 通过计划名称获取测试用例对象集
* @param name
* @return
* @param name 测试计划名称
* @return 返回用例List
*/
public static List<ProjectCase> getCasesbyplanname(String name) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetCaseListByPlanName.do?planName=" + name);
List<ProjectCase> caseList = JSONObject.parseArray(result, ProjectCase.class);
return caseList;
return JSONObject.parseArray(result, ProjectCase.class);
}
/**
* 通过用例ID获取下面的步骤对象
* @param caseid
* @return
* @param caseid 用例ID
* @return 返回用例步骤List
*/
public static List<ProjectCaseSteps> getStepsbycaseid(Integer caseid) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetStepListByCaseId.do?caseId=" + caseid);
List<ProjectCaseSteps> stepsList = JSONObject.parseArray(result, ProjectCaseSteps.class);
return stepsList;
return JSONObject.parseArray(result, ProjectCaseSteps.class);
}
/**
* 通过taskid获取对象
* @param taskid
* @return
* @param taskid 测试任务ID
* @return 返回测试任务对象
*/
public static TaskExecute cgetTaskbyid(int taskid) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetTaskByTaskId.do?taskId=" + taskid);
TaskExecute task = JSONObject.parseObject(result, TaskExecute.class);
return task;
return JSONObject.parseObject(result, TaskExecute.class);
}
/**
* 通过taskid获取调度对象
* @param taskid
* @return
* @param taskid 测试任务ID
* @return 返回调度对象
*/
public static TaskScheduling cGetTaskSchedulingByTaskId(int taskid) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetTaskSchedulingByTaskId.do?taskId=" + taskid);
TaskScheduling taskScheduling = JSONObject.parseObject(result, TaskScheduling.class);
return taskScheduling;
return JSONObject.parseObject(result, TaskScheduling.class);
}
/**
* 通过用例编号获取对象
* @param sign
* @return
* @param sign 用例编号
* @return 用例对象
*/
public static ProjectCase cgetCaseBysign(String sign) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetCaseByCaseSign.do?caseSign=" + sign);
ProjectCase projectCase = JSONObject.parseObject(result, ProjectCase.class);
return projectCase;
return JSONObject.parseObject(result, ProjectCase.class);
}
/**
* 通过用例ID获取对象
* @param caseId
* @return
* @param caseId 用例ID
* @return 用例对象
*/
public static ProjectCase cGetCaseByCaseId(Integer caseId) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetCaseByCaseId.do?caseId=" + caseId);
ProjectCase projectCase = JSONObject.parseObject(result, ProjectCase.class);
return projectCase;
return JSONObject.parseObject(result, ProjectCase.class);
}
/**
* 获取项目下的所有公共参数
* @param projectid
* @return
* @param projectid 项目ID
* @return 公共参数集合
*/
public static List<ProjectCaseParams> cgetParamsByProjectid(String projectid) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetParamsByProjectId.do?projectId="+projectid);
@ -125,43 +110,36 @@ public class GetServerApi {
/**
* 通过计划ID获取测试用例对象集
* @param taskId
* @return
* @param taskId 测试任务ID
* @return 测试用例ID集合
*/
public static List<Integer> clientGetCaseListForUnSucByTaskId(Integer taskId) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetCaseListForUnSucByTaskId.do?taskId=" + taskId);
List<Integer> caseIdList = JSONObject.parseArray(result, Integer.class);
return caseIdList;
String result = HttpRequest.loadJSON(PREFIX+"/clientGetCaseListForUnSucByTaskId.do?taskId=" + taskId);
return JSONObject.parseArray(result, Integer.class);
}
/**
* 通过templateId获取实体
* @param templateId
* @return
* @param templateId 模板ID
* @return 协议模板对象
* @author Seagull
* @date 2019年4月24日
*/
public static ProjectProtocolTemplate clientGetProjectProtocolTemplateByTemplateId(Integer templateId) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetProjectProtocolTemplateByTemplateId.do?templateId=" + templateId);
ProjectProtocolTemplate projectProtocolTemplate = JSONObject.parseObject(result, ProjectProtocolTemplate.class);
return projectProtocolTemplate;
return JSONObject.parseObject(result, ProjectProtocolTemplate.class);
}
/**
* 通过模板ID获取参数列表
* @param templateId
* @return
* @param templateId 模板ID
* @return 参数集合
* @author Seagull
* @date 2019年4月24日
*/
public static List<ProjectTemplateParams> clientGetProjectTemplateParamsListByTemplateId(Integer templateId) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetProjectTemplateParamsListByTemplateId.do?templateId=" + templateId);
List<ProjectTemplateParams> projectTemplateParamsList = JSONObject.parseArray(result, ProjectTemplateParams.class);
return projectTemplateParamsList;
}
public static void main(String[] args) throws UnsupportedEncodingException {
return JSONObject.parseArray(result, ProjectTemplateParams.class);
}
}

View File

@ -24,11 +24,11 @@ public class PostServerApi {
/**
* put web界面的数据到服务端
* @param userId
* @param caseId
* @param logLevel
* @param logDetail
* @param debugIsend
* @param userId 用户ID
* @param caseId 用例ID
* @param logLevel 日志级别
* @param logDetail 日志明细
* @param debugIsend 结束标志
*/
public static void cPostDebugLog(Integer userId, Integer caseId, String logLevel, String logDetail,Integer debugIsend){
ProjectCaseDebug projectCaseDebug = new ProjectCaseDebug();
@ -43,12 +43,12 @@ public class PostServerApi {
/**
* 插入用例执行明细到数据库
* @param taskId
* @param projectId
* @param caseId
* @param caseSign
* @param caseName
* @param caseStatus
* @param taskId 任务ID
* @param projectId 项目ID
* @param caseId 用例ID
* @param caseSign 用例编号
* @param caseName 用例名称
* @param caseStatus 用例状态
* @author Seagull
* @date 2019年4月22日
*/
@ -66,9 +66,9 @@ public class PostServerApi {
/**
* 修改用例执行状态
* @param taskId
* @param caseId
* @param caseStatus
* @param taskId 任务ID
* @param caseId 用例ID
* @param caseStatus 用例状态
* @author Seagull
* @date 2019年4月22日
*/
@ -83,12 +83,12 @@ public class PostServerApi {
/**
* 插入用例执行明细到数据库
* @param taskId
* @param caseId
* @param logDetail
* @param logGrade
* @param logStep
* @param imgname
* @param taskId 任务ID
* @param caseId 用例ID
* @param logDetail 日志明细
* @param logGrade 日志等级
* @param logStep 日志对应步骤
* @param imgname 截图名称
* @author Seagull
* @date 2019年4月22日
*/
@ -107,10 +107,10 @@ public class PostServerApi {
/**
* 更新任务执行数据
* @param taskId
* @param caseCount
* @param taskStatus
* @return
* @param taskId 任务ID
* @param caseCount 用例总数
* @param taskStatus 任务状态
* @return 更新结果
*/
public static String clientUpdateTaskExecuteData(Integer taskId, Integer caseCount, Integer taskStatus){
String str = "{\"taskId\":"+taskId+",\"caseCount\":"+caseCount+",\"taskStatus\":"+taskStatus+"}";
@ -119,22 +119,21 @@ public class PostServerApi {
}
/**
* ¸üÐÂÈÎÎñÖ´ÐÐÊý¾Ý
* @param taskId
* @param caseId
* @return
* 删除用例执行日志
* @param taskId 任务ID
* @param caseId 用例ID
*/
public static String clientDeleteTaskCaseLog(Integer taskId, Integer caseId){
public static void clientDeleteTaskCaseLog(Integer taskId, Integer caseId){
String str = "{\"taskId\":"+taskId+",\"caseId\":"+caseId+"}";
JSONObject jsonObject = JSON.parseObject(str);
return HttpRequest.httpClientPostJson(PREFIX+"/clientDeleteTaskCaseLog", jsonObject.toJSONString());
HttpRequest.httpClientPostJson(PREFIX + "/clientDeleteTaskCaseLog", jsonObject.toJSONString());
}
/**
* 提取测试用例的详细日志以及结果
* @param taskName
* @param caseSign
* @return
* @param taskName 任务名称
* @param caseSign 用例编号
* @return 提取结果
*/
public static String getLogDetailResult(String taskName, String caseSign){
String str = "{\"taskName\":\""+taskName+"\",\"caseSign\":\""+caseSign+"\"}";

View File

@ -1,262 +1,262 @@
package luckyclient.remote.api;
import java.util.Date;
import java.util.List;
import com.alibaba.fastjson.JSONObject;
import cn.hutool.core.util.StrUtil;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年4月23日
*/
public class serverOperation {
/**
* 任务执行类型 0 任务调度模式 1 控制台模式
*/
public static int exetype;
/**
* 插入用例执行状态 0通过 1失败 2锁定 3执行中 4未执行
*/
public void insertTaskCaseExecute(String taskIdStr, Integer projectId,Integer caseId, String caseSign,String caseName, Integer caseStatus) {
if (0 == exetype) {
Integer taskId=Integer.valueOf(taskIdStr);
PostServerApi.clientPostInsertTaskCaseExecute(taskId, projectId, caseId, caseSign, caseName, caseStatus);
}
}
/**
* 更新用例执行状态 0通过 1失败 2锁定 3执行中 4未执行
*/
public void updateTaskCaseExecuteStatus(String taskIdStr, Integer caseId, Integer caseStatus) {
if (0 == exetype) {
Integer taskId=Integer.valueOf(taskIdStr);
PostServerApi.clientUpdateTaskCaseExecuteStatus(taskId, caseId, caseStatus);
}
}
/**
* 插入用例执行日志
*/
public void insertTaskCaseLog(String taskIdStr, Integer caseId, String logDetail, String logGrade, String logStep,
String imgname) {
if (0 == exetype) {
if (logDetail.length()>5000) {
LogUtil.APP.info("第{}步,日志级别{},日志明细【{}】...日志明细超过5000字符无法进入数据库存储进行日志明细打印...",logStep,logGrade,logDetail);
logDetail="日志明细超过5000字符无法存入数据库已在LOG4J日志中打印请前往查看...";
}
Integer taskId=Integer.valueOf(taskIdStr);
PostServerApi.clientPostInsertTaskCaseLog(taskId, caseId, logDetail, logGrade, logStep, imgname);
}
}
/**
* 更新本次任务的执行统计情况
* 状态 0未执行 1执行中 2执行完成 3执行失败 4唤起客户端失败
*/
public static int[] updateTaskExecuteData(String taskIdStr, int caseCount, int taskStatus) {
int[] taskcount = null;
if (0 == exetype) {
Integer taskId = Integer.parseInt(taskIdStr);
String str = PostServerApi.clientUpdateTaskExecuteData(taskId, caseCount,taskStatus);
JSONObject jsonObject = JSONObject.parseObject(str);
// 返回本次任务执行情况
taskcount = new int[5];
taskcount[0] = jsonObject.getInteger("caseCount");
taskcount[1] = jsonObject.getInteger("caseSuc");
taskcount[2] = jsonObject.getInteger("caseFail");
taskcount[3] = jsonObject.getInteger("caseLock");
taskcount[4] = jsonObject.getInteger("caseNoExec");
}
return taskcount;
}
/**
* 更新本次任务的执行状态
* 状态 0未执行 1执行中 2执行完成 3执行失败 4唤起客户端失败
*/
public static void updateTaskExecuteStatusIng(String taskIdStr, int caseCount) {
if (0 == exetype) {
Integer taskId = Integer.parseInt(taskIdStr);
PostServerApi.clientUpdateTaskExecuteData(taskId, caseCount,1);
}
}
/**
* 删除单次任务指定的用例日志明细
*/
public static void deleteTaskCaseLog(Integer caseId, String taskIdStr) {
Integer taskId = Integer.parseInt(taskIdStr);
PostServerApi.clientDeleteTaskCaseLog(taskId, caseId);
}
/**
* 取出指定任务ID中的不属于成功状态的用例ID
*/
public List<Integer> getCaseListForUnSucByTaskId(String taskIdStr) {
int taskId = Integer.parseInt(taskIdStr);
return GetServerApi.clientGetCaseListForUnSucByTaskId(taskId);
}
/**
* 取出指定任务ID中所属的调度是否要发送邮件状态及收件人地址 发送邮件通知时的具体逻辑, -1-不通知 0-全部1-成功2-失败
* 发送 eMailer varchar(100) ; --收件人
*/
public static String[] getEmailAddress(String taskIdStr) {
Integer taskId = Integer.parseInt(taskIdStr);
String[] address = null;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
if (!taskScheduling.getEmailSendCondition().equals(-1)) {
String temp = taskScheduling.getEmailAddress();
// 清除最后一个;
if (temp.indexOf(";") > -1 && temp.substring(temp.length() - 1, temp.length()).indexOf(";") > -1) {
temp = temp.substring(0, temp.length() - 1);
}
// 多个地址
if (temp.indexOf("null") <= -1 && temp.indexOf(";") > -1) {
address = temp.split(";", -1);
// 一个地址
} else if (temp.indexOf("null") <= -1 && temp.indexOf(";") <= -1) {
address = new String[1];
address[0] = temp;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取邮件收件人地址出现异常,请检查!",e);
return address;
}
return address;
}
/**
* 取出指定任务ID中所属的调度是否要自动构建以及构建的项目名称 为空时不构建
*/
public static String[] getBuildName(String taskIdStr) {
Integer taskId = Integer.parseInt(taskIdStr);
String[] buildname = null;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
if (StrUtil.isEmpty(taskScheduling.getBuildingLink())) {
return buildname;
}else{
String jobName = taskScheduling.getBuildingLink();
// 清除最后一个;
if (jobName.indexOf(";") > -1 && jobName.substring(jobName.length() - 1, jobName.length()).indexOf(";") > -1) {
jobName = jobName.substring(0, jobName.length() - 1);
}
// 多个名称
if (jobName.indexOf("null") <= -1 && jobName.indexOf(";") > -1) {
buildname = jobName.split(";", -1);
// 一个名称
} else if (jobName.indexOf("null") <= -1 && jobName.indexOf(";") <= -1) {
buildname = new String[1];
buildname[0] = jobName;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取构建地址出现异常,请检查!",e);
return buildname;
}
return buildname;
}
/**
* 取出指定任务ID中所属的调度是否要自动重启TOMCAT
* 自动重启 restartcomm varchar(200) ; -- 格式服务器IP;服务器用户名;服务器密码;ssh端口;Shell命令;
* 192.168.222.22;pospsettle;pospsettle;22;cd
* /home/pospsettle/tomcat-7.0-7080/bin&&./restart.sh;
*/
public static String[] getRestartComm(String taskIdStr) {
Integer taskId = Integer.parseInt(taskIdStr);
String[] command = null;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
if (null == taskScheduling.getRemoteShell() || "".equals(taskScheduling.getRemoteShell())) {
return command;
}else{
String temp = taskScheduling.getRemoteShell();
// 清除最后一个;
if (temp.indexOf(";") > -1 && temp.substring(temp.length() - 1, temp.length()).indexOf(";") > -1) {
temp = temp.substring(0, temp.length() - 1);
}
// 多个名称
if (temp.indexOf("null") <= -1 && temp.indexOf(";") > -1) {
command = temp.split(";", -1);
// 一个名称
} else if (temp.indexOf("null") <= -1 && temp.indexOf(";") <= -1) {
command = new String[1];
command[0] = temp;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取远程shell地址出现异常请检查",e);
return command;
}
return command;
}
/**
* 获取任务测试时长
*/
public static String getTestTime(String taskIdStr) {
Integer taskId = Integer.parseInt(taskIdStr);
String desTime = "计算测试时长出错!";
try {
TaskExecute taskExecute = GetServerApi.cgetTaskbyid(taskId);
Date start = taskExecute.getCreateTime();
if (null!= taskExecute.getFinishTime()) {
Date finish = taskExecute.getFinishTime();
long l = finish.getTime() - start.getTime();
long day = l / (24 * 60 * 60 * 1000);
long hour = (l / (60 * 60 * 1000) - day * 24);
long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
desTime = "<font color='#2828FF'>" + hour + "</font>小时<font color='#2828FF'>" + min
+ "</font>分<font color='#2828FF'>" + s + "</font>秒";
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取任务测试时长出现异常,请检查!",e);
return desTime;
}
return desTime;
}
/**
* 查询web执行浏览器类型 UI自动化浏览器类型 0 IE 1 火狐 2 谷歌 3 Edge
*/
public static int querydrivertype(String taskIdStr) {
Integer taskId = Integer.parseInt(taskIdStr);
int driverType = 0;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
driverType = taskScheduling.getBrowserType();
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取浏览器类型出现异常,请检查!",e);
return driverType;
}
return driverType;
}
}
package luckyclient.remote.api;
import java.util.Date;
import java.util.List;
import com.alibaba.fastjson.JSONObject;
import cn.hutool.core.util.StrUtil;
import luckyclient.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.utils.LogUtil;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年4月23日
*/
public class serverOperation {
/**
* 任务执行类型 0 任务调度模式 1 控制台模式
*/
public static int exetype;
/**
* 插入用例执行状态 0通过 1失败 2锁定 3执行中 4未执行
*/
public void insertTaskCaseExecute(String taskIdStr, Integer projectId,Integer caseId, String caseSign,String caseName, Integer caseStatus) {
if (0 == exetype) {
Integer taskId=Integer.valueOf(taskIdStr);
PostServerApi.clientPostInsertTaskCaseExecute(taskId, projectId, caseId, caseSign, caseName, caseStatus);
}
}
/**
* 更新用例执行状态 0通过 1失败 2锁定 3执行中 4未执行
*/
public void updateTaskCaseExecuteStatus(String taskIdStr, Integer caseId, Integer caseStatus) {
if (0 == exetype) {
Integer taskId=Integer.valueOf(taskIdStr);
PostServerApi.clientUpdateTaskCaseExecuteStatus(taskId, caseId, caseStatus);
}
}
/**
* 插入用例执行日志
*/
public void insertTaskCaseLog(String taskIdStr, Integer caseId, String logDetail, String logGrade, String logStep,
String imgname) {
if (0 == exetype) {
if (logDetail.length()>5000) {
LogUtil.APP.info("第{}步,日志级别{},日志明细【{}】...日志明细超过5000字符无法进入数据库存储进行日志明细打印...",logStep,logGrade,logDetail);
logDetail="日志明细超过5000字符无法存入数据库已在LOG4J日志中打印请前往查看...";
}
Integer taskId=Integer.valueOf(taskIdStr);
PostServerApi.clientPostInsertTaskCaseLog(taskId, caseId, logDetail, logGrade, logStep, imgname);
}
}
/**
* 更新本次任务的执行统计情况
* 状态 0未执行 1执行中 2执行完成 3执行失败 4唤起客户端失败
*/
public static int[] updateTaskExecuteData(String taskIdStr, int caseCount, int taskStatus) {
int[] taskcount = null;
if (0 == exetype) {
Integer taskId = Integer.parseInt(taskIdStr);
String str = PostServerApi.clientUpdateTaskExecuteData(taskId, caseCount,taskStatus);
JSONObject jsonObject = JSONObject.parseObject(str);
// 返回本次任务执行情况
taskcount = new int[5];
taskcount[0] = jsonObject.getInteger("caseCount");
taskcount[1] = jsonObject.getInteger("caseSuc");
taskcount[2] = jsonObject.getInteger("caseFail");
taskcount[3] = jsonObject.getInteger("caseLock");
taskcount[4] = jsonObject.getInteger("caseNoExec");
}
return taskcount;
}
/**
* 更新本次任务的执行状态
* 状态 0未执行 1执行中 2执行完成 3执行失败 4唤起客户端失败
*/
public static void updateTaskExecuteStatusIng(String taskIdStr, int caseCount) {
if (0 == exetype) {
Integer taskId = Integer.parseInt(taskIdStr);
PostServerApi.clientUpdateTaskExecuteData(taskId, caseCount,1);
}
}
/**
* 删除单次任务指定的用例日志明细
*/
public static void deleteTaskCaseLog(Integer caseId, String taskIdStr) {
Integer taskId = Integer.parseInt(taskIdStr);
PostServerApi.clientDeleteTaskCaseLog(taskId, caseId);
}
/**
* 取出指定任务ID中的不属于成功状态的用例ID
*/
public List<Integer> getCaseListForUnSucByTaskId(String taskIdStr) {
int taskId = Integer.parseInt(taskIdStr);
return GetServerApi.clientGetCaseListForUnSucByTaskId(taskId);
}
/**
* 取出指定任务ID中所属的调度是否要发送邮件状态及收件人地址 发送邮件通知时的具体逻辑, -1-不通知 0-全部1-成功2-失败
* 发送 eMailer varchar(100) ; --收件人
*/
public static String[] getEmailAddress(String taskIdStr) {
int taskId = Integer.parseInt(taskIdStr);
String[] address = null;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
if (!taskScheduling.getEmailSendCondition().equals(-1)) {
String temp = taskScheduling.getEmailAddress();
// 清除最后一个;
if (temp.contains(";") && temp.substring(temp.length() - 1).contains(";")) {
temp = temp.substring(0, temp.length() - 1);
}
// 多个地址
if (!temp.contains("null") && temp.contains(";")) {
address = temp.split(";", -1);
// 一个地址
} else if (!temp.contains("null") && !temp.contains(";")) {
address = new String[1];
address[0] = temp;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取邮件收件人地址出现异常,请检查!",e);
return address;
}
return address;
}
/**
* 取出指定任务ID中所属的调度是否要自动构建以及构建的项目名称 为空时不构建
*/
public static String[] getBuildName(String taskIdStr) {
int taskId = Integer.parseInt(taskIdStr);
String[] buildname = null;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
if (StrUtil.isEmpty(taskScheduling.getBuildingLink())) {
return buildname;
}else{
String jobName = taskScheduling.getBuildingLink();
// 清除最后一个;
if (jobName.contains(";") && jobName.substring(jobName.length() - 1).contains(";")) {
jobName = jobName.substring(0, jobName.length() - 1);
}
// 多个名称
if (!jobName.contains("null") && jobName.contains(";")) {
buildname = jobName.split(";", -1);
// 一个名称
} else if (!jobName.contains("null") && !jobName.contains(";")) {
buildname = new String[1];
buildname[0] = jobName;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取构建地址出现异常,请检查!",e);
return buildname;
}
return buildname;
}
/**
* 取出指定任务ID中所属的调度是否要自动重启TOMCAT
* 自动重启 restartcomm varchar(200) ; -- 格式服务器IP;服务器用户名;服务器密码;ssh端口;Shell命令;
* 192.168.222.22;pospsettle;pospsettle;22;cd
* /home/pospsettle/tomcat-7.0-7080/bin&&./restart.sh;
*/
public static String[] getRestartComm(String taskIdStr) {
int taskId = Integer.parseInt(taskIdStr);
String[] command = null;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
if (null == taskScheduling.getRemoteShell() || "".equals(taskScheduling.getRemoteShell())) {
return command;
}else{
String temp = taskScheduling.getRemoteShell();
// 清除最后一个;
if (temp.contains(";") && temp.substring(temp.length() - 1).contains(";")) {
temp = temp.substring(0, temp.length() - 1);
}
// 多个名称
if (!temp.contains("null") && temp.contains(";")) {
command = temp.split(";", -1);
// 一个名称
} else if (!temp.contains("null") && !temp.contains(";")) {
command = new String[1];
command[0] = temp;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取远程shell地址出现异常请检查",e);
return command;
}
return command;
}
/**
* 获取任务测试时长
*/
public static String getTestTime(String taskIdStr) {
int taskId = Integer.parseInt(taskIdStr);
String desTime = "计算测试时长出错!";
try {
TaskExecute taskExecute = GetServerApi.cgetTaskbyid(taskId);
Date start = taskExecute.getCreateTime();
if (null!= taskExecute.getFinishTime()) {
Date finish = taskExecute.getFinishTime();
long l = finish.getTime() - start.getTime();
long day = l / (24 * 60 * 60 * 1000);
long hour = (l / (60 * 60 * 1000) - day * 24);
long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
desTime = "<font color='#2828FF'>" + hour + "</font>小时<font color='#2828FF'>" + min
+ "</font>分<font color='#2828FF'>" + s + "</font>秒";
}
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取任务测试时长出现异常,请检查!",e);
return desTime;
}
return desTime;
}
/**
* 查询web执行浏览器类型 UI自动化浏览器类型 0 IE 1 火狐 2 谷歌 3 Edge
*/
public static int querydrivertype(String taskIdStr) {
int taskId = Integer.parseInt(taskIdStr);
int driverType = 0;
try {
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(taskId);
driverType = taskScheduling.getBrowserType();
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("获取浏览器类型出现异常,请检查!",e);
return driverType;
}
return driverType;
}
}

View File

@ -1,202 +1,197 @@
package luckyclient.remote.entity.monitor;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
/**
* 获取IP方法
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年5月5日
*/
public class IpUtils
{
public static String getIpAddr(HttpServletRequest request)
{
if (request == null)
{
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
public static boolean internalIp(String ip)
{
byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip);
}
private static boolean internalIp(byte[] addr)
{
final byte b0 = addr[0];
final byte b1 = addr[1];
// 10.x.x.x/8
final byte section1 = 0x0A;
// 172.16.x.x/12
final byte section2 = (byte) 0xAC;
final byte section3 = (byte) 0x10;
final byte section4 = (byte) 0x1F;
// 192.168.x.x/16
final byte section5 = (byte) 0xC0;
final byte section6 = (byte) 0xA8;
switch (b0)
{
case section1:
return true;
case section2:
if (b1 >= section3 && b1 <= section4)
{
return true;
}
case section5:
switch (b1)
{
case section6:
return true;
default:
return false;
}
default:
return false;
}
}
/**
* 将IPv4地址转换成字节
*
* @param text IPv4地址
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text)
{
if (text.length() == 0)
{
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try
{
long l;
int i;
switch (elements.length)
{
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L)){
return null;
}
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L)){
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L)){
return null;
}
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)){
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L)){
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)){
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
}
catch (NumberFormatException e)
{
return null;
}
return bytes;
}
public static String getHostIp()
{
try
{
return InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException e)
{
}
return "127.0.0.1";
}
public static String getHostName()
{
try
{
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
}
return "未知";
}
package luckyclient.remote.entity.monitor;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
/**
* 获取IP方法
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年5月5日
*/
public class IpUtils
{
public static String getIpAddr(HttpServletRequest request)
{
if (request == null)
{
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
public static boolean internalIp(String ip)
{
byte[] addr = textToNumericFormatV4(ip);
assert addr != null;
return internalIp(addr) || "127.0.0.1".equals(ip);
}
private static boolean internalIp(byte[] addr)
{
final byte b0 = addr[0];
final byte b1 = addr[1];
// 10.x.x.x/8
final byte section1 = 0x0A;
// 172.16.x.x/12
final byte section2 = (byte) 0xAC;
final byte section3 = (byte) 0x10;
final byte section4 = (byte) 0x1F;
// 192.168.x.x/16
final byte section5 = (byte) 0xC0;
final byte section6 = (byte) 0xA8;
switch (b0)
{
case section1:
return true;
case section2:
if (b1 >= section3 && b1 <= section4)
{
return true;
}
case section5:
return b1 == section6;
default:
return false;
}
}
/**
* 将IPv4地址转换成字节
*
* @param text IPv4地址
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text)
{
if (text.length() == 0)
{
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try
{
long l;
int i;
switch (elements.length)
{
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L)){
return null;
}
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L)){
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L)){
return null;
}
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)){
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L)){
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i)
{
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)){
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
}
catch (NumberFormatException e)
{
return null;
}
return bytes;
}
public static String getHostIp()
{
try
{
return InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException ignored)
{
}
return "127.0.0.1";
}
public static String getHostName()
{
try
{
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ignored)
{
}
return "未知";
}
}

View File

@ -1,238 +1,236 @@
package luckyclient.remote.entity.monitor;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
/**
* 服务器相关信息
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年5月5日
*/
public class Server
{
private static final int OSHI_WAIT_SECOND = 1000;
/**
* CPU相关信息
*/
private Cpu cpu = new Cpu();
/**
* 內存相关信息
*/
private Mem mem = new Mem();
/**
* JVM相关信息
*/
private Jvm jvm = new Jvm();
/**
* 服务器相关信息
*/
private Sys sys = new Sys();
/**
* 磁盘相关信息
*/
private List<SysFile> sysFiles = new LinkedList<SysFile>();
public Cpu getCpu()
{
return cpu;
}
public void setCpu(Cpu cpu)
{
this.cpu = cpu;
}
public Mem getMem()
{
return mem;
}
public void setMem(Mem mem)
{
this.mem = mem;
}
public Jvm getJvm()
{
return jvm;
}
public void setJvm(Jvm jvm)
{
this.jvm = jvm;
}
public Sys getSys()
{
return sys;
}
public void setSys(Sys sys)
{
this.sys = sys;
}
public List<SysFile> getSysFiles()
{
return sysFiles;
}
public void setSysFiles(List<SysFile> sysFiles)
{
this.sysFiles = sysFiles;
}
public void copyTo() throws Exception
{
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
setCpuInfo(hal.getProcessor());
setMemInfo(hal.getMemory());
setSysInfo();
setJvmInfo();
setSysFiles(si.getOperatingSystem());
}
/**
* 设置CPU信息
*/
private void setCpuInfo(CentralProcessor processor)
{
// CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND);
long[] ticks = processor.getSystemCpuLoadTicks();
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
cpu.setCpuNum(processor.getLogicalProcessorCount());
cpu.setTotal(totalCpu);
cpu.setSys(cSys);
cpu.setUsed(user);
cpu.setWait(iowait);
cpu.setFree(idle);
}
/**
* 设置内存信息
*/
private void setMemInfo(GlobalMemory memory)
{
mem.setTotal(memory.getTotal());
mem.setUsed(memory.getTotal() - memory.getAvailable());
mem.setFree(memory.getAvailable());
}
/**
* 设置服务器信息
*/
private void setSysInfo()
{
Properties props = System.getProperties();
sys.setComputerName(IpUtils.getHostName());
sys.setComputerIp(IpUtils.getHostIp());
sys.setOsName(props.getProperty("os.name"));
sys.setOsArch(props.getProperty("os.arch"));
sys.setUserDir(props.getProperty("user.dir"));
}
/**
* 设置Java虚拟机
*/
private void setJvmInfo() throws UnknownHostException
{
Properties props = System.getProperties();
jvm.setTotal(Runtime.getRuntime().totalMemory());
jvm.setMax(Runtime.getRuntime().maxMemory());
jvm.setFree(Runtime.getRuntime().freeMemory());
jvm.setVersion(props.getProperty("java.version"));
jvm.setHome(props.getProperty("java.home"));
}
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os)
{
FileSystem fileSystem = os.getFileSystem();
OSFileStore[] fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray)
{
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
sysFiles.add(sysFile);
}
}
/**
* 字节转换
*
* @param size 字节大小
* @return 转换后值
*/
public String convertFileSize(long size)
{
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb)
{
return String.format("%.1f GB", (float) size / gb);
}
else if (size >= mb)
{
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
}
else if (size >= kb)
{
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
}
else
{
return String.format("%d B", size);
}
}
}
package luckyclient.remote.entity.monitor;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
/**
* 服务器相关信息
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年5月5日
*/
public class Server
{
private static final int OSHI_WAIT_SECOND = 1000;
/**
* CPU相关信息
*/
private Cpu cpu = new Cpu();
/**
* 內存相关信息
*/
private Mem mem = new Mem();
/**
* JVM相关信息
*/
private Jvm jvm = new Jvm();
/**
* 服务器相关信息
*/
private Sys sys = new Sys();
/**
* 磁盘相关信息
*/
private List<SysFile> sysFiles = new LinkedList<>();
public Cpu getCpu()
{
return cpu;
}
public void setCpu(Cpu cpu)
{
this.cpu = cpu;
}
public Mem getMem()
{
return mem;
}
public void setMem(Mem mem)
{
this.mem = mem;
}
public Jvm getJvm()
{
return jvm;
}
public void setJvm(Jvm jvm)
{
this.jvm = jvm;
}
public Sys getSys()
{
return sys;
}
public void setSys(Sys sys)
{
this.sys = sys;
}
public List<SysFile> getSysFiles()
{
return sysFiles;
}
public void setSysFiles(List<SysFile> sysFiles)
{
this.sysFiles = sysFiles;
}
public void copyTo() {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
setCpuInfo(hal.getProcessor());
setMemInfo(hal.getMemory());
setSysInfo();
setJvmInfo();
setSysFiles(si.getOperatingSystem());
}
/**
* 设置CPU信息
*/
private void setCpuInfo(CentralProcessor processor)
{
// CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND);
long[] ticks = processor.getSystemCpuLoadTicks();
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
cpu.setCpuNum(processor.getLogicalProcessorCount());
cpu.setTotal(totalCpu);
cpu.setSys(cSys);
cpu.setUsed(user);
cpu.setWait(iowait);
cpu.setFree(idle);
}
/**
* 设置内存信息
*/
private void setMemInfo(GlobalMemory memory)
{
mem.setTotal(memory.getTotal());
mem.setUsed(memory.getTotal() - memory.getAvailable());
mem.setFree(memory.getAvailable());
}
/**
* 设置服务器信息
*/
private void setSysInfo()
{
Properties props = System.getProperties();
sys.setComputerName(IpUtils.getHostName());
sys.setComputerIp(IpUtils.getHostIp());
sys.setOsName(props.getProperty("os.name"));
sys.setOsArch(props.getProperty("os.arch"));
sys.setUserDir(props.getProperty("user.dir"));
}
/**
* 设置Java虚拟机
*/
private void setJvmInfo() {
Properties props = System.getProperties();
jvm.setTotal(Runtime.getRuntime().totalMemory());
jvm.setMax(Runtime.getRuntime().maxMemory());
jvm.setFree(Runtime.getRuntime().freeMemory());
jvm.setVersion(props.getProperty("java.version"));
jvm.setHome(props.getProperty("java.home"));
}
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os)
{
FileSystem fileSystem = os.getFileSystem();
OSFileStore[] fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray)
{
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
sysFiles.add(sysFile);
}
}
/**
* 字节转换
*
* @param size 字节大小
* @return 转换后值
*/
public String convertFileSize(long size)
{
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb)
{
return String.format("%.1f GB", (float) size / gb);
}
else if (size >= mb)
{
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
}
else if (size >= kb)
{
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
}
else
{
return String.format("%d B", size);
}
}
}

View File

@ -1,73 +1,73 @@
package luckyclient.tool.jenkins;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.offbytwo.jenkins.model.BuildResult;
import luckyclient.remote.api.serverOperation;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class BuildingInitialization {
protected static int THREAD_COUNT = 0;
protected static int THREAD_SUCCOUNT = 0;
public static BuildResult buildingRun(String tastid) throws InterruptedException {
try {
String[] jobName = serverOperation.getBuildName(tastid);
if (jobName != null) {
ThreadPoolExecutor threadExecute = new ThreadPoolExecutor(jobName.length, 10, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000),
new ThreadPoolExecutor.CallerRunsPolicy());
LogUtil.APP.info("准备将配置的测试项目进行构建!请稍等。。。。");
for (int i = 0; i < jobName.length; i++) {
BuildingInitialization.THREAD_COUNT++; //多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForBuildJob(jobName[i]));
}
//多线程计数用于检测线程是否全部执行完
int k=0;
while(BuildingInitialization.THREAD_COUNT!=0){
k++;
//最长等待构建时间45分钟
if(k>2700){
break;
}
Thread.sleep(1000);
}
threadExecute.shutdown();
if(jobName.length!=THREAD_SUCCOUNT){
LogUtil.APP.info("待构建项目{}个,构建成功的项目{}个,有构建任务异常或失败状态,详情请查看构建日志...",jobName.length,THREAD_SUCCOUNT);
return BuildResult.FAILURE;
}else{
LogUtil.APP.info("总共构建成功的项目{}个,全部构建成功,详情请查看构建日志...",THREAD_SUCCOUNT);
}
} else {
LogUtil.APP.info("当前任务没有找到需要构建的项目!");
}
} catch (Exception e) {
LogUtil.APP.error("项目构建过程中出现异常", e);
return BuildResult.UNSTABLE;
}
return BuildResult.SUCCESS;
}
}
package luckyclient.tool.jenkins;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.offbytwo.jenkins.model.BuildResult;
import luckyclient.remote.api.serverOperation;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class BuildingInitialization {
protected static int THREAD_COUNT = 0;
protected static int THREAD_SUCCOUNT = 0;
public static BuildResult buildingRun(String tastid) {
try {
String[] jobName = serverOperation.getBuildName(tastid);
if (jobName != null) {
ThreadPoolExecutor threadExecute = new ThreadPoolExecutor(jobName.length, 10, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1000),
new ThreadPoolExecutor.CallerRunsPolicy());
LogUtil.APP.info("准备将配置的测试项目进行构建!请稍等。。。。");
for (String s : jobName) {
BuildingInitialization.THREAD_COUNT++; //多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForBuildJob(s));
}
//多线程计数用于检测线程是否全部执行完
int k=0;
while(BuildingInitialization.THREAD_COUNT!=0){
k++;
//最长等待构建时间45分钟
if(k>2700){
break;
}
Thread.sleep(1000);
}
threadExecute.shutdown();
if(jobName.length!=THREAD_SUCCOUNT){
LogUtil.APP.info("待构建项目{}个,构建成功的项目{}个,有构建任务异常或失败状态,详情请查看构建日志...",jobName.length,THREAD_SUCCOUNT);
return BuildResult.FAILURE;
}else{
LogUtil.APP.info("总共构建成功的项目{}个,全部构建成功,详情请查看构建日志...",THREAD_SUCCOUNT);
}
} else {
LogUtil.APP.info("当前任务没有找到需要构建的项目!");
}
} catch (Exception e) {
LogUtil.APP.error("项目构建过程中出现异常", e);
return BuildResult.UNSTABLE;
}
return BuildResult.SUCCESS;
}
}

View File

@ -1,70 +1,68 @@
package luckyclient.tool.jenkins;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.SysConfig;
/**
* Jenkins链接
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年10月29日
*/
public class JenkinsConnect {
private String JENKINS_URL;
private String JENKINS_USERNAME;
private String JENKINS_PASSWORD;
JenkinsConnect() {
Properties properties = SysConfig.getConfiguration();
this.JENKINS_URL=properties.getProperty("jenkins.url");
this.JENKINS_USERNAME=properties.getProperty("jenkins.username");
this.JENKINS_PASSWORD=properties.getProperty("jenkins.password");
}
/**
* 如果有些 API 该Jar工具包未提供可以用此Http客户端操作远程接口执行命令
* @return
* @author Seagull
* @date 2019年10月29日
*/
public JenkinsHttpClient getClient() {
JenkinsHttpClient jenkinsHttpClient = null;
try {
jenkinsHttpClient = new JenkinsHttpClient(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return jenkinsHttpClient;
}
/**
* Jenkins API链接
* @return
* @author Seagull
* @date 2019年10月29日
*/
public JenkinsServer connection() {
JenkinsServer jenkinsServer = null;
try {
LogUtil.APP.info("准备连接Jenkins...URL:{} 用户名:{} 密码:{}",JENKINS_URL,JENKINS_USERNAME,JENKINS_PASSWORD);
jenkinsServer = new JenkinsServer(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD);
LogUtil.APP.info("连接Jenkins成功");
LogUtil.APP.info("Jenkins版本:{}",jenkinsServer.getVersion());
} catch (URISyntaxException e) {
LogUtil.APP.error("连接Jenkins出现异常",e);
}
return jenkinsServer;
}
package luckyclient.tool.jenkins;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.client.JenkinsHttpClient;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.SysConfig;
/**
* Jenkins链接
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年10月29日
*/
public class JenkinsConnect {
private String JENKINS_URL;
private String JENKINS_USERNAME;
private String JENKINS_PASSWORD;
JenkinsConnect() {
Properties properties = SysConfig.getConfiguration();
this.JENKINS_URL=properties.getProperty("jenkins.url");
this.JENKINS_USERNAME=properties.getProperty("jenkins.username");
this.JENKINS_PASSWORD=properties.getProperty("jenkins.password");
}
/**
* 如果有些 API 该Jar工具包未提供可以用此Http客户端操作远程接口执行命令
* @return 返回jenkins客户端对象
*/
public JenkinsHttpClient getClient() {
JenkinsHttpClient jenkinsHttpClient = null;
try {
jenkinsHttpClient = new JenkinsHttpClient(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return jenkinsHttpClient;
}
/**
* Jenkins API链接
* @return 返回jenkins服务对象
* @author Seagull
* @date 2019年10月29日
*/
public JenkinsServer connection() {
JenkinsServer jenkinsServer = null;
try {
LogUtil.APP.info("准备连接Jenkins...URL:{} 用户名:{} 密码:{}",JENKINS_URL,JENKINS_USERNAME,JENKINS_PASSWORD);
jenkinsServer = new JenkinsServer(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD);
LogUtil.APP.info("连接Jenkins成功");
LogUtil.APP.info("Jenkins版本:{}",jenkinsServer.getVersion());
} catch (URISyntaxException e) {
LogUtil.APP.error("连接Jenkins出现异常",e);
}
return jenkinsServer;
}
}

View File

@ -1,94 +1,94 @@
package luckyclient.tool.jenkins;
import java.io.IOException;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.BuildResult;
import com.offbytwo.jenkins.model.BuildWithDetails;
import com.offbytwo.jenkins.model.ConsoleLog;
import com.offbytwo.jenkins.model.JobWithDetails;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import luckyclient.utils.LogUtil;
/**
* * Job Build(任务构建) 相关操作 例如对任务 Build 相关的信息进行获取操作例如获取构建日志
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
*
* @author Seagull
* @date 2019年10月30日
*/
public class JobBuildApi {
// Jenkins 对象
private JenkinsServer jenkinsServer;
// http 客户端对象
//private JenkinsHttpClient jenkinsHttpClient;
/**
* 构造方法中调用连接 Jenkins 方法
*
* 2019年10月30日
*/
JobBuildApi() {
JenkinsConnect jenkinsConnect = new JenkinsConnect();
// 连接 Jenkins
jenkinsServer = jenkinsConnect.connection();
// 设置客户端连接 Jenkins
//jenkinsHttpClient = jenkinsConnect.getClient();
}
/**
* 通过job名称触发构建并获取构建结果
* @param jobName
* @return
* @author Seagull
* @date 2019年11月29日
*/
public BuildResult buildAndGetResultForJobName(String jobName) {
BuildResult buildResult = null;
try {
//触发构建
jenkinsServer.getJob(jobName).build(false);
// 获取 Job 信息
JobWithDetails job = jenkinsServer.getJob(jobName);
// 这里用最后一次编译来示例
BuildWithDetails build = job.getLastBuild().details();
// 获取构建的显示名称
LogUtil.APP.info("构建项目:{}, 构建名称:{}", jobName,build.getDisplayName());
// 获取构建的参数信息
LogUtil.APP.info("构建项目:{}, 构建参数:{}", jobName,build.getParameters());
// 获取构建编号
LogUtil.APP.info("构建项目:{}, 构建编号:{}", jobName,build.getNumber());
// 获取执行构建的活动信息
LogUtil.APP.info("构建项目:{}, 构建活动信息:{}", jobName,build.getActions());
// 获取构建开始时间戳
LogUtil.APP.info("构建项目:{}, 构建时间:{}", jobName,DateUtil.format(DateUtil.date(build.getTimestamp()), "yyyy-MM-dd HH:mm:ss"));
// 当前日志
ConsoleLog currentLog = build.getConsoleOutputText(0);
// 输出当前获取日志信息
//LogUtil.APP.info(currentLog.getConsoleLog());
// 检测是否还有更多日志,如果是则继续循环获取
while (currentLog.getHasMoreData()) {
// 获取最新日志信息
ConsoleLog newLog = build.getConsoleOutputText(currentLog.getCurrentBufferSize());
// 输出最新日志
if(!StrUtil.isBlank(newLog.getConsoleLog())){
LogUtil.APP.info("构建项目:{}, 构建日志:{}",jobName,newLog.getConsoleLog());
}
currentLog = newLog;
}
buildResult = job.getBuildByNumber(build.getNumber()).details().getResult();
LogUtil.APP.info("构建项目:{}, 构建结果:>>>>>>>>>{}",jobName,buildResult.toString());
} catch (IOException e) {
LogUtil.APP.error("获取执行任务状态出现异常", e);
}
return buildResult;
}
}
package luckyclient.tool.jenkins;
import java.io.IOException;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.BuildResult;
import com.offbytwo.jenkins.model.BuildWithDetails;
import com.offbytwo.jenkins.model.ConsoleLog;
import com.offbytwo.jenkins.model.JobWithDetails;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import luckyclient.utils.LogUtil;
/**
* * Job Build(任务构建) 相关操作 例如对任务 Build 相关的信息进行获取操作例如获取构建日志
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
*
* @author Seagull
* @date 2019年10月30日
*/
public class JobBuildApi {
// Jenkins 对象
private JenkinsServer jenkinsServer;
// http 客户端对象
//private JenkinsHttpClient jenkinsHttpClient;
/**
* 构造方法中调用连接 Jenkins 方法
*
* 2019年10月30日
*/
JobBuildApi() {
JenkinsConnect jenkinsConnect = new JenkinsConnect();
// 连接 Jenkins
jenkinsServer = jenkinsConnect.connection();
// 设置客户端连接 Jenkins
//jenkinsHttpClient = jenkinsConnect.getClient();
}
/**
* 通过job名称触发构建并获取构建结果
* @param jobName 任务名称
* @return 返回构建结果
* @author Seagull
* @date 2019年11月29日
*/
public BuildResult buildAndGetResultForJobName(String jobName) {
BuildResult buildResult = null;
try {
//触发构建
jenkinsServer.getJob(jobName).build(false);
// 获取 Job 信息
JobWithDetails job = jenkinsServer.getJob(jobName);
// 这里用最后一次编译来示例
BuildWithDetails build = job.getLastBuild().details();
// 获取构建的显示名称
LogUtil.APP.info("构建项目:{}, 构建名称:{}", jobName,build.getDisplayName());
// 获取构建的参数信息
LogUtil.APP.info("构建项目:{}, 构建参数:{}", jobName,build.getParameters());
// 获取构建编号
LogUtil.APP.info("构建项目:{}, 构建编号:{}", jobName,build.getNumber());
// 获取执行构建的活动信息
LogUtil.APP.info("构建项目:{}, 构建活动信息:{}", jobName,build.getActions());
// 获取构建开始时间戳
LogUtil.APP.info("构建项目:{}, 构建时间:{}", jobName,DateUtil.format(DateUtil.date(build.getTimestamp()), "yyyy-MM-dd HH:mm:ss"));
// 当前日志
ConsoleLog currentLog = build.getConsoleOutputText(0);
// 输出当前获取日志信息
//LogUtil.APP.info(currentLog.getConsoleLog());
// 检测是否还有更多日志,如果是则继续循环获取
while (currentLog.getHasMoreData()) {
// 获取最新日志信息
ConsoleLog newLog = build.getConsoleOutputText(currentLog.getCurrentBufferSize());
// 输出最新日志
if(!StrUtil.isBlank(newLog.getConsoleLog())){
LogUtil.APP.info("构建项目:{}, 构建日志:{}",jobName,newLog.getConsoleLog());
}
currentLog = newLog;
}
buildResult = job.getBuildByNumber(build.getNumber()).details().getResult();
LogUtil.APP.info("构建项目:{}, 构建结果:>>>>>>>>>{}",jobName,buildResult.toString());
} catch (IOException e) {
LogUtil.APP.error("获取执行任务状态出现异常", e);
}
return buildResult;
}
}

View File

@ -1,45 +1,45 @@
package luckyclient.tool.shell;
import luckyclient.remote.api.serverOperation;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class RestartServerInitialization {
public static String restartServerRun(String tastid){
String result = "Status:true"+" 重启命令执行成功!";
try{
String[] command = serverOperation.getRestartComm(tastid);
if(command!=null){
LogUtil.APP.info("准备重启指定的TOMCAT请稍等。。。参数个数:{}",command.length);
if(command.length==5){
LogUtil.APP.info("开始调用重启TOMCAT方法。。。参数0:{} 参数1:{} 参数2:{} 参数3:{} 参数4:{}",command[0],command[1],command[2],command[3],command[4]);
result = RmtShellExecutor.sshShell(command[0], command[1], command[2], Integer.valueOf(command[3]), command[4]);
}else{
LogUtil.APP.warn("重启TOMCAT命令行参数出现异常请检查配置信息");
result = "重启TOMCAT命令行参数出现异常请检查配置信息";
}
}else{
result = "Status:true"+" 当前任务没有找到需要重启的TOMCAT命令";
LogUtil.APP.info("当前任务没有指定需要重启TOMCAT");
}
}catch(Throwable e){
LogUtil.APP.error("重启TOMCAT过程中出现异常",e);
result = "重启TOMCAT过程中出现异常";
return result;
}
return result;
}
}
package luckyclient.tool.shell;
import luckyclient.remote.api.serverOperation;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class RestartServerInitialization {
public static String restartServerRun(String tastid){
String result;
try{
String[] command = serverOperation.getRestartComm(tastid);
if(command!=null){
LogUtil.APP.info("准备重启指定的TOMCAT请稍等。。。参数个数:{}",command.length);
if(command.length==5){
LogUtil.APP.info("开始调用重启TOMCAT方法。。。参数0:{} 参数1:{} 参数2:{} 参数3:{} 参数4:{}",command[0],command[1],command[2],command[3],command[4]);
result = RmtShellExecutor.sshShell(command[0], command[1], command[2], Integer.parseInt(command[3]), command[4]);
}else{
LogUtil.APP.warn("重启TOMCAT命令行参数出现异常请检查配置信息");
result = "重启TOMCAT命令行参数出现异常请检查配置信息";
}
}else{
result = "Status:true"+" 当前任务没有找到需要重启的TOMCAT命令";
LogUtil.APP.info("当前任务没有指定需要重启TOMCAT");
}
}catch(Throwable e){
LogUtil.APP.error("重启TOMCAT过程中出现异常",e);
result = "重启TOMCAT过程中出现异常";
return result;
}
return result;
}
}

View File

@ -1,4 +1,5 @@
package luckyclient.tool.shell;
import java.io.InputStream;
import java.io.OutputStream;
@ -10,110 +11,95 @@ import luckyclient.utils.LogUtil;
/**
* 远程执行shell脚本类
*
* @author l
*/
public class RmtShellExecutor {
/**
* 利用JSch包实现远程主机SHELL命令执行
* @param ip 主机IP
* @param user 主机登陆用户名
* @param psw 主机登陆密码
* @param port 主机ssh2登陆端口如果取默认值-1
* @param command Shell命令 cd /home/pospsettle/tomcat-7.0-7080/bin&&./restart.sh
*/
public static String sshShell(String ip, String user, String psw
,int port,String command) throws Exception{
Session session = null;
Channel channel = null;
String privateKey = "";
String passphrase = "";
String result = "Status:true"+" 重启命令执行成功!";
try {
JSch jsch = new JSch();
LogUtil.APP.info("进入到重启TOMCAT方法...");
//设置密钥和密码
if (privateKey != null && !"".equals(privateKey)) {
if (passphrase != null && "".equals(passphrase)) {
//设置带口令的密钥
jsch.addIdentity(privateKey, passphrase);
} else {
//设置不带口令的密钥
jsch.addIdentity(privateKey);
}
}
if(port <=0){
//连接服务器采用默认端口
LogUtil.APP.info("设置重启TOMCAT服务器IP及默认端口...");
session = jsch.getSession(user, ip);
}else{
//采用指定的端口连接服务器
LogUtil.APP.info("设置重启TOMCAT服务器IP及端口...");
session = jsch.getSession(user, ip ,port);
LogUtil.APP.info("设置重启TOMCAT服务器IP及端口完成!");
}
//如果服务器连接不上则抛出异常
if (session == null) {
LogUtil.APP.warn("重启TOMCAT过程中链接服务器session is null");
result = "重启TOMCAT过程中链接服务器session is null";
throw new Exception("session is null");
}
//设置登陆主机的密码
session.setPassword(psw);
//设置第一次登陆的时候提示可选值(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
//设置登陆超时时间
session.connect(30000);
//创建sftp通信通道
channel = (Channel) session.openChannel("shell");
channel.connect(1000);
//获取输入流和输出流
InputStream instream = channel.getInputStream();
OutputStream outstream = channel.getOutputStream();
//发送需要执行的SHELL命令需要用\n结尾表示回车
LogUtil.APP.info("准备往重启TOMCAT服务器发送命令!");
String shellCommand = command+" \n";
outstream.write(shellCommand.getBytes());
outstream.flush();
/**
* 利用JSch包实现远程主机SHELL命令执行
*
* @param ip 主机IP
* @param user 主机登陆用户名
* @param psw 主机登陆密码
* @param port 主机ssh2登陆端口如果取默认值-1
* @param command Shell命令 cd /home/pospsettle/tomcat-7.0-7080/bin&&./restart.sh
*/
public static String sshShell(String ip, String user, String psw
, int port, String command) {
Thread.sleep(10000);
//获取命令执行的结果
if (instream.available() > 0) {
byte[] data = new byte[instream.available()];
int nLen = instream.read(data);
if (nLen < 0) {
LogUtil.APP.warn("重启TOMCAT过程中获取命令执行结果出现异常");
result = "重启TOMCAT过程中获取命令执行结果出现异常";
throw new Exception("network error.");
}
//转换输出结果并打印出来
String temp = new String(data, 0, nLen,"iso8859-1");
LogUtil.APP.info("开始打印重启TOMCAT命令执行结果...",temp);
}
outstream.close();
instream.close();
} catch (Exception e) {
result = "重启TOMCAT过程中出现异常";
LogUtil.APP.error("重启TOMCAT过程中出现异常", e);
return result;
} finally {
if(null!=session){
session.disconnect();
}
if(null!=channel){
channel.disconnect();
}
Session session = null;
Channel channel = null;
String result = "Status:true" + " 重启命令执行成功!";
try {
JSch jsch = new JSch();
LogUtil.APP.info("进入到重启TOMCAT方法...");
}
return result;
}
if (port <= 0) {
//连接服务器采用默认端口
LogUtil.APP.info("设置重启TOMCAT服务器IP及默认端口...");
session = jsch.getSession(user, ip);
} else {
//采用指定的端口连接服务器
LogUtil.APP.info("设置重启TOMCAT服务器IP及端口...");
session = jsch.getSession(user, ip, port);
LogUtil.APP.info("设置重启TOMCAT服务器IP及端口完成!");
}
public static void main(String args[]) throws Exception {
//如果服务器连接不上则抛出异常
if (session == null) {
LogUtil.APP.warn("重启TOMCAT过程中链接服务器session is null");
throw new Exception("session is null");
}
//设置登陆主机的密码
session.setPassword(psw);
//设置第一次登陆的时候提示可选值(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
//设置登陆超时时间
session.connect(30000);
//创建sftp通信通道
channel = session.openChannel("shell");
channel.connect(1000);
//获取输入流和输出流
InputStream instream = channel.getInputStream();
OutputStream outstream = channel.getOutputStream();
//发送需要执行的SHELL命令需要用\n结尾表示回车
LogUtil.APP.info("准备往重启TOMCAT服务器发送命令!");
String shellCommand = command + " \n";
outstream.write(shellCommand.getBytes());
outstream.flush();
Thread.sleep(10000);
//获取命令执行的结果
if (instream.available() > 0) {
byte[] data = new byte[instream.available()];
int nLen = instream.read(data);
if (nLen < 0) {
LogUtil.APP.warn("重启TOMCAT过程中获取命令执行结果出现异常");
}
//转换输出结果并打印出来
String temp = new String(data, 0, nLen, "iso8859-1");
LogUtil.APP.info("开始打印重启TOMCAT命令执行结果...{}", temp);
}
outstream.close();
instream.close();
} catch (Exception e) {
result = "重启TOMCAT过程中出现异常";
LogUtil.APP.error("重启TOMCAT过程中出现异常", e);
return result;
} finally {
if (null != session) {
session.disconnect();
}
if (null != channel) {
channel.disconnect();
}
}
return result;
}
}

View File

@ -1,163 +1,160 @@
package luckyclient.utils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
/**
* 时间工具类
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年5月5日
*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
public static String YYYY = "yyyy";
public static String YYYY_MM = "yyyy-MM";
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public static Date getNowDate()
{
return new Date();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*
* @return String
*/
public static String getDate()
{
return dateTimeNow(YYYY_MM_DD);
}
public static final String getTime()
{
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static final String dateTimeNow()
{
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static final String dateTimeNow(final String format)
{
return parseDateToStr(format, new Date());
}
public static final String dateTime(final Date date)
{
return parseDateToStr(YYYY_MM_DD, date);
}
public static final String parseDateToStr(final String format, final Date date)
{
return new SimpleDateFormat(format).format(date);
}
public static final Date dateTime(final String format, final String ts)
{
try
{
return new SimpleDateFormat(format).parse(ts);
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
/**
* 日期路径 即年// 如2018/08/08
*/
public static final String datePath()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年// 如20180808
*/
public static final String dateTime()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate(Object str)
{
if (str == null)
{
return null;
}
try
{
return parseDate(str.toString(), parsePatterns);
}
catch (ParseException e)
{
return null;
}
}
/**
* 获取服务器启动时间
*/
public static Date getServerStartDate()
{
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算两个时间差
*/
public static String getDatePoor(Date endDate, Date nowDate)
{
if(null==nowDate){
return 0 + "" + 0 + "小时" + 0 + "分钟";
}
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "" + hour + "小时" + min + "分钟";
}
}
package luckyclient.utils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
/**
* 时间工具类
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年5月5日
*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public static Date getNowDate()
{
return new Date();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*
* @return String
*/
public static String getDate()
{
return dateTimeNow(YYYY_MM_DD);
}
public static String getTime()
{
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static String dateTimeNow()
{
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static String dateTimeNow(final String format)
{
return parseDateToStr(format, new Date());
}
public static String dateTime(final Date date)
{
return parseDateToStr(YYYY_MM_DD, date);
}
public static String parseDateToStr(final String format, final Date date)
{
return new SimpleDateFormat(format).format(date);
}
public static Date dateTime(final String format, final String ts)
{
try
{
return new SimpleDateFormat(format).parse(ts);
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
/**
* 日期路径 即年// 如2018/08/08
*/
public static String datePath()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年// 如20180808
*/
public static String dateTime()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate(Object str)
{
if (str == null)
{
return null;
}
try
{
return parseDate(str.toString(), parsePatterns);
}
catch (ParseException e)
{
return null;
}
}
/**
* 获取服务器启动时间
*/
public static Date getServerStartDate()
{
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算两个时间差
*/
public static String getDatePoor(Date endDate, Date nowDate)
{
if(null==nowDate){
return 0 + "" + 0 + "小时" + 0 + "分钟";
}
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "" + hour + "小时" + min + "分钟";
}
}

View File

@ -4,148 +4,140 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: DBOperation
*
* @ClassName: DBOperation
* @Description: 封装自动化过程中对数据库的部分操作
* @author seagull
* @date 2014年8月24日 上午9:29:40
*
* @date 2014年8月24日 上午9:29:40
*/
public class DbOperation {
DbToolkit dbt =null;
/**
* 创建链接池注意此方法不能new多次会导致多次创建链接池最好放在任务启动方法中
*/
public DbOperation(String urlBase,String usernameBase,String passwordBase) {
dbt = new DbToolkit(urlBase,usernameBase,passwordBase);
}
/**
* 执行SQL
* @param sql
* @throws Exception
*/
public String executeSql(String sql) throws Exception{
Connection conn = null;
String result;
try{
conn = dbt.getBaseConnection();
int resultnum = DbToolkit.executeSQL(conn, sql);
if(resultnum>0){
result= "成功执行SQL,更新数据"+resultnum+"行!";
}else{
result= "成功执行SQL,没有更新到数据!";
}
return result;
}catch(Exception e){
return e.toString();
}finally{
DbToolkit.closeConnection(conn);
}
}
/**
* 执行SQL流水查询
* @param sql
* @throws SQLException
*/
public String executeQuery(String sql) throws Exception{
Connection conn = null;
ResultSet rs=null;
try{
conn = dbt.getBaseConnection();
StringBuffer sb = new StringBuffer();
rs = DbToolkit.executeQuery(conn, sql);
ResultSetMetaData metaData = rs.getMetaData();
int colum = metaData.getColumnCount();
int count=0;
//行数
while(rs.next()){
count++;
if (count > 1){
sb.append("#");
}
//列数
for (int i = 1; i <= colum; i++){
if(rs.getObject(metaData.getColumnName(i))== null){
sb.append("null").append("%");
continue;
}
sb.append(rs.getObject(metaData.getColumnName(i)).toString()).append("%");
}
DbToolkit dbt;
/**
* 创建链接池注意此方法不能new多次会导致多次创建链接池最好放在任务启动方法中
*/
public DbOperation(String urlBase, String usernameBase, String passwordBase) {
dbt = new DbToolkit(urlBase, usernameBase, passwordBase);
}
/**
* 执行SQL
*
* @param sql 执行SQL语句
*/
public String executeSql(String sql) {
Connection conn = null;
String result;
try {
conn = dbt.getBaseConnection();
int resultnum = DbToolkit.executeSQL(conn, sql);
if (resultnum > 0) {
result = "成功执行SQL,更新数据" + resultnum + "行!";
} else {
result = "成功执行SQL,没有更新到数据!";
}
return result;
} catch (Exception e) {
return e.toString();
} finally {
DbToolkit.closeConnection(conn);
}
}
/**
* 执行SQL流水查询
*
* @param sql 查询SQL语句
*/
public String executeQuery(String sql) throws Exception {
Connection conn = null;
ResultSet rs = null;
try {
conn = dbt.getBaseConnection();
StringBuilder sb = new StringBuilder();
rs = DbToolkit.executeQuery(conn, sql);
ResultSetMetaData metaData = rs.getMetaData();
int colum = metaData.getColumnCount();
int count = 0;
//行数
while (rs.next()) {
count++;
if (count > 1) {
sb.append("#");
}
//列数
for (int i = 1; i <= colum; i++) {
if (rs.getObject(metaData.getColumnName(i)) == null) {
sb.append("null").append("%");
continue;
}
sb.append(rs.getObject(metaData.getColumnName(i)).toString()).append("%");
}
/* if(DbOperation.sumString(sb.toString(), "%")>500){
sb.delete(0,sb.length());
sb.append("查询出来的数据太多啦(超过100项)!我显示不过来哦。。。。");
break;
}*/
}
return sb.toString();
}catch(Exception e){
throw e;
}finally{
if(rs!=null){
rs.close();
}
DbToolkit.closeConnection(conn);
}
}
}
return sb.toString();
} finally {
if (rs != null) {
rs.close();
}
DbToolkit.closeConnection(conn);
}
}
/**
*
* @Title: subString
* 截取字符串
*
* @return String
* @Description: 截取字符串
* @return String
* @throws
*/
public String subString(String str,String begin,String end){
try{
return str.substring(str.indexOf(begin)+begin.length(), str.lastIndexOf(end));
}
catch (Exception e) {
public String subString(String str, String begin, String end) {
try {
return str.substring(str.indexOf(begin) + begin.length(), str.lastIndexOf(end));
} catch (Exception e) {
return null;
}
}
/**
*
* @Title: sumString
* @Description: 统计字符在字符串中出现的次数
* @return int
* @throws
*/
public static int sumString(String str,String a){
char chs[]=a.toCharArray();
int num = 0;
char[] chars = str.toCharArray();
for(int i = 0; i < chars.length; i++){
if(chs[0] == chars[i])
{
num++;
}
}
return num;
}
}
/**
* @throws InterruptedException
*
* @Title: Wait
* @Description: 等待时间
/**
* 统计字符在字符串中出现的次数
*
* @return int
* @throws
*/
public static void stepWait(String s) throws InterruptedException{
int second = Integer.parseInt(s);
Thread.sleep(second*1000);
}
public static int sumString(String str, String a) {
char[] chs = a.toCharArray();
int num = 0;
char[] chars = str.toCharArray();
for (char aChar : chars) {
if (chs[0] == aChar) {
num++;
}
}
return num;
}
/**
* Wait等待时间
*
* @return int
*/
public static void stepWait(String s) throws InterruptedException {
int second = Integer.parseInt(s);
Thread.sleep(second * 1000);
}
}

View File

@ -26,7 +26,7 @@ public class DbToolkit {
/**
* 建立数据库链接池
*/
public ComboPooledDataSource cpds=null;
public ComboPooledDataSource cpds;
private static final String DRIVERCLASS = DrivenConfig.getConfiguration().getProperty("db.ComboPooledDataSource.DriverClass");
public DbToolkit(String urlBase,String usernameBase,String passwordBase){
@ -57,8 +57,7 @@ public class DbToolkit {
public Connection getBaseConnection() throws SQLException{
// TODO Auto-generated method stub
Connection conn = cpds.getConnection();
return conn;
return cpds.getConnection();
}
/**
@ -66,25 +65,22 @@ public class DbToolkit {
*
* @param conn 数据库连接
* @param staticSql 静态SQL语句字符串
* @return 返回查询结果集ResultSet对象
* @throws SQLException
* @return 返回查询结果集ResultSet对象
*/
public static ResultSet executeQuery(Connection conn, String staticSql) throws SQLException {
//创建执行SQL的对象
Statement stmt = conn.createStatement();
//执行SQL并获取返回结果
ResultSet rs = stmt.executeQuery(staticSql);
// stmt.close();
return rs;
// stmt.close();
return stmt.executeQuery(staticSql);
}
/**
* 在一个数据库连接上执行一个静态SQL语句
*
* @param conn 数据库连接
* @param staticSql 静态SQL语句字符串
* @throws SQLException
* @param staticSql 静态SQL语句字符串
*/
public static int executeSQL(Connection conn, String staticSql) throws SQLException {
//创建执行SQL的对象

View File

@ -1,79 +1,80 @@
package luckyclient.utils;
import java.io.File;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class JarClassFind {
private static void findClassInLocalSystem(String path,String classname) {
int count = 0;
//String path = "D:\\web_task\\TestFrame\\lib\\"; //指定查找路径
classname = classname.replace('.', '/') + ".class";
//JavaBaseTest.LogUtil.APP.info("即将去服务器路径【" + path + "】下查找类【" + classname + "");
System.out.println("即将去服务器路径【" + path + "】下查找类【" + classname + "");
if (path.charAt(path.length() - 1) != '\\') {
path += '\\';
}
File file = new File(path);
if (!file.exists()) {
//JavaBaseTest.LogUtil.ERROR.error("找不到本地指定包查找路径!");
System.out.println("找不到本地指定包查找路径!");
return;
}
String[] filelist = file.list();
for (int i = 0; i < filelist.length; i++) {
File temp = new File(path + filelist[i]);
if ((temp.isDirectory() && !temp.isHidden() && temp.exists())&&filelist[i].equals(classname)) {
count++;
System.out.println(""+path + filelist[i]+"】查找到第"+count+"个JAR包存在指定类");
} else {
if (filelist[i].endsWith("jar")) {
try {
JarFile jarfile = new java.util.jar.JarFile(path + filelist[i]);
for (Enumeration<JarEntry> e = jarfile.entries(); e.hasMoreElements();) {
String name = e.nextElement().toString();
if (name.equals(classname) || name.indexOf(classname) > -1) {
count++;
//JavaBaseTest.LogUtil.APP.info(""+path + filelist[i]+"】查找到第"+count+"个JAR包存在指定类");
System.out.println(""+path + filelist[i]+"】查找到第"+count+"个JAR包存在指定类");
}
}
jarfile.close();
} catch (Exception e) {
}
}
}
}
if(count==0){
//JavaBaseTest.LogUtil.APP.info("没有在当前路径下找到指定类");
System.out.println("没有在当前路径下找到指定类");
}else if(count==1){
//JavaBaseTest.LogUtil.APP.info("在当前路径下只找到一个存在的指定类,不存在类冲突情况!");
System.out.println("在当前路径下只找到一个存在的指定类,不存在类冲突情况!");
}
}
static public void main(String[] args) {
String path = args[0];
String classname = args[1];
findClassInLocalSystem(path,classname);
}
}
package luckyclient.utils;
import java.io.File;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class JarClassFind {
private static void findClassInLocalSystem(String path,String classname) {
int count = 0;
//String path = "D:\\web_task\\TestFrame\\lib\\"; //指定查找路径
classname = classname.replace('.', '/') + ".class";
//JavaBaseTest.LogUtil.APP.info("即将去服务器路径【" + path + "】下查找类【" + classname + "");
System.out.println("即将去服务器路径【" + path + "】下查找类【" + classname + "");
if (path.charAt(path.length() - 1) != '\\') {
path += '\\';
}
File file = new File(path);
if (!file.exists()) {
//JavaBaseTest.LogUtil.ERROR.error("找不到本地指定包查找路径!");
System.out.println("找不到本地指定包查找路径!");
return;
}
String[] filelist = file.list();
assert filelist != null;
for (String s : filelist) {
File temp = new File(path + s);
if ((temp.isDirectory() && !temp.isHidden() && temp.exists()) && s.equals(classname)) {
count++;
System.out.println("" + path + s + "】查找到第" + count + "个JAR包存在指定类");
} else {
if (s.endsWith("jar")) {
try {
JarFile jarfile = new JarFile(path + s);
for (Enumeration<JarEntry> e = jarfile.entries(); e.hasMoreElements(); ) {
String name = e.nextElement().toString();
if (name.equals(classname) || name.contains(classname)) {
count++;
//JavaBaseTest.LogUtil.APP.info(""+path + filelist[i]+"】查找到第"+count+"个JAR包存在指定类");
System.out.println("" + path + s + "】查找到第" + count + "个JAR包存在指定类");
}
}
jarfile.close();
} catch (Exception ignored) {
}
}
}
}
if(count==0){
//JavaBaseTest.LogUtil.APP.info("没有在当前路径下找到指定类");
System.out.println("没有在当前路径下找到指定类");
}else if(count==1){
//JavaBaseTest.LogUtil.APP.info("在当前路径下只找到一个存在的指定类,不存在类冲突情况!");
System.out.println("在当前路径下只找到一个存在的指定类,不存在类冲突情况!");
}
}
static public void main(String[] args) {
String path = args[0];
String classname = args[1];
findClassInLocalSystem(path,classname);
}
}

View File

@ -1,57 +1,54 @@
package luckyclient.utils;
import java.lang.reflect.Field;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 系统日志记录
* @author Seagull
*
*/
public class LogUtil {
/**
* 主要使用三种日志级别info,warn,error
* info 记录客户端系统日志监控客户端运行情况
* warn 记录客户端业务上的告警日志
* error 记录客户端在执行过程中抛出的异常以及严重错误
*/
public static final Logger APP = LoggerFactory.getLogger("info");
public static StringBuffer getFieldValue(Object bean){
StringBuffer sb = new StringBuffer();
try{
if(bean==null){
return null;
}
Field[] fieldArray = bean.getClass().getDeclaredFields();
if(fieldArray != null){
int indexId = 0;
Object obj = null;
for(Field field:fieldArray){
field.setAccessible(true);
obj = field.get(bean);
if(!(obj instanceof List) && !"serialVersionUID".equals(field.getName())){
if(indexId>0){
sb.append(",");
}
if(obj != null){
sb.append(field.getName()).append("=").append( obj.toString());
}else{
sb.append(field.getName()).append("=");
}
indexId += 1;
}
}
}
}
catch(Exception ex){
LogUtil.APP.error("日志异常",ex);
}
return sb;
}
}
package luckyclient.utils;
import java.lang.reflect.Field;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 系统日志记录
*
* @author Seagull
*/
public class LogUtil {
/**
* 主要使用三种日志级别info,warn,error
* info 记录客户端系统日志监控客户端运行情况
* warn 记录客户端业务上的告警日志
* error 记录客户端在执行过程中抛出的异常以及严重错误
*/
public static final Logger APP = LoggerFactory.getLogger("info");
public static StringBuffer getFieldValue(Object bean) {
StringBuffer sb = new StringBuffer();
try {
if (bean == null) {
return null;
}
Field[] fieldArray = bean.getClass().getDeclaredFields();
int indexId = 0;
Object obj;
for (Field field : fieldArray) {
field.setAccessible(true);
obj = field.get(bean);
if (!(obj instanceof List) && !"serialVersionUID".equals(field.getName())) {
if (indexId > 0) {
sb.append(",");
}
if (obj != null) {
sb.append(field.getName()).append("=").append(obj.toString());
} else {
sb.append(field.getName()).append("=");
}
indexId += 1;
}
}
} catch (Exception ex) {
LogUtil.APP.error("日志异常", ex);
}
return sb;
}
}

View File

@ -1,31 +1,32 @@
package luckyclient.utils.config;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import luckyclient.utils.LogUtil;
/**
* 初始化Appium配置参数
* @author seagull
*
*/
public class AppiumConfig {
private static final Properties SYS_CONFIG = new Properties();
private static final String SYS_CONFIG_FILE = "/appium_config.properties";
static{
try {
InputStream in = new BufferedInputStream(AppiumConfig.class.getResourceAsStream(SYS_CONFIG_FILE));
SYS_CONFIG.load(new InputStreamReader(in, "UTF-8"));
} catch (IOException e) {
LogUtil.APP.error("读取移动端appium_config.properties配置文件出现异常请检查", e);
}
}
private AppiumConfig(){}
public static Properties getConfiguration(){
return SYS_CONFIG;
}
}
package luckyclient.utils.config;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import luckyclient.utils.LogUtil;
/**
* 初始化Appium配置参数
* @author seagull
*
*/
public class AppiumConfig {
private static final Properties SYS_CONFIG = new Properties();
private static final String SYS_CONFIG_FILE = "/appium_config.properties";
static{
try {
InputStream in = new BufferedInputStream(AppiumConfig.class.getResourceAsStream(SYS_CONFIG_FILE));
SYS_CONFIG.load(new InputStreamReader(in, StandardCharsets.UTF_8));
} catch (IOException e) {
LogUtil.APP.error("读取移动端appium_config.properties配置文件出现异常请检查", e);
}
}
private AppiumConfig(){}
public static Properties getConfiguration(){
return SYS_CONFIG;
}
}

View File

@ -1,35 +1,36 @@
package luckyclient.utils.config;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import luckyclient.utils.LogUtil;
/**
* 初始化数据库驱动配置
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2020年2月17日
*/
public class DrivenConfig {
private static final Properties SYS_CONFIG = new Properties();
private static final String SYS_CONFIG_FILE = "/TestDriven/driven_config.properties";
static{
try {
InputStream in = new BufferedInputStream(DrivenConfig.class.getResourceAsStream(SYS_CONFIG_FILE));
SYS_CONFIG.load(new InputStreamReader(in, "UTF-8"));
} catch (IOException e) {
LogUtil.APP.error("读取测试驱动driven_config.properties配置文件出现异常请检查", e);
}
}
private DrivenConfig(){}
public static Properties getConfiguration(){
return SYS_CONFIG;
}
}
package luckyclient.utils.config;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import luckyclient.utils.LogUtil;
/**
* 初始化数据库驱动配置
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2020年2月17日
*/
public class DrivenConfig {
private static final Properties SYS_CONFIG = new Properties();
private static final String SYS_CONFIG_FILE = "/TestDriven/driven_config.properties";
static{
try {
InputStream in = new BufferedInputStream(DrivenConfig.class.getResourceAsStream(SYS_CONFIG_FILE));
SYS_CONFIG.load(new InputStreamReader(in, StandardCharsets.UTF_8));
} catch (IOException e) {
LogUtil.APP.error("读取测试驱动driven_config.properties配置文件出现异常请检查", e);
}
}
private DrivenConfig(){}
public static Properties getConfiguration(){
return SYS_CONFIG;
}
}

View File

@ -1,16 +1,7 @@
package luckyclient.utils.httputils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.SysConfig;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
@ -20,8 +11,11 @@ import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.SysConfig;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
/**
* =================================================================
@ -41,12 +35,12 @@ public class HttpRequest {
/**
* 字符串参数
* @param repath
* @return
* @param repath 请求路径
* @return 返回请求结果
*/
public static String loadJSON(String repath) {
String charset="GBK";
StringBuffer resultBuffer = null;
StringBuffer resultBuffer;
CloseableHttpClient httpclient = HttpClients.createDefault();
BufferedReader br = null;
// 构建请求参数
@ -69,8 +63,6 @@ public class HttpRequest {
br.close();
} catch (IOException e) {
LogUtil.APP.error("loadJSON发送请求后关闭br流出现异常请检查", e);
br = null;
throw new RuntimeException(e);
}
}
}
@ -86,7 +78,7 @@ public class HttpRequest {
public static String sendPost(String repath, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
StringBuilder result = new StringBuilder();
try {
URL realUrl = new URL(WEB_URL+repath);
// 打开和URL之间的连接
@ -109,7 +101,7 @@ public class HttpRequest {
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
String line;
while ((line = in.readLine()) != null) {
result += line;
result.append(line);
}
} catch (Exception e) {
LogUtil.APP.error("向指定URL发送POST方法的请求出现异常请检查", e);
@ -128,17 +120,17 @@ public class HttpRequest {
LogUtil.APP.error("向指定URL发送POST方法的请求后关闭流出现异常请检查", ex);
}
}
return result;
return result.toString();
}
/**
* 使用HttpClient以JSON格式发送post请求
* @param urlParam
* @param params
* @return
* @param urlParam 请求路径
* @param params 请求参数
* @return 返回请求结果
*/
public static String httpClientPostJson(String urlParam, String params){
StringBuffer resultBuffer = null;
StringBuffer resultBuffer;
CloseableHttpClient httpclient=HttpClients.createDefault();
HttpPost httpPost = new HttpPost(WEB_URL+urlParam);
httpPost.setHeader("Content-Type", "application/json");
@ -159,7 +151,7 @@ public class HttpRequest {
// 读取服务器响应数据
resultBuffer = new StringBuffer();
if(null!=response.getEntity()){
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8));
String temp;
while ((temp = br.readLine()) != null) {
resultBuffer.append(temp);
@ -173,9 +165,7 @@ public class HttpRequest {
try {
br.close();
} catch (IOException e) {
br = null;
LogUtil.APP.error("使用HttpClient以JSON格式发送post请求后关闭br流出现异常请检查", e);
throw new RuntimeException(e);
}
}
}

View File

@ -1,36 +1,34 @@
package luckyclient.utils.httputils;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年8月8日
*/
public class MyX509TrustManager implements X509TrustManager
{
@Override
public void checkClientTrusted(X509Certificate ax509certificate[], String s) throws CertificateException
{
//TODO nothing
}
@Override
public void checkServerTrusted(X509Certificate ax509certificate[], String s) throws CertificateException
{
//TODO nothing
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[]{};
}
}
package luckyclient.utils.httputils;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年8月8日
*/
public class MyX509TrustManager implements X509TrustManager
{
@Override
public void checkClientTrusted(X509Certificate[] ax509certificate, String s) {
//TODO nothing
}
@Override
public void checkServerTrusted(X509Certificate[] ax509certificate, String s) {
//TODO nothing
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[]{};
}
}

View File

@ -9,14 +9,11 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -51,14 +48,14 @@ public class HttpImpl {
private static final String OS=System.getProperty("os.name").toLowerCase();
/**
* 运行自动化任务
* @param req
* @return
* @throws RemoteException
* @param req HTTP请求
* @return 返回运行任务结果
*/
@PostMapping("/runTask")
private String runTask(HttpServletRequest req) throws RemoteException {
private String runTask(HttpServletRequest req) {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
try {
BufferedReader reader = req.getReader();
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
@ -81,7 +78,7 @@ public class HttpImpl {
}
log.info("初始化Runtime...");
Runtime run = Runtime.getRuntime();
StringBuffer sbf=new StringBuffer();
StringBuilder sbf=new StringBuilder();
sbf.append(runTaskEntity.getTaskId()).append(" ");
sbf.append(runTaskEntity.getLoadPath());
log.info("启动任务模式测试程序...调度名称:【{}】 任务ID:【{}】",runTaskEntity.getSchedulingName(),runTaskEntity.getTaskId());
@ -104,14 +101,14 @@ public class HttpImpl {
/**
* 批量运行用例
* @param req
* @return
* @throws RemoteException
* @param req HTTP请求
* @return 返回批量运行用例结果
*/
@PostMapping("/runBatchCase")
private String runBatchCase(HttpServletRequest req) throws RemoteException {
private String runBatchCase(HttpServletRequest req) {
StringBuilder sbd = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
try {
BufferedReader reader = req.getReader();
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
@ -139,7 +136,7 @@ public class HttpImpl {
}
log.info("初始化Runtime...");
Runtime run = Runtime.getRuntime();
StringBuffer sb=new StringBuffer();
StringBuilder sb=new StringBuilder();
sb.append(taskId).append(" ");
sb.append(batchCase).append(" ");
sb.append(loadPath);
@ -164,14 +161,14 @@ public class HttpImpl {
/**
* web界面调度接口
* @param req
* @return
* @throws RemoteException
* @param req HTTP请求
* @return 返回调试用例运行结果
*/
@PostMapping("/webDebugCase")
private String webDebugCase(HttpServletRequest req) throws RemoteException {
private String webDebugCase(HttpServletRequest req) {
StringBuilder sbd = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
try {
BufferedReader reader = req.getReader();
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
@ -190,7 +187,7 @@ public class HttpImpl {
return "客户端测试驱动桩路径不存在,请检查【"+file.getPath()+"";
}
Runtime run = Runtime.getRuntime();
StringBuffer sb=new StringBuffer();
StringBuilder sb=new StringBuilder();
sb.append(webDebugCaseEntity.getCaseId()).append(" ");
sb.append(webDebugCaseEntity.getUserId()).append(" ");
sb.append(webDebugCaseEntity.getLoadpath());
@ -210,23 +207,19 @@ public class HttpImpl {
/**
* 获取客户端本地日志
* @param req
* @return
* @throws RemoteException
* @param req HTTP请求
* @return 返回日志全部信息
*/
@GetMapping("/getLogdDetail")
private String getLogdDetail(HttpServletRequest req) throws RemoteException{
private String getLogdDetail(HttpServletRequest req) {
String fileName=req.getParameter("filename");
String ctxPath = System.getProperty("user.dir")+File.separator+"log";
String downLoadPath = ctxPath +File.separator+ fileName;
String str = "";
InputStreamReader isr=null;
String str;
InputStreamReader isr;
try {
isr = new InputStreamReader(new FileInputStream(downLoadPath), "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
isr = new InputStreamReader(new FileInputStream(downLoadPath), StandardCharsets.UTF_8);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@ -234,7 +227,7 @@ public class HttpImpl {
return "读取日志路径错误,请检查客户端日志路径是否存在!downLoadPath: "+downLoadPath;
}
BufferedReader bos = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
try {
while ((str = bos.readLine()) != null)
{
@ -253,12 +246,11 @@ public class HttpImpl {
/**
* 获取错误截图
* @param req
* @return
* @throws RemoteException
* @param req HTTP请求
* @return 返回图片字节
*/
@GetMapping("/getLogImg")
private byte[] getLogImg(HttpServletRequest req,HttpServletResponse res) throws RemoteException{
private byte[] getLogImg(HttpServletRequest req) {
String imgName=req.getParameter("imgName");
String ctxPath = System.getProperty("user.dir")+File.separator+"log"+File.separator+"ScreenShot";
String downLoadPath = ctxPath+File.separator+imgName;
@ -267,7 +259,7 @@ public class HttpImpl {
File file = new File(downLoadPath);
b = new byte[(int) file.length()];
BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
is.read(b);
//is.read(b);
is.close();
log.info("服务端获取本地图片:{}",downLoadPath);
} catch (FileNotFoundException e) {
@ -285,9 +277,9 @@ public class HttpImpl {
* 上传驱动文件到客户端
*/
@PostMapping("/uploadJar")
private String uploadJar(HttpServletRequest req,HttpServletResponse res, HttpSession session,@RequestParam("jarfile") MultipartFile jarfile) throws IOException, ServletException{
private String uploadJar(HttpServletRequest req, @RequestParam("jarfile") MultipartFile jarfile) {
if (!jarfile.isEmpty()){
if (!jarfile.getOriginalFilename().endsWith(".jar")&&!jarfile.getOriginalFilename().endsWith(".py")) {
if (!Objects.requireNonNull(jarfile.getOriginalFilename()).endsWith(".jar")&&!jarfile.getOriginalFilename().endsWith(".py")) {
log.warn("文件格式后缀不是.jar或.py上传失败");
return "文件格式后缀不是.jar或.py上传失败";
}
@ -311,14 +303,19 @@ public class HttpImpl {
if (file.exists()){
file.deleteOnExit();
}
file.createNewFile();
BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
byte[] jarfileByte = jarfile.getBytes();
os.write(jarfileByte);
os.flush();
os.close();
log.info("上传驱动包【{}】到客户端驱动目录【{}】成功!",name,file.getAbsolutePath());
return "上传驱动包【"+name+"】到客户端驱动目录【"+file.getAbsolutePath()+"】成功!";
boolean newFile = file.createNewFile();
if(newFile){
BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
byte[] jarfileByte = jarfile.getBytes();
os.write(jarfileByte);
os.flush();
os.close();
log.info("上传驱动包【{}】到客户端驱动目录【{}】成功!",name,file.getAbsolutePath());
return "上传驱动包【"+name+"】到客户端驱动目录【"+file.getAbsolutePath()+"】成功!";
}else{
log.error("上传驱动包【{}】到客户端驱动目录【{}】失败!",name,file.getAbsolutePath());
return "上传驱动包【"+name+"】到客户端驱动目录【"+file.getAbsolutePath()+"】失败!";
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
log.error("客户端未找到正确路径或文件,上传失败!文件路径名称:{}",pathName,e);
@ -332,12 +329,10 @@ public class HttpImpl {
/**
* 检查客户端心跳
* @param req
* @return
* @throws RemoteException
* @return 返回心跳结果
*/
@GetMapping("/getClientStatus")
private String getClientStatus(HttpServletRequest req) throws RemoteException{
private String getClientStatus() {
Properties properties = SysConfig.getConfiguration();
String verison=properties.getProperty("client.verison");
return "{\"status\":\"success\",\"version\":\""+verison+"\"}";
@ -345,14 +340,12 @@ public class HttpImpl {
/**
* 获取客户端资源监控情况
* @param req
* @return
* @return 返回客户端资源情况
* @author Seagull
* @throws Exception
* @date 2019年5月5日
*/
@GetMapping("/getClientMonitorData")
private String getClientMonitorData(HttpServletRequest req) throws Exception{
private String getClientMonitorData() {
Server server = new Server();
server.copyTo();
return JSON.toJSONString(server);
@ -360,11 +353,10 @@ public class HttpImpl {
/**
* 检查客户端中的配置
* @return
* @author Seagull
* @date 2019年5月6日
*/
public static boolean checkHostNet() {
public static void checkHostNet() {
log.info("检查客户端配置中,请稍后......");
Properties properties = SysConfig.getConfiguration();
String version="Version "+properties.getProperty("client.verison");
@ -384,9 +376,7 @@ public class HttpImpl {
} catch (Exception e) {
log.error("客户端配置检测异常,请确认您项目根目录下的客户端配置文件(sys_config.properties)是否已经正确配置。",e);
return false;
}
return true;
}
}
}
}