对代码注释进行优化

This commit is contained in:
seagull 2020-03-10 18:55:27 +08:00
parent 709b2b6b83
commit c3eeb50cc6
23 changed files with 2866 additions and 2865 deletions

View File

@ -1,202 +1,200 @@
package luckyclient.execution.appium;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.offbytwo.jenkins.model.BuildResult;
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.execution.appium.androidex.AndroidCaseExecution;
import luckyclient.execution.appium.iosex.IosCaseExecution;
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.remote.entity.TaskScheduling;
import luckyclient.tool.jenkins.BuildingInitialization;
import luckyclient.tool.mail.HtmlMail;
import luckyclient.tool.mail.MailSendInitialization;
import luckyclient.tool.shell.RestartServerInitialization;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class AppTestControl {
/**
* @param args
* @throws ClassNotFoundException
* 控制台模式调度计划执行用例
*/
public static void manualExecutionPlan(String planname) {
// 不记日志到数据库
serverOperation.exetype = 1;
String taskid = "888888";
AndroidDriver<AndroidElement> androiddriver = null;
IOSDriver<IOSElement> iosdriver = null;
Properties properties = AppiumConfig.getConfiguration();
try {
if ("Android".equals(properties.getProperty("platformName"))) {
androiddriver = AppiumInitialization.setAndroidAppium(properties);
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver = AppiumInitialization.setIosAppium(properties);
}
} catch (IOException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("控制台模式初始化Appium Driver异常", e);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
LogUtil.APP.info("当前计划中读取到用例共{}个",testCases.size());
int i = 0;
for (ProjectCase testcase : testCases) {
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
i++;
LogUtil.APP.info("开始执行计划中的第{}条用例:【{}】......",i,testcase.getCaseSign());
try {
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidCaseExecution.caseExcution(testcase, steps, taskid, androiddriver, caselog, pcplist);
} 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);
}
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
}
LogUtil.APP.info("当前项目测试计划中的用例已经全部执行完成...");
// 关闭APP以及appium会话
if ("Android".equals(properties.getProperty("platformName"))) {
androiddriver.closeApp();
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver.closeApp();
}
}
public static void taskExecutionPlan(TaskExecute task) throws InterruptedException {
// 记录日志到数据库
String taskId=task.getTaskId().toString();
serverOperation.exetype = 0;
TestControl.TASKID = taskId;
AndroidDriver<AndroidElement> androiddriver = null;
IOSDriver<IOSElement> iosdriver = null;
Properties properties = AppiumConfig.getConfiguration();
AppiumService as=null;
//根据配置自动启动Appiume服务
if(Boolean.valueOf(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId());
String restartstatus = RestartServerInitialization.restartServerRun(taskId);
BuildResult buildResult = BuildingInitialization.buildingRun(taskId);
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(task.getProjectId().toString());
String projectname = task.getProject().getProjectName();
String jobname = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId()).getSchedulingName();
int[] tastcount = null;
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
// 判断是否构建是否成功
if (BuildResult.SUCCESS.equals(buildResult)) {
try {
if ("Android".equals(properties.getProperty("platformName"))) {
androiddriver = AppiumInitialization.setAndroidAppium(properties);
LogUtil.APP.info("完成AndroidDriver初始化动作...APPIUM Server【http://{}/wd/hub】",properties.getProperty("appiumsever"));
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver = AppiumInitialization.setIosAppium(properties);
LogUtil.APP.info("完成IOSDriver初始化动作...APPIUM Server【http://{}/wd/hub】",properties.getProperty("appiumsever"));
}
} catch (Exception e) {
LogUtil.APP.error("初始化AppiumDriver出错 APPIUM Server【http://{}/wd/hub】",properties.getProperty("appiumsever"), e);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
LogUtil.APP.info("当前计划【{}】中共有【{}】条待测试用例...",task.getTaskName(),cases.size());
serverOperation.updateTaskExecuteStatusIng(taskId, cases.size());
int i = 0;
for (ProjectCase testcase : cases) {
i++;
LogUtil.APP.info("开始执行当前测试任务 {} 的第【{}】条测试用例:【{}】......",task.getTaskName(),i,testcase.getCaseSign());
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
try {
//插入开始执行的用例
caselog.insertTaskCaseExecute(taskId, taskScheduling.getProjectId(),testcase.getCaseId(),testcase.getCaseSign(), testcase.getCaseName(), 4);
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidCaseExecution.caseExcution(testcase, steps, taskId, androiddriver, caselog, pcplist);
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosCaseExecution.caseExcution(testcase, steps, taskId, iosdriver, caselog, pcplist);
}
} catch (InterruptedException | IOException e) {
// TODO Auto-generated catch block
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);
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"))) {
androiddriver.closeApp();
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver.closeApp();
}
} else {
LogUtil.APP.warn("项目构建失败自动化测试自动退出请前往JENKINS中检查项目构建情况。");
MailSendInitialization.sendMailInitialization(jobname, "构建项目过程中失败自动化测试自动退出请前去JENKINS查看构建情况", taskId, taskScheduling, tastcount);
}
} else {
LogUtil.APP.warn("项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况。");
MailSendInitialization.sendMailInitialization(jobname, "项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况", taskId, taskScheduling, tastcount);
}
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package luckyclient.execution.appium;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import com.offbytwo.jenkins.model.BuildResult;
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.execution.appium.androidex.AndroidCaseExecution;
import luckyclient.execution.appium.iosex.IosCaseExecution;
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.remote.entity.TaskScheduling;
import luckyclient.tool.jenkins.BuildingInitialization;
import luckyclient.tool.mail.HtmlMail;
import luckyclient.tool.mail.MailSendInitialization;
import luckyclient.tool.shell.RestartServerInitialization;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.AppiumConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class AppTestControl {
/**
* 控制台模式调度计划执行用例
* @param planname
*/
public static void manualExecutionPlan(String planname) {
// 不记日志到数据库
serverOperation.exetype = 1;
String taskid = "888888";
AndroidDriver<AndroidElement> androiddriver = null;
IOSDriver<IOSElement> iosdriver = null;
Properties properties = AppiumConfig.getConfiguration();
try {
if ("Android".equals(properties.getProperty("platformName"))) {
androiddriver = AppiumInitialization.setAndroidAppium(properties);
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver = AppiumInitialization.setIosAppium(properties);
}
} catch (IOException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("控制台模式初始化Appium Driver异常", e);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
LogUtil.APP.info("当前计划中读取到用例共{}个",testCases.size());
int i = 0;
for (ProjectCase testcase : testCases) {
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
i++;
LogUtil.APP.info("开始执行计划中的第{}条用例:【{}】......",i,testcase.getCaseSign());
try {
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidCaseExecution.caseExcution(testcase, steps, taskid, androiddriver, caselog, pcplist);
} 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);
}
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
}
LogUtil.APP.info("当前项目测试计划中的用例已经全部执行完成...");
// 关闭APP以及appium会话
if ("Android".equals(properties.getProperty("platformName"))) {
androiddriver.closeApp();
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver.closeApp();
}
}
public static void taskExecutionPlan(TaskExecute task) throws InterruptedException {
// 记录日志到数据库
String taskId=task.getTaskId().toString();
serverOperation.exetype = 0;
TestControl.TASKID = taskId;
AndroidDriver<AndroidElement> androiddriver = null;
IOSDriver<IOSElement> iosdriver = null;
Properties properties = AppiumConfig.getConfiguration();
AppiumService as=null;
//根据配置自动启动Appiume服务
if(Boolean.valueOf(properties.getProperty("autoRunAppiumService"))){
as =new AppiumService();
as.start();
Thread.sleep(10000);
}
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId());
String restartstatus = RestartServerInitialization.restartServerRun(taskId);
BuildResult buildResult = BuildingInitialization.buildingRun(taskId);
List<ProjectCaseParams> pcplist = GetServerApi
.cgetParamsByProjectid(task.getProjectId().toString());
String projectname = task.getProject().getProjectName();
String jobname = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId()).getSchedulingName();
int[] tastcount = null;
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
// 判断是否构建是否成功
if (BuildResult.SUCCESS.equals(buildResult)) {
try {
if ("Android".equals(properties.getProperty("platformName"))) {
androiddriver = AppiumInitialization.setAndroidAppium(properties);
LogUtil.APP.info("完成AndroidDriver初始化动作...APPIUM Server【http://{}/wd/hub】",properties.getProperty("appiumsever"));
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver = AppiumInitialization.setIosAppium(properties);
LogUtil.APP.info("完成IOSDriver初始化动作...APPIUM Server【http://{}/wd/hub】",properties.getProperty("appiumsever"));
}
} catch (Exception e) {
LogUtil.APP.error("初始化AppiumDriver出错 APPIUM Server【http://{}/wd/hub】",properties.getProperty("appiumsever"), e);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
LogUtil.APP.info("当前计划【{}】中共有【{}】条待测试用例...",task.getTaskName(),cases.size());
serverOperation.updateTaskExecuteStatusIng(taskId, cases.size());
int i = 0;
for (ProjectCase testcase : cases) {
i++;
LogUtil.APP.info("开始执行当前测试任务 {} 的第【{}】条测试用例:【{}】......",task.getTaskName(),i,testcase.getCaseSign());
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
try {
//插入开始执行的用例
caselog.insertTaskCaseExecute(taskId, taskScheduling.getProjectId(),testcase.getCaseId(),testcase.getCaseSign(), testcase.getCaseName(), 4);
if ("Android".equals(properties.getProperty("platformName"))) {
AndroidCaseExecution.caseExcution(testcase, steps, taskId, androiddriver, caselog, pcplist);
} else if ("IOS".equals(properties.getProperty("platformName"))) {
IosCaseExecution.caseExcution(testcase, steps, taskId, iosdriver, caselog, pcplist);
}
} catch (InterruptedException | IOException e) {
// TODO Auto-generated catch block
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);
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"))) {
androiddriver.closeApp();
} else if ("IOS".equals(properties.getProperty("platformName"))) {
iosdriver.closeApp();
}
} else {
LogUtil.APP.warn("项目构建失败自动化测试自动退出请前往JENKINS中检查项目构建情况。");
MailSendInitialization.sendMailInitialization(jobname, "构建项目过程中失败自动化测试自动退出请前去JENKINS查看构建情况", taskId, taskScheduling, tastcount);
}
} else {
LogUtil.APP.warn("项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况。");
MailSendInitialization.sendMailInitialization(jobname, "项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况", taskId, taskScheduling, tastcount);
}
//关闭Appium服务的线程
if(as!=null){
as.interrupt();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}

View File

@ -1,227 +1,242 @@
package luckyclient.execution.appium.androidex;
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.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.android.AndroidTouchAction;
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 2017年12月1日 上午9:29:40
*
*/
public class AndroidBaseAppium {
/**
* 安卓手机报错截图
*
* @param appium
* @param imagname
* @throws IOException
*/
public static void screenShot(AndroidDriver<AndroidElement> 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("安卓手机滑动休眠出现异常",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("安卓手机报错截图异常",e);
}
}
/**
* @param args
* @throws IOException
* appium不支持中文输入 参考了robotium的以js方式为元素直接设置value的做法
* 利用Selenium中Webdriver执行js方法实现中文输入
*/
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 + "'");
}
/**
* @param args
* js webview 支持4.14.4
*/
public static void webViewSwipe(AndroidDriver<AndroidElement> 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("安卓手机滑动出现异常",e);
} finally {
// 释放变量
}
}
/**
* @param args
* 调用 ADB直接滑动 支持4.14.4
*/
public static void adbSwipe(AndroidDriver<AndroidElement> 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 " + "Android" + " shell input swipe " + sX2 + " " + sY2 + " " + eX2 + " " + eY2);
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("安卓手机调用 ADB直接滑动出现异常",e);
} finally {
// 释放变量
}
}
/**
* @param args
* 屏幕点击事件
*/
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);
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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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.androidex;
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.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.android.AndroidTouchAction;
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 2017年12月1日 上午9:29:40
*
*/
public class AndroidBaseAppium {
/**
* 安卓手机报错截图
*
* @param appium
* @param imagname
* @throws IOException
*/
public static void screenShot(AndroidDriver<AndroidElement> 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("安卓手机滑动休眠出现异常",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("安卓手机报错截图异常",e);
}
}
/**
* appium不支持中文输入 参考了robotium的以js方式为元素直接设置value的做法
* 利用Selenium中Webdriver执行js方法实现中文输入
* @param 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 + "'");
}
/**
* js webview 支持4.14.4
* @param appium
* @param sX
* @param sY
* @param eX
* @param eY
* @param duration
* @throws Exception
*/
public static void webViewSwipe(AndroidDriver<AndroidElement> 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("安卓手机滑动出现异常",e);
} finally {
// 释放变量
}
}
/**
* 调用 ADB直接滑动 支持4.14.4
* @param appium
* @param sX
* @param sY
* @param eX
* @param eY
* @throws Exception
*/
public static void adbSwipe(AndroidDriver<AndroidElement> 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 " + "Android" + " shell input swipe " + sX2 + " " + sY2 + " " + eX2 + " " + eY2);
} catch (Exception e) {
// TODO Auto-generated catch block
LogUtil.APP.error("安卓手机调用 ADB直接滑动出现异常",e);
} finally {
// 释放变量
}
}
/**
* 屏幕点击事件
* @param drivers
* @param x
* @param 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);
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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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(AndroidDriver<AndroidElement> 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;
AndroidTouchAction action = new AndroidTouchAction(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,75 +1,71 @@
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;
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 AndroidCaseLocalDebug {
public static void oneCasedebug(AndroidDriver<AndroidElement> androiddriver, 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", androiddriver, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
/**
* 用于做多条用例串行调试
* @param androiddriver
* @param projectname
* @param addtestcase
* @author Seagull
* @date 2019年4月18日
*/
public static void moreCaseDebug(AndroidDriver<AndroidElement> androiddriver, String projectname,
List<String> addtestcase) {
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try {
LogUtil.APP
.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(androiddriver, testCaseExternalId);
} catch (Exception e) {
LogUtil.APP.error("多用例调试过程中抛出异常!", e);
continue;
}
}
// 关闭APP以及appium会话
androiddriver.closeApp();
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
}
}
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;
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 AndroidCaseLocalDebug {
public static void oneCasedebug(AndroidDriver<AndroidElement> androiddriver, 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", androiddriver, caselog, pcplist);
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
} catch (Exception e) {
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
}
/**
* 用于做多条用例串行调试
* @param androiddriver
* @param projectname
* @param addtestcase
* @author Seagull
* @date 2019年4月18日
*/
public static void moreCaseDebug(AndroidDriver<AndroidElement> androiddriver, String projectname,
List<String> addtestcase) {
System.out.println("当前调试用例总共:"+addtestcase.size());
for(String testCaseExternalId:addtestcase) {
try {
LogUtil.APP
.info("开始调用方法,项目名:{},用例编号:{}",projectname,testCaseExternalId);
oneCasedebug(androiddriver, testCaseExternalId);
} catch (Exception e) {
LogUtil.APP.error("多用例调试过程中抛出异常!", e);
continue;
}
}
// 关闭APP以及appium会话
androiddriver.closeApp();
}
}

View File

@ -1,35 +1,35 @@
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类获取JSON字符串指定Key的值的
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="getjv")
public class GetJsonActionParser implements ActionKeyWordParser {
/**
* 获取JSON字符串指定Key的值是
* @param actionKeyWord 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
String key="";
String index="1";
if(actionParams.endsWith("]")&&actionParams.contains("[")){
key=actionParams.substring(0,actionParams.indexOf("["));
index=actionParams.substring(actionParams.indexOf("[")+1, actionParams.lastIndexOf("]"));
testResult= SubString.getJsonValue(testResult, key, index);
}else{
key=actionParams;
testResult=SubString.getJsonValue(testResult, key, index);
}
LogUtil.APP.info("Action(getJV):获取JSON字符串指定Key的值是:{}",testResult);
return testResult;
}
}
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类获取JSON字符串指定Key的值的
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="getjv")
public class GetJsonActionParser implements ActionKeyWordParser {
/**
* 获取JSON字符串指定Key的值是
* @param actionParams 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
String key="";
String index="1";
if(actionParams.endsWith("]")&&actionParams.contains("[")){
key=actionParams.substring(0,actionParams.indexOf("["));
index=actionParams.substring(actionParams.indexOf("[")+1, actionParams.lastIndexOf("]"));
testResult= SubString.getJsonValue(testResult, key, index);
}else{
key=actionParams;
testResult=SubString.getJsonValue(testResult, key, index);
}
LogUtil.APP.info("Action(getJV):获取JSON字符串指定Key的值是:{}",testResult);
return testResult;
}
}

View File

@ -1,29 +1,32 @@
package luckyclient.execution.dispose.actionkeyword;
import com.alibaba.fastjson.JSONObject;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类从响应header中取出某个header值
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="header")
public class HeaderParser implements ActionKeyWordParser {
/**
* @param actionorder 动作关键字
*/
@Override
public String parse(String actionParams, String testResult) {
String pre = "RESPONSE_HEAD:【";
String headerStr = testResult.substring(testResult.indexOf(pre) + pre.length(), testResult.indexOf("】 RESPONSE_CODE"));
String getHeader = JSONObject.parseObject(headerStr).getJSONArray(actionParams).getString(0);
LogUtil.APP.info("Action(header):从响应header中取出指定header值是:{}",getHeader);
return getHeader;
}
}
package luckyclient.execution.dispose.actionkeyword;
import com.alibaba.fastjson.JSONObject;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类从响应header中取出某个header值
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="header")
public class HeaderParser implements ActionKeyWordParser {
/**
* 动作关键字
* @param actionParams
* @param testResult
* @return
*/
@Override
public String parse(String actionParams, String testResult) {
String pre = "RESPONSE_HEAD:【";
String headerStr = testResult.substring(testResult.indexOf(pre) + pre.length(), testResult.indexOf("】 RESPONSE_CODE"));
String getHeader = JSONObject.parseObject(headerStr).getJSONArray(actionParams).getString(0);
LogUtil.APP.info("Action(header):从响应header中取出指定header值是:{}",getHeader);
return getHeader;
}
}

View File

@ -1,32 +1,32 @@
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类使用jsonpath处理json字符串
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年8月26日
*/
@Action(name="jsonpath")
public class JsonPathActionParser implements ActionKeyWordParser {
/**
* 通过jsonPath表达式获取JSON字符串指定值
* 仅支持返回值是String类型不支持List,如果jsonPath表达式返回的是List将抛出异常
* @param actionKeyWord 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
LogUtil.APP.info("Action(jsonPath):开始处理jsonPath动作...参数:【{}】 待处理json字符串【{}】",actionParams,testResult);
testResult = SubString.jsonPathGetParams(actionParams, testResult);
LogUtil.APP.info("Action(jsonPath):处理jsonPath动作完成...处理结果【{}】",testResult);
return testResult;
}
}
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类使用jsonpath处理json字符串
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年8月26日
*/
@Action(name="jsonpath")
public class JsonPathActionParser implements ActionKeyWordParser {
/**
* 通过jsonPath表达式获取JSON字符串指定值
* 仅支持返回值是String类型不支持List,如果jsonPath表达式返回的是List将抛出异常
* @param actionParams 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
LogUtil.APP.info("Action(jsonPath):开始处理jsonPath动作...参数:【{}】 待处理json字符串【{}】",actionParams,testResult);
testResult = SubString.jsonPathGetParams(actionParams, testResult);
LogUtil.APP.info("Action(jsonPath):处理jsonPath动作完成...处理结果【{}】",testResult);
return testResult;
}
}

View File

@ -1,34 +1,34 @@
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类截取测试结果指定开始及结束位置字符串
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="subcentrenum")
public class SubCentreNumActionParser implements ActionKeyWordParser {
/**
* 截取测试结果指定开始及结束位置字符串
* @param actionKeyWord 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
if(actionParams.startsWith("[")&&actionParams.endsWith("]")){
String startnum=actionParams.substring(actionParams.indexOf("[")+1, actionParams.indexOf("]"));
String endnum=actionParams.substring(actionParams.lastIndexOf("[")+1, actionParams.lastIndexOf("]"));
testResult= SubString.subCentreNum(testResult, startnum, endnum);
LogUtil.APP.info("Action(subCentreNum):截取测试结果指定开始及结束位置字符串:{}",testResult);
}else{
testResult="步骤动作subCentreNum 必须是[\"开始字符\"][\"结束字符\"]#subCentreNum 格式,请检查您的步骤动作参数:"+actionParams;
LogUtil.APP.warn("步骤动作subCentreNum 必须是[\"开始位置(整数)\"][\"结束位置(整数)\"]#subCentreNum 格式,请检查您的步骤动作参数:{}",actionParams);
}
return testResult;
}
}
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类截取测试结果指定开始及结束位置字符串
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="subcentrenum")
public class SubCentreNumActionParser implements ActionKeyWordParser {
/**
* 截取测试结果指定开始及结束位置字符串
* @param actionParams 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
if(actionParams.startsWith("[")&&actionParams.endsWith("]")){
String startnum=actionParams.substring(actionParams.indexOf("[")+1, actionParams.indexOf("]"));
String endnum=actionParams.substring(actionParams.lastIndexOf("[")+1, actionParams.lastIndexOf("]"));
testResult= SubString.subCentreNum(testResult, startnum, endnum);
LogUtil.APP.info("Action(subCentreNum):截取测试结果指定开始及结束位置字符串:{}",testResult);
}else{
testResult="步骤动作subCentreNum 必须是[\"开始字符\"][\"结束字符\"]#subCentreNum 格式,请检查您的步骤动作参数:"+actionParams;
LogUtil.APP.warn("步骤动作subCentreNum 必须是[\"开始位置(整数)\"][\"结束位置(整数)\"]#subCentreNum 格式,请检查您的步骤动作参数:{}",actionParams);
}
return testResult;
}
}

View File

@ -1,35 +1,35 @@
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类截取测试结果指定开始及结束位置字符串
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="subcentrestr")
public class SubCentresStrActionParser implements ActionKeyWordParser {
/**
* 截取测试结果指定开始及结束位置字符串
* @param actionKeyWord 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
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("]"));
testResult= SubString.subCentreStr(testResult, startstr, endstr);
LogUtil.APP.info("Action(subCentreStr):截取测试结果指定开始及结束位置字符串:{}",testResult);
}else{
testResult="步骤动作subCentreStr 必须是[\"开始字符\"][\"结束字符\"]#subCentreStr 格式,请检查您的步骤动作参数:"+actionParams;
LogUtil.APP.warn("步骤动作subCentreStr 必须是[\"开始字符\"][\"结束字符\"]#subCentreStr 格式,请检查您的步骤动作参数:{}",actionParams);
}
return testResult;
}
}
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类截取测试结果指定开始及结束位置字符串
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="subcentrestr")
public class SubCentresStrActionParser implements ActionKeyWordParser {
/**
* 截取测试结果指定开始及结束位置字符串
* @param actionParams 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
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("]"));
testResult= SubString.subCentreStr(testResult, startstr, endstr);
LogUtil.APP.info("Action(subCentreStr):截取测试结果指定开始及结束位置字符串:{}",testResult);
}else{
testResult="步骤动作subCentreStr 必须是[\"开始字符\"][\"结束字符\"]#subCentreStr 格式,请检查您的步骤动作参数:"+actionParams;
LogUtil.APP.warn("步骤动作subCentreStr 必须是[\"开始字符\"][\"结束字符\"]#subCentreStr 格式,请检查您的步骤动作参数:{}",actionParams);
}
return testResult;
}
}

View File

@ -1,35 +1,35 @@
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类获取JSON字符串指定Key的值采用正则匹配
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="substrrgex")
public class SubStrRegxActionParser implements ActionKeyWordParser {
/**
* 获取JSON字符串指定Key的值采用正则匹配
* @param actionKeyWord 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
String key="";
String index="1";
if(actionParams.endsWith("]")&&actionParams.contains("[")){
key=actionParams.substring(0,actionParams.lastIndexOf("["));
index=actionParams.substring(actionParams.lastIndexOf("[")+1, actionParams.lastIndexOf("]"));
testResult= SubString.subStrRgex(testResult, key, index);
}else{
key=actionParams;
testResult= SubString.subStrRgex(testResult, key, index);
}
LogUtil.APP.info("Action(subStrRgex):获取JSON字符串指定Key的值是:{}",testResult);
return testResult;
}
}
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.driven.SubString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类获取JSON字符串指定Key的值采用正则匹配
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="substrrgex")
public class SubStrRegxActionParser implements ActionKeyWordParser {
/**
* 获取JSON字符串指定Key的值采用正则匹配
* @param actionParams 动作关键字
* @param testResult 测试结果
*/
@Override
public String parse(String actionParams, String testResult) {
String key="";
String index="1";
if(actionParams.endsWith("]")&&actionParams.contains("[")){
key=actionParams.substring(0,actionParams.lastIndexOf("["));
index=actionParams.substring(actionParams.lastIndexOf("[")+1, actionParams.lastIndexOf("]"));
testResult= SubString.subStrRgex(testResult, key, index);
}else{
key=actionParams;
testResult= SubString.subStrRgex(testResult, key, index);
}
LogUtil.APP.info("Action(subStrRgex):获取JSON字符串指定Key的值是:{}",testResult);
return testResult;
}
}

View File

@ -1,38 +1,41 @@
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.execution.dispose.ChangString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类线程等待时间
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="wait")
public class ThreadWaitAction implements ActionKeyWordParser {
/**
* @param actionorder 动作关键字
*/
@Override
public String parse(String actionParams, String testResult) {
if(ChangString.isInteger(actionParams)){
try {
// 获取步骤间等待时间
int time=Integer.parseInt(actionParams);
if (time > 0) {
LogUtil.APP.info("Action(Wait):线程等待【{}】秒...",time);
Thread.sleep(time * 1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
LogUtil.APP.error("使用等待关键字的参数不是整数,直接跳过此动作,请检查!");
}
return testResult;
}
}
package luckyclient.execution.dispose.actionkeyword;
import luckyclient.execution.dispose.ChangString;
import luckyclient.utils.LogUtil;
/**
* 动作关键字的处理接口的实现类线程等待时间
* @author: sunshaoyan
* @date: Created on 2019/4/13
*/
@Action(name="wait")
public class ThreadWaitAction implements ActionKeyWordParser {
/**
* 动作关键字
* @param actionParams
* @param testResult
* @return
*/
@Override
public String parse(String actionParams, String testResult) {
if(ChangString.isInteger(actionParams)){
try {
// 获取步骤间等待时间
int time=Integer.parseInt(actionParams);
if (time > 0) {
LogUtil.APP.info("Action(Wait):线程等待【{}】秒...",time);
Thread.sleep(time * 1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
LogUtil.APP.error("使用等待关键字的参数不是整数,直接跳过此动作,请检查!");
}
return testResult;
}
}

View File

@ -1,67 +1,69 @@
package luckyclient.execution.httpinterface;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class BatchTestCaseExecution {
/**
* @param args
* @throws ClassNotFoundException
* 创建线程池多线程执行用例
*/
public static void batchCaseExecuteForTast(String projectname,String taskid,String batchcase) throws Exception{
int threadcount = GetServerApi.cGetTaskSchedulingByTaskId(Integer.valueOf(taskid)).getExThreadCount();
ThreadPoolExecutor threadExecute = new ThreadPoolExecutor(threadcount, 30, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000),
new ThreadPoolExecutor.CallerRunsPolicy());
//执行全部非成功状态用例
if(batchcase.indexOf("ALLFAIL")>-1){
//初始化写用例结果以及日志模块
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));
}
}else{ //批量执行用例
String[] temp=batchcase.split("\\#");
LogUtil.APP.info("当前批量执行任务中共有【{}】条待测试用例...",temp.length);
for(int i=0;i<temp.length;i++){
TestControl.THREAD_COUNT++; //多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForBatchCase(projectname,Integer.valueOf(temp[i]),taskid));
}
}
//多线程计数用于检测线程是否全部执行完
int i=0;
while(TestControl.THREAD_COUNT!=0){
i++;
if(i>600){
break;
}
Thread.sleep(6000);
}
threadExecute.shutdown();
}
}
package luckyclient.execution.httpinterface;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.serverOperation;
import luckyclient.remote.entity.ProjectCase;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class BatchTestCaseExecution {
/**
* 创建线程池多线程执行用例
* @param projectname
* @param taskid
* @param batchcase
* @throws Exception
*/
public static void batchCaseExecuteForTast(String projectname,String taskid,String batchcase) throws Exception{
int threadcount = GetServerApi.cGetTaskSchedulingByTaskId(Integer.valueOf(taskid)).getExThreadCount();
ThreadPoolExecutor threadExecute = new ThreadPoolExecutor(threadcount, 30, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1000),
new ThreadPoolExecutor.CallerRunsPolicy());
//执行全部非成功状态用例
if(batchcase.indexOf("ALLFAIL")>-1){
//初始化写用例结果以及日志模块
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));
}
}else{ //批量执行用例
String[] temp=batchcase.split("\\#");
LogUtil.APP.info("当前批量执行任务中共有【{}】条待测试用例...",temp.length);
for(int i=0;i<temp.length;i++){
TestControl.THREAD_COUNT++; //多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForBatchCase(projectname,Integer.valueOf(temp[i]),taskid));
}
}
//多线程计数用于检测线程是否全部执行完
int i=0;
while(TestControl.THREAD_COUNT!=0){
i++;
if(i>600){
break;
}
Thread.sleep(6000);
}
threadExecute.shutdown();
}
}

View File

@ -1,175 +1,173 @@
package luckyclient.execution.httpinterface;
import java.util.ArrayList;
import java.util.List;
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.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.remote.entity.TaskScheduling;
import luckyclient.tool.jenkins.BuildingInitialization;
import luckyclient.tool.mail.HtmlMail;
import luckyclient.tool.mail.MailSendInitialization;
import luckyclient.tool.shell.RestartServerInitialization;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: TestControl
* @Description: 启动扫描指定项目的用例脚本并调用脚本中的方法 @author seagull
* @date 2014年8月24日 上午9:29:40
*
*/
public class TestControl {
public static String TASKID = "NULL";
public static int THREAD_COUNT = 0;
/**
* @param args
* @throws ClassNotFoundException
* 控制台模式调度计划执行用例
*/
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());
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
String taskid = "888888";
// 初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
for (ProjectCase testcase : testCases) {
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
LogUtil.APP.warn("用例【{}】没有找到步骤,直接跳过,请检查!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在用例中没有找到步骤,请检查", "error", "1", "");
continue;
}
THREAD_COUNT++; // 多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForExecuteCase(testcase, steps, taskid, pcplist, caselog));
}
// 多线程计数用于检测线程是否全部执行完
int i = 0;
while (THREAD_COUNT != 0) {
i++;
if (i > 600) {
break;
}
Thread.sleep(6000);
}
LogUtil.APP.info("亲,没有下一条啦!我发现你的用例已经全部执行完毕,快去看看有没有失败的用例吧!");
threadExecute.shutdown();
}
/**
* @param args
* @throws ClassNotFoundException
* 计划任务模式调度计划执行用例
*/
public static void taskExecutionPlan(TaskExecute task) throws Exception {
serverOperation.exetype = 0;
String taskid = task.getTaskId().toString();
TestControl.TASKID = taskid;
String restartstatus = RestartServerInitialization.restartServerRun(taskid);
BuildResult buildResult = BuildingInitialization.buildingRun(taskid);
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId());
String jobname = taskScheduling.getSchedulingName();
int timeout = taskScheduling.getTaskTimeout();
int[] tastcount = null;
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(taskScheduling.getProjectId().toString());
// 初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
// 判断是否构建是否成功
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());
List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
LogUtil.APP.info("当前测试任务 {} 中共有【{}】条待测试用例...",task.getTaskName(),cases.size());
serverOperation.updateTaskExecuteStatusIng(taskid, cases.size());
int casepriority = 0;
for (int j = 0; j < cases.size(); j++) {
ProjectCase projectcase = cases.get(j);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(projectcase.getCaseId());
if (steps.size() == 0) {
caselog.insertTaskCaseExecute(taskid, taskScheduling.getProjectId(),projectcase.getCaseId(),projectcase.getCaseSign(), projectcase.getCaseName(), 2);
LogUtil.APP.warn("用例【{}】没有找到步骤,直接跳过,请检查!",projectcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, projectcase.getCaseId(), "在用例中没有找到步骤,请检查", "error", "1", "");
continue;
}
// 多线程计数,如果用例设置了优先级必须等优先级高的用例执行完成才继续后面的用例
if (casepriority < projectcase.getPriority()) {
LogUtil.APP.info("用例编号:{} 上条用例优先级:{} 当前用例优先级:{}",projectcase.getCaseSign(),casepriority,projectcase.getPriority());
int i = 0;
while (THREAD_COUNT != 0) {
i++;
if (i > timeout * 60 * 5 / cases.size()) {
LogUtil.APP.warn("用例编号:{} 上条用例优先级:{} 当前用例优先级:{} 等待时间已经超过设置的用例平均超时间{}秒(计算公式:任务超时时间*5/用例总数),现在继续往下执行...",projectcase.getCaseSign(),casepriority,projectcase.getPriority(),i);
break;
}
Thread.sleep(1000);
}
}
casepriority = projectcase.getPriority();
THREAD_COUNT++; // 多线程计数++用于检测线程是否全部执行完
LogUtil.APP.info("开始执行当前测试任务 {} 的第【{}】条测试用例...",task.getTaskName(),j+1);
threadExecute.execute(new ThreadForExecuteCase(projectcase, steps, taskid, pcplist, caselog));
}
// 多线程计数用于检测线程是否全部执行完
int i = 0;
int taskStatus=2;
while (THREAD_COUNT != 0) {
i++;
if (i > timeout * 10) {
taskStatus=3;
LogUtil.APP.warn("当前测试任务 {} 执行已经超过设置的最大任务超时时间【{}】分钟,现在即将停止任务执行...",task.getTaskName(),timeout);
break;
}
Thread.sleep(6000);
}
tastcount = serverOperation.updateTaskExecuteData(taskid, cases.size(),taskStatus);
String testtime = serverOperation.getTestTime(taskid);
MailSendInitialization.sendMailInitialization(HtmlMail.htmlSubjectFormat(jobname),
HtmlMail.htmlContentFormat(tastcount, taskid, buildResult.toString(), restartstatus, testtime, jobname),
taskid, taskScheduling, tastcount);
threadExecute.shutdown();
LogUtil.APP.info("亲,没有下一条啦!我发现你的用例已经全部执行完毕,快去看看有没有失败的用例吧!");
} else {
LogUtil.APP.warn("项目构建失败,自动化测试自动退出!请查看构建日志检查项目构建情况...");
MailSendInitialization.sendMailInitialization(jobname, "构建项目过程中失败,自动化测试自动退出!请查看构建日志检查项目构建情况...", taskid,
taskScheduling, tastcount);
}
} else {
LogUtil.APP.warn("项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况。");
MailSendInitialization.sendMailInitialization(jobname, "项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况", taskid,
taskScheduling, tastcount);
}
}
}
package luckyclient.execution.httpinterface;
import java.util.ArrayList;
import java.util.List;
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.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.remote.entity.TaskScheduling;
import luckyclient.tool.jenkins.BuildingInitialization;
import luckyclient.tool.mail.HtmlMail;
import luckyclient.tool.mail.MailSendInitialization;
import luckyclient.tool.shell.RestartServerInitialization;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @ClassName: TestControl
* @Description: 启动扫描指定项目的用例脚本并调用脚本中的方法 @author seagull
* @date 2014年8月24日 上午9:29:40
*
*/
public class TestControl {
public static String TASKID = "NULL";
public static int THREAD_COUNT = 0;
/**
* 控制台模式调度计划执行用例
* @param planname
* @throws Exception
*/
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());
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
String taskid = "888888";
// 初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
for (ProjectCase testcase : testCases) {
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
LogUtil.APP.warn("用例【{}】没有找到步骤,直接跳过,请检查!",testcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, testcase.getCaseId(), "在用例中没有找到步骤,请检查", "error", "1", "");
continue;
}
THREAD_COUNT++; // 多线程计数++用于检测线程是否全部执行完
threadExecute.execute(new ThreadForExecuteCase(testcase, steps, taskid, pcplist, caselog));
}
// 多线程计数用于检测线程是否全部执行完
int i = 0;
while (THREAD_COUNT != 0) {
i++;
if (i > 600) {
break;
}
Thread.sleep(6000);
}
LogUtil.APP.info("亲,没有下一条啦!我发现你的用例已经全部执行完毕,快去看看有没有失败的用例吧!");
threadExecute.shutdown();
}
/**
* 计划任务模式调度计划执行用例
* @param task
* @throws Exception
*/
public static void taskExecutionPlan(TaskExecute task) throws Exception {
serverOperation.exetype = 0;
String taskid = task.getTaskId().toString();
TestControl.TASKID = taskid;
String restartstatus = RestartServerInitialization.restartServerRun(taskid);
BuildResult buildResult = BuildingInitialization.buildingRun(taskid);
TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId());
String jobname = taskScheduling.getSchedulingName();
int timeout = taskScheduling.getTaskTimeout();
int[] tastcount = null;
List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(taskScheduling.getProjectId().toString());
// 初始化写用例结果以及日志模块
serverOperation caselog = new serverOperation();
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
// 判断是否构建是否成功
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());
List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
LogUtil.APP.info("当前测试任务 {} 中共有【{}】条待测试用例...",task.getTaskName(),cases.size());
serverOperation.updateTaskExecuteStatusIng(taskid, cases.size());
int casepriority = 0;
for (int j = 0; j < cases.size(); j++) {
ProjectCase projectcase = cases.get(j);
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(projectcase.getCaseId());
if (steps.size() == 0) {
caselog.insertTaskCaseExecute(taskid, taskScheduling.getProjectId(),projectcase.getCaseId(),projectcase.getCaseSign(), projectcase.getCaseName(), 2);
LogUtil.APP.warn("用例【{}】没有找到步骤,直接跳过,请检查!",projectcase.getCaseSign());
caselog.insertTaskCaseLog(taskid, projectcase.getCaseId(), "在用例中没有找到步骤,请检查", "error", "1", "");
continue;
}
// 多线程计数,如果用例设置了优先级必须等优先级高的用例执行完成才继续后面的用例
if (casepriority < projectcase.getPriority()) {
LogUtil.APP.info("用例编号:{} 上条用例优先级:{} 当前用例优先级:{}",projectcase.getCaseSign(),casepriority,projectcase.getPriority());
int i = 0;
while (THREAD_COUNT != 0) {
i++;
if (i > timeout * 60 * 5 / cases.size()) {
LogUtil.APP.warn("用例编号:{} 上条用例优先级:{} 当前用例优先级:{} 等待时间已经超过设置的用例平均超时间{}秒(计算公式:任务超时时间*5/用例总数),现在继续往下执行...",projectcase.getCaseSign(),casepriority,projectcase.getPriority(),i);
break;
}
Thread.sleep(1000);
}
}
casepriority = projectcase.getPriority();
THREAD_COUNT++; // 多线程计数++用于检测线程是否全部执行完
LogUtil.APP.info("开始执行当前测试任务 {} 的第【{}】条测试用例...",task.getTaskName(),j+1);
threadExecute.execute(new ThreadForExecuteCase(projectcase, steps, taskid, pcplist, caselog));
}
// 多线程计数用于检测线程是否全部执行完
int i = 0;
int taskStatus=2;
while (THREAD_COUNT != 0) {
i++;
if (i > timeout * 10) {
taskStatus=3;
LogUtil.APP.warn("当前测试任务 {} 执行已经超过设置的最大任务超时时间【{}】分钟,现在即将停止任务执行...",task.getTaskName(),timeout);
break;
}
Thread.sleep(6000);
}
tastcount = serverOperation.updateTaskExecuteData(taskid, cases.size(),taskStatus);
String testtime = serverOperation.getTestTime(taskid);
MailSendInitialization.sendMailInitialization(HtmlMail.htmlSubjectFormat(jobname),
HtmlMail.htmlContentFormat(tastcount, taskid, buildResult.toString(), restartstatus, testtime, jobname),
taskid, taskScheduling, tastcount);
threadExecute.shutdown();
LogUtil.APP.info("亲,没有下一条啦!我发现你的用例已经全部执行完毕,快去看看有没有失败的用例吧!");
} else {
LogUtil.APP.warn("项目构建失败,自动化测试自动退出!请查看构建日志检查项目构建情况...");
MailSendInitialization.sendMailInitialization(jobname, "构建项目过程中失败,自动化测试自动退出!请查看构建日志检查项目构建情况...", taskid,
taskScheduling, tastcount);
}
} else {
LogUtil.APP.warn("项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况。");
MailSendInitialization.sendMailInitialization(jobname, "项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况", taskid,
taskScheduling, tastcount);
}
}
}

View File

@ -1,216 +1,217 @@
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.GetServerApi;
import luckyclient.remote.api.PostServerApi;
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: WebTestCaseDebug
* @Description: 提供Web端调试接口
* @author seagull
* @date 2018年3月1日
*/
public class WebTestCaseDebug {
/**
* @param executor
* @param sign 用于在WEB页面上调试用例时提供的接口
*/
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 testnote = "初始化测试结果";
int k = 0;
Integer caseId = Integer.valueOf(caseIdStr);
Integer userId = Integer.valueOf(userIdStr);
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseId);
String sign = testcase.getCaseSign();
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());
//进入循环解析用例所有步骤
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) {
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;
}
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));
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "解析包名:" + packagename + " 方法名:" + functionname + "" + (j + 1) + "个参数:" + parameterValues, 0);
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
//调用动态方法执行测试用例
try {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "开始调用方法:" + functionname + " .....",0);
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()) {
// 赋值传参
if (expectedresults.length() > Constants.ASSIGNMENT_SIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_SIGN)) {
variable.put(expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()), testnote);
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "将测试结果【" + testnote + "】赋值给变量【" + expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()) + "",0);
}
// 赋值全局变量
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()));
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "将测试结果【" + testnote + "】赋值给全局变量【" + expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()) + "",0);
}
// 模糊匹配
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()))) {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "模糊匹配预期结果成功!执行结果:" + testnote,0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "步,模糊匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()) + ",测试结果:" + testnote,0);
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()) {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "正则匹配预期结果成功!执行结果:" + testnote,0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "步,正则匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()) + ",测试结果:" + testnote,0);
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;
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "jsonpath断言预期结果成功预期结果" + exceptResult + " 测试结果: " + result.toString() + "校验结果: true", 0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "jsonpath断言预期结果失败预期结果" + exceptResult + ",测试结果:" + result.toString(),0);
testnote = "用例第" + (i + 1) + "jsonpath断言预期结果失败";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 完全相等
else {
if (expectedresults.equals(testnote)) {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "精确匹配预期结果成功!执行结果:" + testnote,0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "步,精确匹配预期结果失败!预期结果:" + expectedresults + ",测试结果:" + testnote,0);
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("用例执行出现异常!",e);
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "调用方法过程出错,方法名:" + functionname + " 请重新检查脚本方法名称以及参数!",0);
testnote = "CallCase调用出错";
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("解析出错啦!")) {
PostServerApi.cPostDebugLog(userId, caseId, "ERRORover", "用例 " + sign + "解析或是调用步骤中的方法出错!",1);
}
if (0 == setcaseresult) {
PostServerApi.cPostDebugLog(userId, caseId, "INFOover", "用例 " + sign + "步骤全部执行完成!",1);
} else {
PostServerApi.cPostDebugLog(userId, caseId, "ERRORover", "用例 " + sign + "在执行过程中失败,请检查!",1);
}
}
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.driven.SubString;
import luckyclient.execution.dispose.ActionManageForSteps;
import luckyclient.execution.dispose.ParamsManageForSteps;
import luckyclient.execution.httpinterface.analyticsteps.InterfaceAnalyticCase;
import luckyclient.remote.api.GetServerApi;
import luckyclient.remote.api.PostServerApi;
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: WebTestCaseDebug
* @Description: 提供Web端调试接口
* @author seagull
* @date 2018年3月1日
*/
public class WebTestCaseDebug {
/**
* 用于在WEB页面上调试用例时提供的接口
* @param caseIdStr
* @param userIdStr
*/
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 testnote = "初始化测试结果";
int k = 0;
Integer caseId = Integer.valueOf(caseIdStr);
Integer userId = Integer.valueOf(userIdStr);
ProjectCase testcase = GetServerApi.cGetCaseByCaseId(caseId);
String sign = testcase.getCaseSign();
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());
//进入循环解析用例所有步骤
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) {
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;
}
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));
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "解析包名:" + packagename + " 方法名:" + functionname + "" + (j + 1) + "个参数:" + parameterValues, 0);
getParameterValues[j] = parameterValues;
}
} else {
getParameterValues = null;
}
//调用动态方法执行测试用例
try {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "开始调用方法:" + functionname + " .....",0);
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()) {
// 赋值传参
if (expectedresults.length() > Constants.ASSIGNMENT_SIGN.length() && expectedresults.startsWith(Constants.ASSIGNMENT_SIGN)) {
variable.put(expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()), testnote);
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "将测试结果【" + testnote + "】赋值给变量【" + expectedresults.substring(Constants.ASSIGNMENT_SIGN.length()) + "",0);
}
// 赋值全局变量
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()));
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "将测试结果【" + testnote + "】赋值给全局变量【" + expectedresults.substring(Constants.ASSIGNMENT_GLOBALSIGN.length()) + "",0);
}
// 模糊匹配
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()))) {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "模糊匹配预期结果成功!执行结果:" + testnote,0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "步,模糊匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.FUZZY_MATCHING_SIGN.length()) + ",测试结果:" + testnote,0);
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()) {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "正则匹配预期结果成功!执行结果:" + testnote,0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "步,正则匹配预期结果失败!预期结果:" + expectedresults.substring(Constants.REGULAR_MATCHING_SIGN.length()) + ",测试结果:" + testnote,0);
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;
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "jsonpath断言预期结果成功预期结果" + exceptResult + " 测试结果: " + result.toString() + "校验结果: true", 0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "jsonpath断言预期结果失败预期结果" + exceptResult + ",测试结果:" + result.toString(),0);
testnote = "用例第" + (i + 1) + "jsonpath断言预期结果失败";
if (testcase.getFailcontinue() == 0) {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,中断本条用例后续步骤执行,进入到下一条用例执行中......",testcase.getCaseSign(),(i+1));
break;
} else {
LogUtil.APP.warn("用例【{}】第【{}】步骤执行失败,继续本条用例后续步骤执行,进入下个步骤执行中......",testcase.getCaseSign(),(i+1));
}
}
}
// 完全相等
else {
if (expectedresults.equals(testnote)) {
PostServerApi.cPostDebugLog(userId, caseId, "INFO", "精确匹配预期结果成功!执行结果:" + testnote,0);
} else {
setcaseresult = 1;
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "" + (i + 1) + "步,精确匹配预期结果失败!预期结果:" + expectedresults + ",测试结果:" + testnote,0);
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("用例执行出现异常!",e);
PostServerApi.cPostDebugLog(userId, caseId, "ERROR", "调用方法过程出错,方法名:" + functionname + " 请重新检查脚本方法名称以及参数!",0);
testnote = "CallCase调用出错";
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("解析出错啦!")) {
PostServerApi.cPostDebugLog(userId, caseId, "ERRORover", "用例 " + sign + "解析或是调用步骤中的方法出错!",1);
}
if (0 == setcaseresult) {
PostServerApi.cPostDebugLog(userId, caseId, "INFOover", "用例 " + sign + "步骤全部执行完成!",1);
} else {
PostServerApi.cPostDebugLog(userId, caseId, "ERRORover", "用例 " + sign + "在执行过程中失败,请检查!",1);
}
}
public static void main(String[] args) throws Exception {
}
}

View File

@ -1,74 +1,75 @@
package luckyclient.execution.webdriver;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
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.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.Augmenter;
import cn.hutool.core.util.BooleanUtil;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.SysConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class BaseWebDrive {
/**
* @param args
* @throws IOException
* @throws IOException
*/
public static Boolean webScreenShot(WebDriver driver,String imgname) {
Boolean result = false;
String relativelyPath = System.getProperty("user.dir");
String pngpath=relativelyPath +File.separator+ "log"+File.separator+"ScreenShot" +File.separator+ imgname + ".png";
// 对远程系统进行截图
driver = new Augmenter().augment(driver);
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File(pngpath));
} catch (IOException e) {
LogUtil.APP.error("截图操作失败,抛出异常请查看日志...", e);
}
scrFile.deleteOnExit();
LogUtil.APP
.info("已对当前界面进行截图操作,可通过用例执行界面的日志明细查看,也可以前往客户端上查看...【{}】",pngpath);
return result;
}
/**
* 在自动化过程中加入点击显示效果
* @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"));
if(highLight){
JavascriptExecutor js = (JavascriptExecutor) driver;
/*调用js将传入参数的页面元素对象的背景颜色和边框颜色分别设定为黄色和红色*/
js.executeScript("arguments[0].setAttribute('style', arguments[1]);", element, "background: yellow; border:2px solid red;");
}
}
}
package luckyclient.execution.webdriver;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
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.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.Augmenter;
import cn.hutool.core.util.BooleanUtil;
import luckyclient.utils.LogUtil;
import luckyclient.utils.config.SysConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class BaseWebDrive {
/**
* 进测试结果进行截图
* @param driver
* @param imgname
* @return
*/
public static Boolean webScreenShot(WebDriver driver,String imgname) {
Boolean result = false;
String relativelyPath = System.getProperty("user.dir");
String pngpath=relativelyPath +File.separator+ "log"+File.separator+"ScreenShot" +File.separator+ imgname + ".png";
// 对远程系统进行截图
driver = new Augmenter().augment(driver);
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File(pngpath));
} catch (IOException e) {
LogUtil.APP.error("截图操作失败,抛出异常请查看日志...", e);
}
scrFile.deleteOnExit();
LogUtil.APP
.info("已对当前界面进行截图操作,可通过用例执行界面的日志明细查看,也可以前往客户端上查看...【{}】",pngpath);
return result;
}
/**
* 在自动化过程中加入点击显示效果
* @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"));
if(highLight){
JavascriptExecutor js = (JavascriptExecutor) driver;
/*调用js将传入参数的页面元素对象的背景颜色和边框颜色分别设定为黄色和红色*/
js.executeScript("arguments[0].setAttribute('style', arguments[1]);", element, "background: yellow; border:2px solid red;");
}
}
}

View File

@ -1,155 +1,153 @@
package luckyclient.execution.webdriver;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import com.offbytwo.jenkins.model.BuildResult;
import luckyclient.execution.httpinterface.TestControl;
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.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.tool.jenkins.BuildingInitialization;
import luckyclient.tool.mail.HtmlMail;
import luckyclient.tool.mail.MailSendInitialization;
import luckyclient.tool.shell.RestartServerInitialization;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebTestControl {
/**
* @param args
* @throws ClassNotFoundException
* 控制台模式调度计划执行用例
*/
public static void manualExecutionPlan(String planname) {
// 不记日志到数据库
serverOperation.exetype = 1;
String taskid = "888888";
WebDriver wd = null;
try {
wd = WebDriverInitialization.setWebDriverForLocal();
} catch (IOException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("初始化WebDriver出现异常",e);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
LogUtil.APP.info("当前计划中读取到用例共【{}】个",testCases.size());
int i = 0;
for (ProjectCase testcase : testCases) {
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
i++;
LogUtil.APP.info("开始执行第{}条用例:【{}】......",i,testcase.getCaseSign());
try {
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
}
LogUtil.APP.info("当前项目测试计划中的用例已经全部执行完成...");
// 关闭浏览器
wd.quit();
}
public static void taskExecutionPlan(TaskExecute task) throws InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
String taskid = task.getTaskId().toString();
TestControl.TASKID = taskid;
String restartstatus = RestartServerInitialization.restartServerRun(taskid);
BuildResult buildResult = BuildingInitialization.buildingRun(taskid);
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));
String jobname = taskScheduling.getSchedulingName();
int drivertype = serverOperation.querydrivertype(taskid);
int[] tastcount = null;
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
// 判断是否构建是否成功
if (BuildResult.SUCCESS.equals(buildResult)) {
WebDriver wd = null;
try {
wd = WebDriverInitialization.setWebDriverForTask(drivertype);
} catch (WebDriverException e1) {
LogUtil.APP.error("初始化WebDriver出错 WebDriverException", e1);
} catch (IOException e2) {
LogUtil.APP.error("初始化WebDriver出错 IOException", e2);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
LogUtil.APP.info("当前测试任务 {} 中共有【{}】条待测试用例...",task.getTaskName(),cases.size());
serverOperation.updateTaskExecuteStatusIng(taskid, cases.size());
int i = 0;
for (ProjectCase testcase : cases) {
i++;
LogUtil.APP.info("开始执行当前测试任务 {} 的第【{}】条测试用例:【{}】......",task.getTaskName(),i,testcase.getCaseSign());
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
try {
// 插入开始执行的用例
caselog.insertTaskCaseExecute(taskid, taskScheduling.getProjectId(),testcase.getCaseId(),testcase.getCaseSign(), testcase.getCaseName(), 4);
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
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);
MailSendInitialization.sendMailInitialization(HtmlMail.htmlSubjectFormat(jobname),
HtmlMail.htmlContentFormat(tastcount, taskid, buildResult.toString(), restartstatus, testtime, jobname),
taskid, taskScheduling, tastcount);
// 关闭浏览器
wd.quit();
} else {
LogUtil.APP.warn("项目构建失败自动化测试自动退出请前往JENKINS中检查项目构建情况。");
MailSendInitialization.sendMailInitialization(jobname, "构建项目过程中失败自动化测试自动退出请前去JENKINS查看构建情况", taskid,
taskScheduling, tastcount);
}
} else {
LogUtil.APP.warn("项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况。");
MailSendInitialization.sendMailInitialization(jobname, "项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况", taskid,
taskScheduling, tastcount);
}
}
}
package luckyclient.execution.webdriver;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import com.offbytwo.jenkins.model.BuildResult;
import luckyclient.execution.httpinterface.TestControl;
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.remote.entity.TaskExecute;
import luckyclient.remote.entity.TaskScheduling;
import luckyclient.tool.jenkins.BuildingInitialization;
import luckyclient.tool.mail.HtmlMail;
import luckyclient.tool.mail.MailSendInitialization;
import luckyclient.tool.shell.RestartServerInitialization;
import luckyclient.utils.LogUtil;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
*
* @date 2017年12月1日 上午9:29:40
*
*/
public class WebTestControl {
/**
* 控制台模式调度计划执行用例
* @param planname
*/
public static void manualExecutionPlan(String planname) {
// 不记日志到数据库
serverOperation.exetype = 1;
String taskid = "888888";
WebDriver wd = null;
try {
wd = WebDriverInitialization.setWebDriverForLocal();
} catch (IOException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("初始化WebDriver出现异常",e);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> testCases = GetServerApi.getCasesbyplanname(planname);
List<ProjectCaseParams> pcplist = new ArrayList<ProjectCaseParams>();
if (testCases.size() != 0) {
pcplist = GetServerApi.cgetParamsByProjectid(String.valueOf(testCases.get(0).getProjectId()));
}
LogUtil.APP.info("当前计划中读取到用例共【{}】个",testCases.size());
int i = 0;
for (ProjectCase testcase : testCases) {
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
i++;
LogUtil.APP.info("开始执行第{}条用例:【{}】......",i,testcase.getCaseSign());
try {
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LogUtil.APP.error("用户执行过程中抛出异常!", e);
}
LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
}
LogUtil.APP.info("当前项目测试计划中的用例已经全部执行完成...");
// 关闭浏览器
wd.quit();
}
public static void taskExecutionPlan(TaskExecute task) throws InterruptedException {
// 记录日志到数据库
serverOperation.exetype = 0;
String taskid = task.getTaskId().toString();
TestControl.TASKID = taskid;
String restartstatus = RestartServerInitialization.restartServerRun(taskid);
BuildResult buildResult = BuildingInitialization.buildingRun(taskid);
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));
String jobname = taskScheduling.getSchedulingName();
int drivertype = serverOperation.querydrivertype(taskid);
int[] tastcount = null;
// 判断是否要自动重启TOMCAT
if (restartstatus.indexOf("Status:true") > -1) {
// 判断是否构建是否成功
if (BuildResult.SUCCESS.equals(buildResult)) {
WebDriver wd = null;
try {
wd = WebDriverInitialization.setWebDriverForTask(drivertype);
} catch (WebDriverException e1) {
LogUtil.APP.error("初始化WebDriver出错 WebDriverException", e1);
} catch (IOException e2) {
LogUtil.APP.error("初始化WebDriver出错 IOException", e2);
}
serverOperation caselog = new serverOperation();
List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
LogUtil.APP.info("当前测试任务 {} 中共有【{}】条待测试用例...",task.getTaskName(),cases.size());
serverOperation.updateTaskExecuteStatusIng(taskid, cases.size());
int i = 0;
for (ProjectCase testcase : cases) {
i++;
LogUtil.APP.info("开始执行当前测试任务 {} 的第【{}】条测试用例:【{}】......",task.getTaskName(),i,testcase.getCaseSign());
List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
if (steps.size() == 0) {
continue;
}
try {
// 插入开始执行的用例
caselog.insertTaskCaseExecute(taskid, taskScheduling.getProjectId(),testcase.getCaseId(),testcase.getCaseSign(), testcase.getCaseName(), 4);
WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
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);
MailSendInitialization.sendMailInitialization(HtmlMail.htmlSubjectFormat(jobname),
HtmlMail.htmlContentFormat(tastcount, taskid, buildResult.toString(), restartstatus, testtime, jobname),
taskid, taskScheduling, tastcount);
// 关闭浏览器
wd.quit();
} else {
LogUtil.APP.warn("项目构建失败自动化测试自动退出请前往JENKINS中检查项目构建情况。");
MailSendInitialization.sendMailInitialization(jobname, "构建项目过程中失败自动化测试自动退出请前去JENKINS查看构建情况", taskid,
taskScheduling, tastcount);
}
} else {
LogUtil.APP.warn("项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况。");
MailSendInitialization.sendMailInitialization(jobname, "项目TOMCAT重启失败自动化测试自动退出请检查项目TOMCAT运行情况", taskid,
taskScheduling, tastcount);
}
}
}

View File

@ -1,133 +1,133 @@
package luckyclient.execution.webdriver.ocr;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.Augmenter;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class Ocr {
/**
* 默认读取工程根目录下的文件
*/
private static String readtextpath = System.getProperty("user.dir")+"\\CAPTCHA.txt";
/**
* 默认把截图放在工程根目录
*/
private static String screenshotpath = System.getProperty("user.dir")+"\\CAPTCHA.png";
/**
* 批处理文件路径
*/
private static String cmdpath = System.getProperty("user.dir");
/**
* 默认把截图放在C盘根目录
*/
private static String cmdname = "handlingCAPTCHA.bat";
/**
* 读取生成的TXT文件中的验证码
* @param filePath
*/
private static String readTextFile() {
String lineTxt = "";
try {
String encoding = "GBK";
File file = new File(readtextpath);
// 判断文件是否存在
if (file.isFile() && file.exists()) {
// 考虑到编码格式
InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);
BufferedReader bufferedReader = new BufferedReader(read);
while ((lineTxt = bufferedReader.readLine()) != null) {
return lineTxt;
}
read.close();
} else {
return "找不到指定的文件";
}
} catch (Exception e) {
e.printStackTrace();
return "读取文件内容出错";
}
return lineTxt;
}
/**
* 截取验证码位置的图片
*
* @param
*/
private static void screenShotForElement(WebDriver driver, WebElement element){
driver = new Augmenter().augment(driver);
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
try {
Point p = element.getLocation();
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
Rectangle rect = new Rectangle(width, height);
BufferedImage img = ImageIO.read(scrFile);
BufferedImage dest = img.getSubimage(p.getX()-9, p.getY()+1, rect.width+2, rect.height+2);
ImageIO.write(dest, "png", scrFile);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileUtils.copyFile(scrFile, new File(screenshotpath));
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getCAPTCHA(WebDriver driver, WebElement element) {
String code = "";
screenShotForElement(driver, element);
Runtime run = Runtime.getRuntime();
try {
run.exec("cmd.exe /k start " + cmdname, null, new File(cmdpath));
Thread.sleep(1000);
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
code = readTextFile();
/* if (new File(readtextpath).exists()) {
new File(readtextpath).delete();
}
if (new File(screenshotpath).exists()) {
new File(screenshotpath).delete();
}*/
return code;
}
public static void main(String[] args) throws IOException, InterruptedException {
}
package luckyclient.execution.webdriver.ocr;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.Augmenter;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class Ocr {
/**
* 默认读取工程根目录下的文件
*/
private static String readtextpath = System.getProperty("user.dir")+"\\CAPTCHA.txt";
/**
* 默认把截图放在工程根目录
*/
private static String screenshotpath = System.getProperty("user.dir")+"\\CAPTCHA.png";
/**
* 批处理文件路径
*/
private static String cmdpath = System.getProperty("user.dir");
/**
* 默认把截图放在C盘根目录
*/
private static String cmdname = "handlingCAPTCHA.bat";
/**
* 读取生成的TXT文件中的验证码
* @return
*/
private static String readTextFile() {
String lineTxt = "";
try {
String encoding = "GBK";
File file = new File(readtextpath);
// 判断文件是否存在
if (file.isFile() && file.exists()) {
// 考虑到编码格式
InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);
BufferedReader bufferedReader = new BufferedReader(read);
while ((lineTxt = bufferedReader.readLine()) != null) {
return lineTxt;
}
read.close();
} else {
return "找不到指定的文件";
}
} catch (Exception e) {
e.printStackTrace();
return "读取文件内容出错";
}
return lineTxt;
}
/**
* 截取验证码位置的图片
*
* @param
*/
private static void screenShotForElement(WebDriver driver, WebElement element){
driver = new Augmenter().augment(driver);
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
try {
Point p = element.getLocation();
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
Rectangle rect = new Rectangle(width, height);
BufferedImage img = ImageIO.read(scrFile);
BufferedImage dest = img.getSubimage(p.getX()-9, p.getY()+1, rect.width+2, rect.height+2);
ImageIO.write(dest, "png", scrFile);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileUtils.copyFile(scrFile, new File(screenshotpath));
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getCAPTCHA(WebDriver driver, WebElement element) {
String code = "";
screenShotForElement(driver, element);
Runtime run = Runtime.getRuntime();
try {
run.exec("cmd.exe /k start " + cmdname, null, new File(cmdpath));
Thread.sleep(1000);
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
code = readTextFile();
/* if (new File(readtextpath).exists()) {
new File(readtextpath).delete();
}
if (new File(screenshotpath).exists()) {
new File(screenshotpath).delete();
}*/
return code;
}
public static void main(String[] args) throws IOException, InterruptedException {
}
}

View File

@ -1,166 +1,167 @@
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.utils.httputils.HttpRequest;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class GetServerApi {
private static final String PREFIX = "/openGetApi";
/**
* 通过计划ID获取测试用例对象集
* @param planid
* @return
*/
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;
}
/**
* 通过计划名称获取测试用例对象集
* @param name
* @return
*/
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;
}
/**
* 通过用例ID获取下面的步骤对象
* @param caseid
* @return
*/
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;
}
/**
* 通过taskid获取对象
* @param taskid
* @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;
}
/**
* 通过taskid获取调度对象
* @param taskid
* @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;
}
/**
* 通过用例编号获取对象
* @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;
}
/**
* 通过用例ID获取对象
* @param sign
* @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;
}
/**
* 获取项目下的所有公共参数
* @param projectid
* @return
*/
public static List<ProjectCaseParams> cgetParamsByProjectid(String projectid) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetParamsByProjectId.do?projectId="+projectid);
List<ProjectCaseParams> paramsList = JSONObject.parseArray(result, ProjectCaseParams.class);
//当公共参数存在内置函数时先进行数据转换
for(ProjectCaseParams pcp:paramsList){
pcp.setParamsValue(ParamsManageForSteps.paramsManage(pcp.getParamsValue()));
}
return paramsList;
}
/**
* 通过计划ID获取测试用例对象集
* @param planid
* @return
*/
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;
}
/**
* 通过templateId获取实体
* @param templateId
* @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;
}
/**
* 通过模板ID获取参数列表
* @param templateId
* @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 {
}
}
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.utils.httputils.HttpRequest;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class GetServerApi {
private static final String PREFIX = "/openGetApi";
/**
* 通过计划ID获取测试用例对象集
* @param planId
* @return
*/
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;
}
/**
* 通过计划名称获取测试用例对象集
* @param name
* @return
*/
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;
}
/**
* 通过用例ID获取下面的步骤对象
* @param caseid
* @return
*/
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;
}
/**
* 通过taskid获取对象
* @param taskid
* @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;
}
/**
* 通过taskid获取调度对象
* @param taskid
* @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;
}
/**
* 通过用例编号获取对象
* @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;
}
/**
* 通过用例ID获取对象
* @param caseId
* @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;
}
/**
* 获取项目下的所有公共参数
* @param projectid
* @return
*/
public static List<ProjectCaseParams> cgetParamsByProjectid(String projectid) {
String result = HttpRequest.loadJSON(PREFIX+"/clientGetParamsByProjectId.do?projectId="+projectid);
List<ProjectCaseParams> paramsList = JSONObject.parseArray(result, ProjectCaseParams.class);
//当公共参数存在内置函数时先进行数据转换
for(ProjectCaseParams pcp:paramsList){
pcp.setParamsValue(ParamsManageForSteps.paramsManage(pcp.getParamsValue()));
}
return paramsList;
}
/**
* 通过计划ID获取测试用例对象集
* @param taskId
* @return
*/
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;
}
/**
* 通过templateId获取实体
* @param templateId
* @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;
}
/**
* 通过模板ID获取参数列表
* @param templateId
* @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 {
}
}

View File

@ -1,146 +1,145 @@
package luckyclient.remote.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import luckyclient.remote.entity.ProjectCaseDebug;
import luckyclient.remote.entity.TaskCaseExecute;
import luckyclient.remote.entity.TaskCaseLog;
import luckyclient.utils.httputils.HttpRequest;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年4月18日
*/
public class PostServerApi {
private static final String PREFIX = "/openPostApi";
/**
* put web界面的数据到服务端
* @param sign
* @param executor
* @param loglevel
* @param detail
*/
public static void cPostDebugLog(Integer userId, Integer caseId, String logLevel, String logDetail,Integer debugIsend){
ProjectCaseDebug projectCaseDebug = new ProjectCaseDebug();
projectCaseDebug.setCaseId(caseId);
projectCaseDebug.setUserId(userId);
projectCaseDebug.setLogLevel(logLevel);
projectCaseDebug.setLogDetail(logDetail);
projectCaseDebug.setDebugIsend(debugIsend);
HttpRequest.httpClientPostJson(PREFIX+"/clientPostCaseDebugLog", JSONObject.toJSONString(projectCaseDebug));
}
/**
* 插入用例执行明细到数据库
* @param taskId
* @param projectId
* @param caseId
* @param caseSign
* @param caseName
* @param caseStatus
* @author Seagull
* @date 2019年4月22日
*/
public static void clientPostInsertTaskCaseExecute(Integer taskId, Integer projectId, Integer caseId, String caseSign, String caseName, Integer caseStatus){
TaskCaseExecute taskCaseExecute = new TaskCaseExecute();
taskCaseExecute.setTaskId(taskId);
taskCaseExecute.setProjectId(projectId);
taskCaseExecute.setCaseId(caseId);
taskCaseExecute.setCaseSign(caseSign);
taskCaseExecute.setCaseName(caseName);
taskCaseExecute.setCaseStatus(caseStatus);
HttpRequest.httpClientPostJson(PREFIX+"/clientPostTaskCaseExecute", JSONObject.toJSONString(taskCaseExecute));
}
/**
* 修改用例执行状态
* @param taskId
* @param caseId
* @param caseStatus
* @author Seagull
* @date 2019年4月22日
*/
public static void clientUpdateTaskCaseExecuteStatus(Integer taskId, Integer caseId, Integer caseStatus){
TaskCaseExecute taskCaseExecute = new TaskCaseExecute();
taskCaseExecute.setTaskId(taskId);
taskCaseExecute.setCaseId(caseId);
taskCaseExecute.setCaseStatus(caseStatus);
HttpRequest.httpClientPostJson(PREFIX+"/clientUpdateTaskCaseExecuteStatus", JSONObject.toJSONString(taskCaseExecute));
}
/**
* 插入用例执行明细到数据库
* @param taskId
* @param caseId
* @param logDetail
* @param logGrade
* @param logStep
* @param imgname
* @author Seagull
* @date 2019年4月22日
*/
public static void clientPostInsertTaskCaseLog(Integer taskId, Integer caseId, String logDetail, String logGrade, String logStep,
String imgname){
TaskCaseLog taskCaseLog = new TaskCaseLog();
taskCaseLog.setTaskId(taskId);
taskCaseLog.setCaseId(caseId);
taskCaseLog.setLogDetail(logDetail);
taskCaseLog.setLogGrade(logGrade);
taskCaseLog.setLogStep(logStep);
taskCaseLog.setImgname(imgname);
HttpRequest.httpClientPostJson(PREFIX+"/clientPostTaskCaseLog", JSONObject.toJSONString(taskCaseLog));
}
/**
* 更新任务执行数据
* @param taskId
* @param casecount
* @author Seagull
* @date 2019年4月22日
*/
public static String clientUpdateTaskExecuteData(Integer taskId, Integer caseCount, Integer taskStatus){
String str = "{\"taskId\":"+taskId+",\"caseCount\":"+caseCount+",\"taskStatus\":"+taskStatus+"}";
JSONObject jsonObject = JSON.parseObject(str);
return HttpRequest.httpClientPostJson(PREFIX+"/clientUpdateTaskExecuteData", jsonObject.toJSONString());
}
/**
* 更新任务执行数据
* @param taskId
* @param casecount
* @author Seagull
* @date 2019年4月22日
*/
public static String clientDeleteTaskCaseLog(Integer taskId, Integer caseId){
String str = "{\"taskId\":"+taskId+",\"caseId\":"+caseId+"}";
JSONObject jsonObject = JSON.parseObject(str);
return HttpRequest.httpClientPostJson(PREFIX+"/clientDeleteTaskCaseLog", jsonObject.toJSONString());
}
/**
* 提取测试用例的详细日志以及结果
* @param taskId
* @param casecount
* @author Seagull
* @date 2019年4月22日
*/
public static String getLogDetailResult(String taskName, String caseSign){
String str = "{\"taskName\":\""+taskName+"\",\"caseSign\":\""+caseSign+"\"}";
JSONObject jsonObject = JSON.parseObject(str);
return HttpRequest.httpClientPostJson(PREFIX+"/getLogDetailResult", jsonObject.toJSONString());
}
}
package luckyclient.remote.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import luckyclient.remote.entity.ProjectCaseDebug;
import luckyclient.remote.entity.TaskCaseExecute;
import luckyclient.remote.entity.TaskCaseLog;
import luckyclient.utils.httputils.HttpRequest;
/**
*
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改 有任何疑问欢迎联系作者讨论 QQ:1573584944 Seagull
* =================================================================
* @author Seagull
* @date 2019年4月18日
*/
public class PostServerApi {
private static final String PREFIX = "/openPostApi";
/**
* put web界面的数据到服务端
* @param userId
* @param caseId
* @param logLevel
* @param logDetail
* @param debugIsend
*/
public static void cPostDebugLog(Integer userId, Integer caseId, String logLevel, String logDetail,Integer debugIsend){
ProjectCaseDebug projectCaseDebug = new ProjectCaseDebug();
projectCaseDebug.setCaseId(caseId);
projectCaseDebug.setUserId(userId);
projectCaseDebug.setLogLevel(logLevel);
projectCaseDebug.setLogDetail(logDetail);
projectCaseDebug.setDebugIsend(debugIsend);
HttpRequest.httpClientPostJson(PREFIX+"/clientPostCaseDebugLog", JSONObject.toJSONString(projectCaseDebug));
}
/**
* 插入用例执行明细到数据库
* @param taskId
* @param projectId
* @param caseId
* @param caseSign
* @param caseName
* @param caseStatus
* @author Seagull
* @date 2019年4月22日
*/
public static void clientPostInsertTaskCaseExecute(Integer taskId, Integer projectId, Integer caseId, String caseSign, String caseName, Integer caseStatus){
TaskCaseExecute taskCaseExecute = new TaskCaseExecute();
taskCaseExecute.setTaskId(taskId);
taskCaseExecute.setProjectId(projectId);
taskCaseExecute.setCaseId(caseId);
taskCaseExecute.setCaseSign(caseSign);
taskCaseExecute.setCaseName(caseName);
taskCaseExecute.setCaseStatus(caseStatus);
HttpRequest.httpClientPostJson(PREFIX+"/clientPostTaskCaseExecute", JSONObject.toJSONString(taskCaseExecute));
}
/**
* 修改用例执行状态
* @param taskId
* @param caseId
* @param caseStatus
* @author Seagull
* @date 2019年4月22日
*/
public static void clientUpdateTaskCaseExecuteStatus(Integer taskId, Integer caseId, Integer caseStatus){
TaskCaseExecute taskCaseExecute = new TaskCaseExecute();
taskCaseExecute.setTaskId(taskId);
taskCaseExecute.setCaseId(caseId);
taskCaseExecute.setCaseStatus(caseStatus);
HttpRequest.httpClientPostJson(PREFIX+"/clientUpdateTaskCaseExecuteStatus", JSONObject.toJSONString(taskCaseExecute));
}
/**
* 插入用例执行明细到数据库
* @param taskId
* @param caseId
* @param logDetail
* @param logGrade
* @param logStep
* @param imgname
* @author Seagull
* @date 2019年4月22日
*/
public static void clientPostInsertTaskCaseLog(Integer taskId, Integer caseId, String logDetail, String logGrade, String logStep,
String imgname){
TaskCaseLog taskCaseLog = new TaskCaseLog();
taskCaseLog.setTaskId(taskId);
taskCaseLog.setCaseId(caseId);
taskCaseLog.setLogDetail(logDetail);
taskCaseLog.setLogGrade(logGrade);
taskCaseLog.setLogStep(logStep);
taskCaseLog.setImgname(imgname);
HttpRequest.httpClientPostJson(PREFIX+"/clientPostTaskCaseLog", JSONObject.toJSONString(taskCaseLog));
}
/**
* 更新任务执行数据
* @param taskId
* @param caseCount
* @param taskStatus
* @return
*/
public static String clientUpdateTaskExecuteData(Integer taskId, Integer caseCount, Integer taskStatus){
String str = "{\"taskId\":"+taskId+",\"caseCount\":"+caseCount+",\"taskStatus\":"+taskStatus+"}";
JSONObject jsonObject = JSON.parseObject(str);
return HttpRequest.httpClientPostJson(PREFIX+"/clientUpdateTaskExecuteData", jsonObject.toJSONString());
}
/**
* 更新任务执行数据
* @param taskId
* @param caseId
* @return
*/
public static String clientDeleteTaskCaseLog(Integer taskId, Integer caseId){
String str = "{\"taskId\":"+taskId+",\"caseId\":"+caseId+"}";
JSONObject jsonObject = JSON.parseObject(str);
return HttpRequest.httpClientPostJson(PREFIX+"/clientDeleteTaskCaseLog", jsonObject.toJSONString());
}
/**
* 提取测试用例的详细日志以及结果
* @param taskName
* @param caseSign
* @return
*/
public static String getLogDetailResult(String taskName, String caseSign){
String str = "{\"taskName\":\""+taskName+"\",\"caseSign\":\""+caseSign+"\"}";
JSONObject jsonObject = JSON.parseObject(str);
return HttpRequest.httpClientPostJson(PREFIX+"/getLogDetailResult", jsonObject.toJSONString());
}
}

View File

@ -1,121 +1,119 @@
package luckyclient.tool.shell;
import java.io.InputStream;
import java.io.OutputStream;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import luckyclient.utils.LogUtil;
/**
* 远程执行shell脚本类
* @author l
*/
public class RmtShellExecutor {
/**
* 利用JSch包实现远程主机SHELL命令执行
* @param ip 主机IP
* @param user 主机登陆用户名
* @param psw 主机登陆密码
* @param port 主机ssh2登陆端口如果取默认值-1
* @param privateKey 密钥文件路径
* @param passphrase 密钥的密码
* @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();
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();
}
}
return result;
}
public static void main(String args[]) throws Exception {
}
package luckyclient.tool.shell;
import java.io.InputStream;
import java.io.OutputStream;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
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();
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();
}
}
return result;
}
public static void main(String args[]) throws Exception {
}
}

View File

@ -1,153 +1,151 @@
package luckyclient.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: DBOperation
* @Description: 封装自动化过程中对数据库的部分操作
* @author seagull
* @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 request
* @param response
* @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 request
* @param response
* @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("%");
}
/* 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);
}
}
/**
*
* @Title: subString
* @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) {
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);
}
}
package luckyclient.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: DBOperation
* @Description: 封装自动化过程中对数据库的部分操作
* @author seagull
* @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("%");
}
/* 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);
}
}
/**
*
* @Title: subString
* @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) {
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);
}
}

View File

@ -1,132 +1,132 @@
package luckyclient.utils;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import luckyclient.utils.config.DrivenConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: DBToolkit
* @Description: 创建与关闭数据库链接
* @author seagull
* @date 2014年8月24日 上午9:29:40
*
*/
public class DbToolkit {
/**
* 建立数据库链接池
*/
public ComboPooledDataSource cpds=null;
private static final String DRIVERCLASS = DrivenConfig.getConfiguration().getProperty("db.ComboPooledDataSource.DriverClass");
public DbToolkit(String urlBase,String usernameBase,String passwordBase){
cpds=new ComboPooledDataSource();
cpds.setUser(usernameBase);
cpds.setPassword(passwordBase);
cpds.setJdbcUrl(urlBase);
try {
cpds.setDriverClass(DRIVERCLASS);
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cpds.setInitialPoolSize(20);
cpds.setMaxIdleTime(20);
cpds.setMaxPoolSize(30);
cpds.setMinPoolSize(1);
}
static {
//注册驱动类
try {
Class.forName(DRIVERCLASS);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public Connection getBaseConnection() throws SQLException{
// TODO Auto-generated method stub
Connection conn = cpds.getConnection();
return conn;
}
/**
* 在一个数据库连接上执行一个静态SQL语句查询
*
* @param conn 数据库连接
* @param staticSql 静态SQL语句字符串
* @return 返回查询结果集ResultSet对象
* @throws SQLException
*/
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;
}
/**
* 在一个数据库连接上执行一个静态SQL语句
*
* @param conn数据库连接
* @param staticSql 静态SQL语句字符串
* @throws SQLException
*/
public static int executeSQL(Connection conn, String staticSql) throws SQLException {
//创建执行SQL的对象
Statement stmt = conn.createStatement();
//执行SQL并获取返回结果
stmt.execute(staticSql);
return stmt.getUpdateCount();
}
/**
* 在一个数据库连接上执行一批静态SQL语句
*
* @param conn 数据库连接
* @param sqlList 静态SQL语句字符串集合
*/
public static void executeBatchSQL(Connection conn, List<String> sqlList) {
try {
//创建执行SQL的对象
Statement stmt = conn.createStatement();
for (String sql : sqlList) {
stmt.addBatch(sql);
}
//执行SQL并获取返回结果
stmt.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void closeConnection(Connection conn) {
if (conn == null){
return;
}
try {
if (!conn.isClosed()) {
//关闭数据库连接
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package luckyclient.utils;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import luckyclient.utils.config.DrivenConfig;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @ClassName: DBToolkit
* @Description: 创建与关闭数据库链接
* @author seagull
* @date 2014年8月24日 上午9:29:40
*
*/
public class DbToolkit {
/**
* 建立数据库链接池
*/
public ComboPooledDataSource cpds=null;
private static final String DRIVERCLASS = DrivenConfig.getConfiguration().getProperty("db.ComboPooledDataSource.DriverClass");
public DbToolkit(String urlBase,String usernameBase,String passwordBase){
cpds=new ComboPooledDataSource();
cpds.setUser(usernameBase);
cpds.setPassword(passwordBase);
cpds.setJdbcUrl(urlBase);
try {
cpds.setDriverClass(DRIVERCLASS);
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cpds.setInitialPoolSize(20);
cpds.setMaxIdleTime(20);
cpds.setMaxPoolSize(30);
cpds.setMinPoolSize(1);
}
static {
//注册驱动类
try {
Class.forName(DRIVERCLASS);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public Connection getBaseConnection() throws SQLException{
// TODO Auto-generated method stub
Connection conn = cpds.getConnection();
return conn;
}
/**
* 在一个数据库连接上执行一个静态SQL语句查询
*
* @param conn 数据库连接
* @param staticSql 静态SQL语句字符串
* @return 返回查询结果集ResultSet对象
* @throws SQLException
*/
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;
}
/**
* 在一个数据库连接上执行一个静态SQL语句
*
* @param conn 数据库连接
* @param staticSql 静态SQL语句字符串
* @throws SQLException
*/
public static int executeSQL(Connection conn, String staticSql) throws SQLException {
//创建执行SQL的对象
Statement stmt = conn.createStatement();
//执行SQL并获取返回结果
stmt.execute(staticSql);
return stmt.getUpdateCount();
}
/**
* 在一个数据库连接上执行一批静态SQL语句
*
* @param conn 数据库连接
* @param sqlList 静态SQL语句字符串集合
*/
public static void executeBatchSQL(Connection conn, List<String> sqlList) {
try {
//创建执行SQL的对象
Statement stmt = conn.createStatement();
for (String sql : sqlList) {
stmt.addBatch(sql);
}
//执行SQL并获取返回结果
stmt.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void closeConnection(Connection conn) {
if (conn == null){
return;
}
try {
if (!conn.isClosed()) {
//关闭数据库连接
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -1,194 +1,185 @@
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 org.apache.http.HttpResponse;
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.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;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class HttpRequest {
final static Properties PROPERTIES = SysConfig.getConfiguration();
private final static String WEB_URL = "http://" + PROPERTIES.getProperty("server.web.ip") + ":"
+ PROPERTIES.getProperty("server.web.port");
/**
* 字符串参数
*
* @param url
* @return
*/
public static String loadJSON(String repath) {
String charset="GBK";
StringBuffer resultBuffer = null;
CloseableHttpClient httpclient = HttpClients.createDefault();
BufferedReader br = null;
// 构建请求参数
HttpGet httpGet = new HttpGet(WEB_URL+repath);
try {
HttpResponse response = httpclient.execute(httpGet);
// 读取服务器响应数据
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), charset));
String temp;
resultBuffer = new StringBuffer();
while ((temp = br.readLine()) != null) {
resultBuffer.append(temp);
}
} catch (Exception e) {
LogUtil.APP.error("loadJSON发送请求出现异常请检查", e);
throw new RuntimeException(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
LogUtil.APP.error("loadJSON发送请求后关闭br流出现异常请检查", e);
br = null;
throw new RuntimeException(e);
}
}
}
return resultBuffer.toString();
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数请求参数应该是 name1=value1&name2=value2 的形式
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String repath, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(WEB_URL+repath);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流设置utf-8编码
out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "GBK"));
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应,设置utf-8编码
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
LogUtil.APP.error("向指定URL发送POST方法的请求出现异常请检查", e);
}
//使用finally块来关闭输出流输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
LogUtil.APP.error("向指定URL发送POST方法的请求后关闭流出现异常请检查", ex);
}
}
return result;
}
/**
* 使用HttpClient以JSON格式发送post请求
* @param urlParam
* @param params
* @param charset
* @param headmsg
* @param cerpath
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static String httpClientPostJson(String urlParam, String params){
StringBuffer resultBuffer = null;
CloseableHttpClient httpclient=HttpClients.createDefault();
HttpPost httpPost = new HttpPost(WEB_URL+urlParam);
httpPost.setHeader("Content-Type", "application/json");
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(60*1000)
.setConnectionRequestTimeout(60*1000)
//设置请求和传输超时时间
.setSocketTimeout(60*1000).build();
httpPost.setConfig(requestConfig);
// 构建请求参数
BufferedReader br = null;
try {
StringEntity entity = new StringEntity(params,"utf-8");
httpPost.setEntity(entity);
CloseableHttpResponse response = httpclient.execute(httpPost);
// 读取服务器响应数据
resultBuffer = new StringBuffer();
if(null!=response.getEntity()){
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
String temp;
while ((temp = br.readLine()) != null) {
resultBuffer.append(temp);
}
}
} catch (Exception e) {
LogUtil.APP.error("使用HttpClient以JSON格式发送post请求出现异常请检查", e);
throw new RuntimeException(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
br = null;
LogUtil.APP.error("使用HttpClient以JSON格式发送post请求后关闭br流出现异常请检查", e);
throw new RuntimeException(e);
}
}
}
return resultBuffer.toString();
}
}
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 org.apache.http.HttpResponse;
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.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;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
*
* @author seagull
* @date 2017年12月1日 上午9:29:40
*
*/
public class HttpRequest {
final static Properties PROPERTIES = SysConfig.getConfiguration();
private final static String WEB_URL = "http://" + PROPERTIES.getProperty("server.web.ip") + ":"
+ PROPERTIES.getProperty("server.web.port");
/**
* 字符串参数
* @param repath
* @return
*/
public static String loadJSON(String repath) {
String charset="GBK";
StringBuffer resultBuffer = null;
CloseableHttpClient httpclient = HttpClients.createDefault();
BufferedReader br = null;
// 构建请求参数
HttpGet httpGet = new HttpGet(WEB_URL+repath);
try {
HttpResponse response = httpclient.execute(httpGet);
// 读取服务器响应数据
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), charset));
String temp;
resultBuffer = new StringBuffer();
while ((temp = br.readLine()) != null) {
resultBuffer.append(temp);
}
} catch (Exception e) {
LogUtil.APP.error("loadJSON发送请求出现异常请检查", e);
throw new RuntimeException(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
LogUtil.APP.error("loadJSON发送请求后关闭br流出现异常请检查", e);
br = null;
throw new RuntimeException(e);
}
}
}
return resultBuffer.toString();
}
/**
* 向指定 URL 发送POST方法的请求
* @param param
* 请求参数请求参数应该是 name1=value1&name2=value2 的形式
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String repath, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(WEB_URL+repath);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流设置utf-8编码
out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "GBK"));
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应,设置utf-8编码
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
LogUtil.APP.error("向指定URL发送POST方法的请求出现异常请检查", e);
}
//使用finally块来关闭输出流输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
LogUtil.APP.error("向指定URL发送POST方法的请求后关闭流出现异常请检查", ex);
}
}
return result;
}
/**
* 使用HttpClient以JSON格式发送post请求
* @param urlParam
* @param params
* @return
*/
public static String httpClientPostJson(String urlParam, String params){
StringBuffer resultBuffer = null;
CloseableHttpClient httpclient=HttpClients.createDefault();
HttpPost httpPost = new HttpPost(WEB_URL+urlParam);
httpPost.setHeader("Content-Type", "application/json");
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(60*1000)
.setConnectionRequestTimeout(60*1000)
//设置请求和传输超时时间
.setSocketTimeout(60*1000).build();
httpPost.setConfig(requestConfig);
// 构建请求参数
BufferedReader br = null;
try {
StringEntity entity = new StringEntity(params,"utf-8");
httpPost.setEntity(entity);
CloseableHttpResponse response = httpclient.execute(httpPost);
// 读取服务器响应数据
resultBuffer = new StringBuffer();
if(null!=response.getEntity()){
br = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
String temp;
while ((temp = br.readLine()) != null) {
resultBuffer.append(temp);
}
}
} catch (Exception e) {
LogUtil.APP.error("使用HttpClient以JSON格式发送post请求出现异常请检查", e);
throw new RuntimeException(e);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
br = null;
LogUtil.APP.error("使用HttpClient以JSON格式发送post请求后关闭br流出现异常请检查", e);
throw new RuntimeException(e);
}
}
}
return resultBuffer.toString();
}
}

View File

@ -1,393 +1,392 @@
package springboot;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
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.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;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import luckyclient.remote.entity.monitor.Server;
import luckyclient.utils.config.SysConfig;
import luckyclient.utils.httputils.HttpRequest;
import springboot.model.RunBatchCaseEntity;
import springboot.model.RunTaskEntity;
import springboot.model.WebDebugCaseEntity;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年7月27日 上午10:28:32
*/
@RestController
public class HttpImpl {
private static final Logger log = LoggerFactory.getLogger(HttpImpl.class);
private static final String OS=System.getProperty("os.name").toLowerCase();
/**
* 运行自动化任务
* @param req
* @param res
* @return
* @throws RemoteException
*/
@PostMapping("/runTask")
private String runTask(HttpServletRequest req) throws RemoteException {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
sb.append(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
log.info("开始转换RunTaskEntity执行任务实体...");
RunTaskEntity runTaskEntity = JSONObject.parseObject(sb.toString(), RunTaskEntity.class);
log.info("TaskId:{},SchedulingName:{},LoadPath:{}",runTaskEntity.getTaskId(),runTaskEntity.getSchedulingName(),runTaskEntity.getLoadPath());
try{
log.info("开始获取客户端驱动路径...");
File file =new File(System.getProperty("user.dir")+runTaskEntity.getLoadPath());
log.info("客户端驱动路径:{}",file.getAbsolutePath());
if (!file .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",file.getPath());
return "客户端测试驱动桩路径不存在,请检查【"+file.getPath()+"";
}
log.info("初始化Runtime...");
Runtime run = Runtime.getRuntime();
StringBuffer sbf=new StringBuffer();
sbf.append(runTaskEntity.getTaskId()).append(" ");
sbf.append(runTaskEntity.getLoadPath());
log.info("启动任务模式测试程序...调度名称:【{}】 任务ID:【{}】",runTaskEntity.getSchedulingName(),runTaskEntity.getTaskId());
if(OS.startsWith("win")){
log.info("开始调起windows命令行窗口...");
run.exec("cmd.exe /k start " + "task.cmd" +" "+ sbf.toString(), null,new File(System.getProperty("user.dir")+File.separator));
log.info("调起windows命令行窗口完成...");
}else{
log.info("开始调起Linux命令脚本...");
Process ps = Runtime.getRuntime().exec(System.getProperty("user.dir")+File.separator+"task.sh"+ " " +sbf.toString());
ps.waitFor();
log.info("调起Linux命令脚本完成...");
}
} catch (Exception e) {
log.error("启动任务模式测试程序异常!!!",e);
return "启动任务模式测试程序异常!!!";
}
return "启动任务模式测试程序正常";
}
/**
* 批量运行用例
* @param req
* @return
* @throws RemoteException
*/
@PostMapping("/runBatchCase")
private String runBatchCase(HttpServletRequest req) throws RemoteException {
StringBuilder sbd = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
sbd.append(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
log.info("开始转换RunBatchCaseEntity批量执行用例实体...");
RunBatchCaseEntity runBatchCaseEntity = JSONObject.parseObject(sbd.toString(), RunBatchCaseEntity.class);
String projectName = runBatchCaseEntity.getProjectname();
String taskId = runBatchCaseEntity.getTaskid();
String loadPath = runBatchCaseEntity.getLoadpath();
String batchCase = runBatchCaseEntity.getBatchcase();
log.info("批量测试用例:{}",batchCase);
try{
log.info("开始获取客户端驱动路径...");
File file =new File(System.getProperty("user.dir")+loadPath);
log.info("客户端驱动路径:{}",file.getAbsolutePath());
if (!file .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",file.getPath());
return "客户端测试驱动桩路径不存在,请检查【"+file.getPath()+"";
}
log.info("初始化Runtime...");
Runtime run = Runtime.getRuntime();
StringBuffer sb=new StringBuffer();
sb.append(taskId).append(" ");
sb.append(batchCase).append(" ");
sb.append(loadPath);
log.info("启动批量用例模式测试程序...测试项目:{} 任务ID:{}",projectName,taskId);
if(OS.startsWith("win")){
log.info("开始调起windows命令行窗口...");
run.exec("cmd.exe /k start " + "task_batch.cmd" + " " +sb.toString(), null,new File(System.getProperty("user.dir")+File.separator));
log.info("调起windows命令行窗口完成...");
}else{
log.info("开始调起Linux命令脚本...");
Process ps = Runtime.getRuntime().exec(System.getProperty("user.dir")+File.separator+"task_batch.sh"+ " " +sb.toString());
ps.waitFor();
log.info("调起Linux命令脚本完成...");
}
} catch (Exception e) {
e.printStackTrace();
log.error("启动批量用例模式测试程序异常!!!",e);
return "启动批量用例模式测试程序异常!!!";
}
return "启动批量用例模式测试程序正常";
}
/**
* web界面调度接口
* @param req
* @return
* @throws RemoteException
*/
@PostMapping("/webDebugCase")
private String webDebugCase(HttpServletRequest req) throws RemoteException {
StringBuilder sbd = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
sbd.append(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
WebDebugCaseEntity webDebugCaseEntity = JSONObject.parseObject(sbd.toString(), WebDebugCaseEntity.class);
log.info("Web端调试用例ID:{} 发起人ID:{}",webDebugCaseEntity.getCaseId(),webDebugCaseEntity.getUserId());
try{
File file =new File(System.getProperty("user.dir")+webDebugCaseEntity.getLoadpath());
if (!file .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",file.getPath());
return "客户端测试驱动桩路径不存在,请检查【"+file.getPath()+"";
}
Runtime run = Runtime.getRuntime();
StringBuffer sb=new StringBuffer();
sb.append(webDebugCaseEntity.getCaseId()).append(" ");
sb.append(webDebugCaseEntity.getUserId()).append(" ");
sb.append(webDebugCaseEntity.getLoadpath());
if(OS.startsWith("win")){
run.exec("cmd.exe /k start " + "web_debugcase.cmd" + " " +sb.toString(), null,new File(System.getProperty("user.dir")+File.separator));
}else{
Process ps = Runtime.getRuntime().exec(System.getProperty("user.dir")+File.separator+"web_debugcase.sh"+ " " +sb.toString());
ps.waitFor();
}
} catch (Exception e) {
e.printStackTrace();
log.error("启动Web调试模式测试程序异常",e);
return "启动Web调试模式测试程序异常";
}
return "启动Web调试模式测试程序正常";
}
/**
* 获取客户端本地日志
* @param req
* @return
* @throws RemoteException
*/
@GetMapping("/getLogdDetail")
private String getLogdDetail(HttpServletRequest req) throws RemoteException{
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;
try {
isr = new InputStreamReader(new FileInputStream(downLoadPath), "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("读取日志路径错误,请检查客户端日志路径是否存在!downLoadPath: "+downLoadPath,e);
return "读取日志路径错误,请检查客户端日志路径是否存在!downLoadPath: "+downLoadPath;
}
BufferedReader bos = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
try {
while ((str = bos.readLine()) != null)
{
sb.append(str).append("##n##");
}
bos.close();
log.info("服务端读取本地日志成功!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("客户端转BufferedReader失败请检查原因",e);
return "客户端转BufferedReader失败请检查原因";
}
return sb.toString();
}
/**
* 获取错误截图
* @param req
* @return
* @throws RemoteException
*/
@GetMapping("/getLogImg")
private byte[] getLogImg(HttpServletRequest req,HttpServletResponse res) throws RemoteException{
String imgName=req.getParameter("imgName");
String ctxPath = System.getProperty("user.dir")+File.separator+"log"+File.separator+"ScreenShot";
String downLoadPath = ctxPath+File.separator+imgName;
byte[] b = null;
try {
File file = new File(downLoadPath);
b = new byte[(int) file.length()];
BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
is.read(b);
is.close();
log.info("服务端获取本地图片:{}",downLoadPath);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
log.error("此文件不存在,请检查:{}",downLoadPath,e);
return b;
} catch (IOException e) {
// TODO Auto-generated catch block
return b;
}
return b;
}
/**
* 上传驱动文件到客户端
*/
@PostMapping("/uploadJar")
private String uploadJar(HttpServletRequest req,HttpServletResponse res, HttpSession session,@RequestParam("jarfile") MultipartFile jarfile) throws IOException, ServletException{
if (!jarfile.isEmpty()){
if (!jarfile.getOriginalFilename().endsWith(".jar")&&!jarfile.getOriginalFilename().endsWith(".py")) {
log.warn("文件格式后缀不是.jar或.py上传失败");
return "文件格式后缀不是.jar或.py上传失败";
}
}else{
log.warn("上传文件为空,请检查!");
return "上传文件为空,请检查!";
}
String name = jarfile.getOriginalFilename();
String loadpath = req.getParameter("loadpath");
String path = System.getProperty("user.dir")+loadpath;
if (!new File(path) .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",path);
return "客户端测试驱动桩路径不存在,请检查【"+path+"";
}
String pathName = path +File.separator+ name;
File file = new File(pathName);
try {
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()+"】成功!";
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
log.error("客户端未找到正确路径或文件,上传失败!文件路径名称:{}",pathName,e);
return "客户端未找到正确路径或文件,上传失败!文件路径名称:"+pathName;
} catch (IOException e) {
// TODO Auto-generated catch block
log.error("客户端IOExceptiona或是未找到驱动路径文件路径名称:{}",pathName,e);
return "客户端IOExceptiona或是未找到驱动路径文件路径名称"+pathName;
}
}
/**
* 检查客户端心跳
* @param req
* @return
* @throws RemoteException
*/
@GetMapping("/getClientStatus")
private String getClientStatus(HttpServletRequest req) throws RemoteException{
Properties properties = SysConfig.getConfiguration();
String verison=properties.getProperty("client.verison");
return "{\"status\":\"success\",\"version\":\""+verison+"\"}";
}
/**
* 获取客户端资源监控情况
* @param req
* @return
* @author Seagull
* @throws Exception
* @date 2019年5月5日
*/
@GetMapping("/getClientMonitorData")
private String getClientMonitorData(HttpServletRequest req) throws Exception{
Server server = new Server();
server.copyTo();
return JSON.toJSONString(server);
}
/**
* 检查客户端中的配置
* @return
* @author Seagull
* @date 2019年5月6日
*/
public static boolean checkHostNet() {
log.info("检查客户端配置中,请稍后......");
Properties properties = SysConfig.getConfiguration();
String version="Version "+properties.getProperty("client.verison");
String webip=properties.getProperty("server.web.ip");
Integer webport=Integer.valueOf(properties.getProperty("server.web.port"));
try {
String result = HttpRequest.loadJSON("/openGetApi/clientGetServerVersion.do");
if(version.equals(result)){
log.info("客户端访问Web端配置: {}:{} 检测通过......",webip,webport);
}else{
if(result.startsWith("Version")){
log.warn("客户端版本:{} 服务端版本:{} 客户端与服务端版本不一致,有可能会导致未知问题,请检查...",version,result);
}else{
log.error("请检查客户端配置,获取服务端版本信息出现异常!");
}
}
} catch (Exception e) {
log.error("客户端配置检测异常,请确认您项目根目录下的客户端配置文件(sys_config.properties)是否已经正确配置。",e);
return false;
}
return true;
}
}
package springboot;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
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.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;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import luckyclient.remote.entity.monitor.Server;
import luckyclient.utils.config.SysConfig;
import luckyclient.utils.httputils.HttpRequest;
import springboot.model.RunBatchCaseEntity;
import springboot.model.RunTaskEntity;
import springboot.model.WebDebugCaseEntity;
/**
* =================================================================
* 这是一个受限制的自由软件您不能在任何未经允许的前提下对程序代码进行修改和用于商业用途也不允许对程序代码修改后以任何形式任何目的的再发布
* 为了尊重作者的劳动成果LuckyFrame关键版权信息严禁篡改
* 有任何疑问欢迎联系作者讨论 QQ:1573584944 seagull1985
* =================================================================
* @author seagull
* @date 2018年7月27日 上午10:28:32
*/
@RestController
public class HttpImpl {
private static final Logger log = LoggerFactory.getLogger(HttpImpl.class);
private static final String OS=System.getProperty("os.name").toLowerCase();
/**
* 运行自动化任务
* @param req
* @return
* @throws RemoteException
*/
@PostMapping("/runTask")
private String runTask(HttpServletRequest req) throws RemoteException {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
sb.append(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
log.info("开始转换RunTaskEntity执行任务实体...");
RunTaskEntity runTaskEntity = JSONObject.parseObject(sb.toString(), RunTaskEntity.class);
log.info("TaskId:{},SchedulingName:{},LoadPath:{}",runTaskEntity.getTaskId(),runTaskEntity.getSchedulingName(),runTaskEntity.getLoadPath());
try{
log.info("开始获取客户端驱动路径...");
File file =new File(System.getProperty("user.dir")+runTaskEntity.getLoadPath());
log.info("客户端驱动路径:{}",file.getAbsolutePath());
if (!file .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",file.getPath());
return "客户端测试驱动桩路径不存在,请检查【"+file.getPath()+"";
}
log.info("初始化Runtime...");
Runtime run = Runtime.getRuntime();
StringBuffer sbf=new StringBuffer();
sbf.append(runTaskEntity.getTaskId()).append(" ");
sbf.append(runTaskEntity.getLoadPath());
log.info("启动任务模式测试程序...调度名称:【{}】 任务ID:【{}】",runTaskEntity.getSchedulingName(),runTaskEntity.getTaskId());
if(OS.startsWith("win")){
log.info("开始调起windows命令行窗口...");
run.exec("cmd.exe /k start " + "task.cmd" +" "+ sbf.toString(), null,new File(System.getProperty("user.dir")+File.separator));
log.info("调起windows命令行窗口完成...");
}else{
log.info("开始调起Linux命令脚本...");
Process ps = Runtime.getRuntime().exec(System.getProperty("user.dir")+File.separator+"task.sh"+ " " +sbf.toString());
ps.waitFor();
log.info("调起Linux命令脚本完成...");
}
} catch (Exception e) {
log.error("启动任务模式测试程序异常!!!",e);
return "启动任务模式测试程序异常!!!";
}
return "启动任务模式测试程序正常";
}
/**
* 批量运行用例
* @param req
* @return
* @throws RemoteException
*/
@PostMapping("/runBatchCase")
private String runBatchCase(HttpServletRequest req) throws RemoteException {
StringBuilder sbd = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
sbd.append(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
log.info("开始转换RunBatchCaseEntity批量执行用例实体...");
RunBatchCaseEntity runBatchCaseEntity = JSONObject.parseObject(sbd.toString(), RunBatchCaseEntity.class);
String projectName = runBatchCaseEntity.getProjectname();
String taskId = runBatchCaseEntity.getTaskid();
String loadPath = runBatchCaseEntity.getLoadpath();
String batchCase = runBatchCaseEntity.getBatchcase();
log.info("批量测试用例:{}",batchCase);
try{
log.info("开始获取客户端驱动路径...");
File file =new File(System.getProperty("user.dir")+loadPath);
log.info("客户端驱动路径:{}",file.getAbsolutePath());
if (!file .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",file.getPath());
return "客户端测试驱动桩路径不存在,请检查【"+file.getPath()+"";
}
log.info("初始化Runtime...");
Runtime run = Runtime.getRuntime();
StringBuffer sb=new StringBuffer();
sb.append(taskId).append(" ");
sb.append(batchCase).append(" ");
sb.append(loadPath);
log.info("启动批量用例模式测试程序...测试项目:{} 任务ID:{}",projectName,taskId);
if(OS.startsWith("win")){
log.info("开始调起windows命令行窗口...");
run.exec("cmd.exe /k start " + "task_batch.cmd" + " " +sb.toString(), null,new File(System.getProperty("user.dir")+File.separator));
log.info("调起windows命令行窗口完成...");
}else{
log.info("开始调起Linux命令脚本...");
Process ps = Runtime.getRuntime().exec(System.getProperty("user.dir")+File.separator+"task_batch.sh"+ " " +sb.toString());
ps.waitFor();
log.info("调起Linux命令脚本完成...");
}
} catch (Exception e) {
e.printStackTrace();
log.error("启动批量用例模式测试程序异常!!!",e);
return "启动批量用例模式测试程序异常!!!";
}
return "启动批量用例模式测试程序正常";
}
/**
* web界面调度接口
* @param req
* @return
* @throws RemoteException
*/
@PostMapping("/webDebugCase")
private String webDebugCase(HttpServletRequest req) throws RemoteException {
StringBuilder sbd = new StringBuilder();
try (BufferedReader reader = req.getReader();) {
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
sbd.append(buff, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
WebDebugCaseEntity webDebugCaseEntity = JSONObject.parseObject(sbd.toString(), WebDebugCaseEntity.class);
log.info("Web端调试用例ID:{} 发起人ID:{}",webDebugCaseEntity.getCaseId(),webDebugCaseEntity.getUserId());
try{
File file =new File(System.getProperty("user.dir")+webDebugCaseEntity.getLoadpath());
if (!file .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",file.getPath());
return "客户端测试驱动桩路径不存在,请检查【"+file.getPath()+"";
}
Runtime run = Runtime.getRuntime();
StringBuffer sb=new StringBuffer();
sb.append(webDebugCaseEntity.getCaseId()).append(" ");
sb.append(webDebugCaseEntity.getUserId()).append(" ");
sb.append(webDebugCaseEntity.getLoadpath());
if(OS.startsWith("win")){
run.exec("cmd.exe /k start " + "web_debugcase.cmd" + " " +sb.toString(), null,new File(System.getProperty("user.dir")+File.separator));
}else{
Process ps = Runtime.getRuntime().exec(System.getProperty("user.dir")+File.separator+"web_debugcase.sh"+ " " +sb.toString());
ps.waitFor();
}
} catch (Exception e) {
e.printStackTrace();
log.error("启动Web调试模式测试程序异常",e);
return "启动Web调试模式测试程序异常";
}
return "启动Web调试模式测试程序正常";
}
/**
* 获取客户端本地日志
* @param req
* @return
* @throws RemoteException
*/
@GetMapping("/getLogdDetail")
private String getLogdDetail(HttpServletRequest req) throws RemoteException{
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;
try {
isr = new InputStreamReader(new FileInputStream(downLoadPath), "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("读取日志路径错误,请检查客户端日志路径是否存在!downLoadPath: "+downLoadPath,e);
return "读取日志路径错误,请检查客户端日志路径是否存在!downLoadPath: "+downLoadPath;
}
BufferedReader bos = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
try {
while ((str = bos.readLine()) != null)
{
sb.append(str).append("##n##");
}
bos.close();
log.info("服务端读取本地日志成功!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("客户端转BufferedReader失败请检查原因",e);
return "客户端转BufferedReader失败请检查原因";
}
return sb.toString();
}
/**
* 获取错误截图
* @param req
* @return
* @throws RemoteException
*/
@GetMapping("/getLogImg")
private byte[] getLogImg(HttpServletRequest req,HttpServletResponse res) throws RemoteException{
String imgName=req.getParameter("imgName");
String ctxPath = System.getProperty("user.dir")+File.separator+"log"+File.separator+"ScreenShot";
String downLoadPath = ctxPath+File.separator+imgName;
byte[] b = null;
try {
File file = new File(downLoadPath);
b = new byte[(int) file.length()];
BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
is.read(b);
is.close();
log.info("服务端获取本地图片:{}",downLoadPath);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
log.error("此文件不存在,请检查:{}",downLoadPath,e);
return b;
} catch (IOException e) {
// TODO Auto-generated catch block
return b;
}
return b;
}
/**
* 上传驱动文件到客户端
*/
@PostMapping("/uploadJar")
private String uploadJar(HttpServletRequest req,HttpServletResponse res, HttpSession session,@RequestParam("jarfile") MultipartFile jarfile) throws IOException, ServletException{
if (!jarfile.isEmpty()){
if (!jarfile.getOriginalFilename().endsWith(".jar")&&!jarfile.getOriginalFilename().endsWith(".py")) {
log.warn("文件格式后缀不是.jar或.py上传失败");
return "文件格式后缀不是.jar或.py上传失败";
}
}else{
log.warn("上传文件为空,请检查!");
return "上传文件为空,请检查!";
}
String name = jarfile.getOriginalFilename();
String loadpath = req.getParameter("loadpath");
String path = System.getProperty("user.dir")+loadpath;
if (!new File(path) .isDirectory())
{
log.warn("客户端测试驱动桩路径不存在,请检查【{}】",path);
return "客户端测试驱动桩路径不存在,请检查【"+path+"";
}
String pathName = path +File.separator+ name;
File file = new File(pathName);
try {
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()+"】成功!";
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
log.error("客户端未找到正确路径或文件,上传失败!文件路径名称:{}",pathName,e);
return "客户端未找到正确路径或文件,上传失败!文件路径名称:"+pathName;
} catch (IOException e) {
// TODO Auto-generated catch block
log.error("客户端IOExceptiona或是未找到驱动路径文件路径名称:{}",pathName,e);
return "客户端IOExceptiona或是未找到驱动路径文件路径名称"+pathName;
}
}
/**
* 检查客户端心跳
* @param req
* @return
* @throws RemoteException
*/
@GetMapping("/getClientStatus")
private String getClientStatus(HttpServletRequest req) throws RemoteException{
Properties properties = SysConfig.getConfiguration();
String verison=properties.getProperty("client.verison");
return "{\"status\":\"success\",\"version\":\""+verison+"\"}";
}
/**
* 获取客户端资源监控情况
* @param req
* @return
* @author Seagull
* @throws Exception
* @date 2019年5月5日
*/
@GetMapping("/getClientMonitorData")
private String getClientMonitorData(HttpServletRequest req) throws Exception{
Server server = new Server();
server.copyTo();
return JSON.toJSONString(server);
}
/**
* 检查客户端中的配置
* @return
* @author Seagull
* @date 2019年5月6日
*/
public static boolean checkHostNet() {
log.info("检查客户端配置中,请稍后......");
Properties properties = SysConfig.getConfiguration();
String version="Version "+properties.getProperty("client.verison");
String webip=properties.getProperty("server.web.ip");
Integer webport=Integer.valueOf(properties.getProperty("server.web.port"));
try {
String result = HttpRequest.loadJSON("/openGetApi/clientGetServerVersion.do");
if(version.equals(result)){
log.info("客户端访问Web端配置: {}:{} 检测通过......",webip,webport);
}else{
if(result.startsWith("Version")){
log.warn("客户端版本:{} 服务端版本:{} 客户端与服务端版本不一致,有可能会导致未知问题,请检查...",version,result);
}else{
log.error("请检查客户端配置,获取服务端版本信息出现异常!");
}
}
} catch (Exception e) {
log.error("客户端配置检测异常,请确认您项目根目录下的客户端配置文件(sys_config.properties)是否已经正确配置。",e);
return false;
}
return true;
}
}