首页 > 代码库 > Android WebApp & NativeApp 适配测试自动化平台GoGo实现 东海陈光剑
Android WebApp & NativeApp 适配测试自动化平台GoGo实现 东海陈光剑
Android WebApp & NativeApp 适配测试自动化平台GoGo实现
东海陈光剑
2014年3月6日 18:27:55
源代码:
https://github.com/universsky/AndroidAutomationTestUniverssky.git
GoGo平台架构:
运行结果:
http://10.73.72.122:88/report.html?run_stamp=20140306052855&sec=336&min=5
http://10.125.1.58:88/report.html?run_stamp=20140428073427?min=3?sec=214
性能分析CPU%:( 用highcharts做成图形化的报告形式 )
运行日志:
生成报告代码:
资源上传服务器:
/**
* Upload.java etao.test.fileload UploadFileToServer 下午1:38:59 2014年4月20日 2014
*/
package etao.test.fileload;
/**
* @author 东海陈光剑
* 2014年4月20日 下午1:38:59
*/
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@SuppressWarnings("serial")
public class Upload extends HttpServlet {
private String uploadPath = "C:\\autoTest\\httpd\\htdocs\\img"; // 上传文件的目录
private String tempPath = "c:\\buffer\\"; // 临时文件目录
File tempPathFile;
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Set factory constraints
factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb
factory.setRepository(tempPathFile);// 设置缓冲区目录
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint
upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB
List<FileItem> items = upload.parseRequest(request);// 得到所有的文件
Iterator<FileItem> i = items.iterator();
while (i.hasNext()) {
FileItem fi = (FileItem) i.next();
String fileName = fi.getName();
if (fileName != null) {
File fullFile = new File(fi.getName());
File savedFile = new File(uploadPath, fullFile.getName());
fi.write(savedFile);
}
System.out.println(fileName + " upload successfully!");
}
// System.out.println("upload succeed");
} catch (Exception e) {
// 可以跳转出错页面
e.printStackTrace();
}
}
public void init() throws ServletException {
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()) {
uploadFile.mkdirs();
}
File tempPathFile = new File(tempPath);
if (!tempPathFile.exists()) {
tempPathFile.mkdirs();
}
}
}
public static void genReport(String run_stamp, String runningSec,
String runningMin) {
/**
* 调用系统默认浏览器打开链接
* http://10.73.72.122:88/report.html?run_stamp=20140302023811
* &sec=250&min=4
*/
if (java.awt.Desktop.isDesktopSupported()) {
try {
String reportUriStr = "http://10.73.72.122:88/report.html?run_stamp="
+ run_stamp
+ "&sec="
+ runningSec
+ "&min="
+ runningMin;
// 创建一个URI实例
java.net.URI reportUri = java.net.URI.create(reportUriStr);
// String uri1Str =
// "http://10.73.72.122:8080/Report/go?run_stamp="
// + run_stamp;
//
// java.net.URI uri1 = java.net.URI.create(uri1Str);
// 获取当前系统桌面扩展
java.awt.Desktop dp = java.awt.Desktop.getDesktop();
// 判断系统桌面是否支持要执行的功能
if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
// 获取系统默认浏览器打开链接
dp.browse(reportUri);
// dp.browse(uri1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}report.html放到Apache httpd Server下面:D:\Apache2.2\htdocs
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>适配测试报告</title>
<script src="http://g.tbcdn.cn/kissy/k/1.4.0/seed-min.js"></script>
<style type="text/css">
body {
background-color: #EEFFFF;
}
p.serif{font-family:"Times New Roman",Georgia,Serif}
p.sansserif{font-family:Arial,Verdana,Sans-serif}
</style>
</head>
<body class="serif">
<br><br><br><br>
<h1 align="center"style=font-family:微软雅黑>一淘android客户端适配测试报告</h1>
<p align="right">
<label for="issue_issue_author_id">联系人:陈光剑</label>
<a href="http://www.taobao.com/webww/ww.php?ver=3&touid=universsky1&siteid=cntaobao&status=2&charset=utf-8" class="inline-item" target="_blank" title="universsky1"><img alt="universsky1" border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid=universsky1&site=cntaobao&s=2&charset=utf-8" /></a><a href="http://amos.alicdn.com/msg.aw?v=2&uid=universsky1&site=cnalichn&s=11&charset=UTF-8" class="inline-item" target="_blank" title="universsky1"></a>
</p>
<div id=time align="right" style=font-family:Verdana></div>
<script>setInterval("time.innerHTML=‘今天是‘+new Date().toLocaleString()+‘ 星期‘+‘日一二三四五六‘.charAt(new Date().getDay())+‘ ‘;",1000);</script>
<script>
KISSY.ready(function(S){
var path="http://10.125.1.58:88/img/";
var href = location.href;
/**
* 调用系统默认浏览器打开链接 Apache httpd
* http://127.0.0.1:88/report.html?run_stamp=20140302023811
* &sec=250&min=4
*/
var m, run_stamp;
m = href.match(/stamp=(\d+)/);
if(!m) run_stamp = "20140421122151";
else run_stamp = m[1] ;
var sec ;
sec = href.match(/sec=(\d+)/);
if(!sec) se = 0;
else se=sec[1];
var min;
min = href.match(/min=(\d+)/);
if(!min) mi=0;
else mi = min[1];
/* 请求报告资源接口,tomcat在8888端口监听 */
S.use("node,io", function(S, Node, IO){
IO({
url: "http://10.125.1.58:8888/Report/go?run_stamp=" + run_stamp,
dataType: "jsonp",
jsonpCallback: "report",
success: function(data) {
var report=data;
var runtime_log = path + run_stamp + "$runtime.log";
var cpu_log = path + run_stamp + "$cpu_usage.log";
var bodyContent="<p><font face=\"verdana\">开始时间:" + run_stamp +"</font></p>";
bodyContent = bodyContent + "<p><font face=\"verdana\">运行时间: " + se + "s ( " + mi + " min ) </font></p>";
bodyContent = bodyContent + "<p align=center ><font face=\"verdana\"><a href=http://www.mamicode.com/""+runtime_log+"\">测试运行记录(点击查看)</a></font></p>";
bodyContent = bodyContent + "<p align=center ><font face=\"verdana\"><a href=http://www.mamicode.com/""+cpu_log +"\">CPU使用情况(点击查看)</a></font></p>";
bodyContent = bodyContent + "<hr noshade size=5 align=center width=100% />";
bodyContent = bodyContent + "<table style=\"table-layout:fixed\" border=\"0\">";
/*表格总开始*/
// 遍历DeviceID
for (var i = 0; i < report.result.length; i++) {
bodyContent=bodyContent+"<tr><td width=\"80\" scope=\"col\"><font face=\"verdana\" >DeviceId(日志)</font></td>";
for (var j = 0; j < report.result[i].img_timestamp.length; j++) {
bodyContent = bodyContent+"<td style=\"word-break : break-all\"; \"overflow:hidden\"; width=\"100\" scope=\"col\"><font face=\"verdana\" >"+report.result[i].url[j]+"</font></td>";
}
bodyContent = bodyContent+"</tr>";
/*以上是urls行*/
/*这里是log记录*/
var log_url = path + run_stamp + "$" + report.result[i].device_id + "$runtime.log";
bodyContent = bodyContent+ "<tr><td scope=\"row\"><font face=\"verdana\" >"+report.result[i].device_id + "</font></td>";
//bodyContent = bodyContent+ "<tr><td scope=\"row\"><font face=\"verdana\" ><a href=http://www.mamicode.com/""+log_url+"\">"+report.result[i].device_id + "</a></font></td>";
/*下面是imgsrc行*/
for (var j = 0; j < report.result[i].img_timestamp.length; j++) {
var imgsrc_url = path + report.run_stamp+"$"+
report.result[i].device_id+"$"+
report.result[i].img_timestamp[j]+"$"+
report.result[i].img_name[j];
bodyContent = bodyContent+
"<td><a href=http://www.mamicode.com/""+ imgsrc_url +"\"><img src=http://www.mamicode.com/"" +imgsrc_url+
"\" width=\"200\" height=\"300\"></td>";
}
bodyContent = bodyContent+"</tr>";
};
/********************************************************************************************************************/
/*总表格结束*/
bodyContent=bodyContent+"</table>";
/*输出总的报告*/
// document.write("<html><head><title>适配测试报告 " + report.run_stamp + "</title></head><body>" + bodyContent);
// document.write("</body></html>");
S.one("body").append(bodyContent);
}
})
});
});
</script>
</body>
</html>
报告url,img资源获取http接口:
- Request URL:http://10.73.72.122:8080/Report/go?_ksTS=1394101086006_19&callback=report&run_stamp=20140306052855
- Request Method:GET
- Status Code: 200 OK
-
接口实现代码:
/** * Report.java ct.report Report 下午7:38:18 2014年2月28日 2014 */package ct.report;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.google.gson.Gson;import ct.dao.ReportDao;/** * @author 东海陈光剑 2014年2月28日 下午7:38:18 */public class Report extends HttpServlet { /** * serialVersionUID long */ private static final long serialVersionUID = -7282812094112943289L; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { run_stamp = req.getParameter("run_stamp"); callback = req.getParameter("callback"); ReportDao dao = new ReportDao(); Gson gson = new Gson(); String json = gson.toJson(dao); // 在console上打印记录 System.out.println(callback + "(" + json + ")"); PrintWriter out = resp.getWriter(); out.print(callback + "(" + json + ")"); out.flush(); } public String getRun_stamp() { return run_stamp; } public void setRun_stamp(String run_stamp) { Report.run_stamp = run_stamp; } static String run_stamp; static String callback;}
/** * ReportDao.java ct.dao Report 下午9:32:16 2014年2月28日 2014 */package ct.dao;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import ct.report.Report;/** * @author 东海陈光剑 2014年2月28日 下午9:32:16 */public class ReportDao { // Report report = new Report(); private String run_stamp = (new Report()).getRun_stamp(); // private ArrayList<String> deviceList = (new Report()).getDeviceList(); // private String device_id = (new Report()).getDevice_id(); // QueryResult qr = new QueryResult(); // Map<String, ArrayList<String>> result = (new QueryResult()).query( // run_stamp, device_id); List<HashMap<String, ArrayList<String>>> result = (new QueryResult()) .query(run_stamp);}
/** * QueryResult.java ct.dao Report 下午10:14:57 2014年2月28日 2014 */package ct.dao;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @author 东海陈光剑 2014年2月28日 下午10:14:57 */public class QueryResult { /** * @param args * void main */ public static void main(String[] args) { String run_stamp = "20140228041020"; QueryResult qr = new QueryResult(); // Map<String, ArrayList<String>> result = qr.query(run_stamp, // device_id); List<HashMap<String, ArrayList<String>>> result = qr.query(run_stamp); System.out.println(result); } List<HashMap<String, ArrayList<String>>> query(String run_stamp) { ArrayList<String> deviceList = getDeviceList(run_stamp); List<HashMap<String, ArrayList<String>>> result = new ArrayList<HashMap<String, ArrayList<String>>>(); // Map<String, ArrayList<String>> imgName = new HashMap<String, // ArrayList<String>>(); // Map<String, ArrayList<String>> imgTimeStamp = new HashMap<String, // ArrayList<String>>(); try { Class.forName("com.mysql.jdbc.Driver"); // 加载MYSQL JDBC驱动程序 System.out.println("Success loading mysql driver!"); } catch (Exception e) { System.out.print("Error loading mysql driver!"); e.printStackTrace(); } try { Connection connect = DriverManager.getConnection( "jdbc:mysql://10.73.72.122:3306/test", "root", "isword"); // 连接URL为 jdbc:mysql//服务器地址/数据库名 ,后面的2个参数分别是登陆用户名和密码 System.out.println("Success connect mysql server!"); Statement stmt = connect.createStatement(); for (String device_id : deviceList) { String queryCmd = "SELECT * FROM ct_pic where run_stamp=‘" + run_stamp + "‘ and device_id=‘" + device_id + "‘ ORDER BY img_timestamp"; System.out.println(queryCmd); ResultSet rs = stmt.executeQuery(queryCmd); ArrayList<String> urlList = new ArrayList<String>(); ArrayList<String> imgNameList = new ArrayList<String>(); ArrayList<String> imgTimeStampList = new ArrayList<String>(); HashMap<String, ArrayList<String>> deviceMap = new HashMap<String, ArrayList<String>>(); while (rs.next()) { System.out.println(rs.getString("url")); urlList.add(rs.getString("url")); System.out.println(rs.getString("img_name")); imgNameList.add(rs.getString("img_name")); System.out.println(rs.getString("img_timestamp")); imgTimeStampList.add(rs.getString("img_timestamp")); } ArrayList<String> d = new ArrayList<String>(1); d.add(device_id); deviceMap.put("device_id", d); deviceMap.put("url", urlList); deviceMap.put("img_name", imgNameList); deviceMap.put("img_timestamp", imgTimeStampList); result.add(deviceMap); }// end for } catch (Exception e) { e.printStackTrace(); } // Map<String, ArrayList<String>> result = new HashMap<String, // ArrayList<String>>(); // result.put("device_list", deviceList); // result.put("url", urlList); // result.put("img_name", imgNameList); // result.put("img_timestamp", imgTimeStampList); return result; } Map<String, ArrayList<String>> query(String run_stamp, String device_id) { ArrayList<String> deviceList = getDeviceList(run_stamp); ArrayList<String> urlList = new ArrayList<String>(); ArrayList<String> imgNameList = new ArrayList<String>(); ArrayList<String> imgTimeStampList = new ArrayList<String>(); try { Class.forName("com.mysql.jdbc.Driver"); // 加载MYSQL JDBC驱动程序 System.out.println("Success loading mysql driver!"); } catch (Exception e) { System.out.print("Error loading mysql driver!"); e.printStackTrace(); } try { Connection connect = DriverManager.getConnection( "jdbc:mysql://10.73.72.122:3306/test", "root", "isword"); // 连接URL为 jdbc:mysql//服务器地址/数据库名 ,后面的2个参数分别是登陆用户名和密码 System.out.println("Success connect mysql server!"); Statement stmt = connect.createStatement(); String queryCmd = "SELECT * FROM ct_pic where run_stamp=‘" + run_stamp + "‘ and device_id=‘" + device_id + "‘ ORDER BY img_timestamp"; System.out.println(queryCmd); ResultSet rs = stmt.executeQuery(queryCmd); while (rs.next()) { System.out.println(rs.getString("img_name")); imgNameList.add(rs.getString("img_name")); System.out.println(rs.getString("url")); urlList.add(rs.getString("url")); System.out.println(rs.getString("img_timestamp")); imgTimeStampList.add(rs.getString("img_timestamp")); } } catch (Exception e) { e.printStackTrace(); } Map<String, ArrayList<String>> result = new HashMap<String, ArrayList<String>>(); result.put("device_list", deviceList); result.put("url", urlList); result.put("img_name", imgNameList); result.put("img_timestamp", imgTimeStampList); return result; } public ArrayList<String> getDeviceList(String run_stamp) { ArrayList<String> deviceList = new ArrayList<String>(); try { Connection connect = DriverManager.getConnection( "jdbc:mysql://10.73.72.122:3306/test", "root", "isword"); // 连接URL为 jdbc:mysql//服务器地址/数据库名 ,后面的2个参数分别是登陆用户名和密码 System.out.println("Success connect mysql server!"); Statement stmt = connect.createStatement(); String queryCmd = "SELECT device_id FROM ct_pic" + " where run_stamp=‘" + run_stamp + "‘ GROUP BY device_id;"; System.out.println(queryCmd); ResultSet rs = stmt.executeQuery(queryCmd); while (rs.next()) { System.out.println(rs.getString("device_id")); deviceList.add(rs.getString("device_id")); } } catch (Exception e) { e.printStackTrace(); } return deviceList; }}
测试xUnit代码:
package ct4taobaoh5.test;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.android.AndroidDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.events.WebDriverEventListener;
import ct4h5.Init;
import ct4h5.config.Const;
import ct4h5.util.EventListener;
import ct4h5.util.Util;
/**
*
* @author 东海陈光剑 2014年2月21日 下午11:13:59
*/
@SuppressWarnings("deprecation")
@RunWith(Parameterized.class)
public class SearchTest extends TestCase {
String deviceId;
AndroidDriver driver;
public SearchTest(String deviceId) {
this.deviceId = deviceId;
}
@Before
public void init() {
/**
* forward tcp
*/
// Init.forward(deviceId);
Init.init(deviceId);
}
/**
* <p>
* The custom runner <code>Parameterized</code> implements parameterized
* tests. When running a parameterized test class, instances are created for
* the cross-product of the test methods and the test data elements.
* </p>
*
* For example, to test a Fibonacci function, write:
*
* <pre>
* @RunWith(Parameterized.class)
* public class FibonacciTest {
* @Parameters
* public static Collection<Object[]> data() {
* return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
* { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
* }
*
* private int fInput;
* private int fExpected;
*
* public FibonacciTest(int input, int expected) {
* fInput = input;
* fExpected = expected;
* }
*
* @Test
* public void test() {
* assertEquals(fExpected, Fibonacci.compute(fInput));
* }
* }
* </pre>
*
* <p>
* Each instance of <code>FibonacciTest</code> will be constructed using the
* two-argument constructor and the data values in the
* <code>@Parameters</code> method.
* </p>
*/
@Parameterized.Parameters
public static Collection deviceIds() {
List<String> deviceList = Util.getDeviceList();
List<String[]> col = new ArrayList<String[]>(); // List
// [4d004077b4369049,
// Coolpad5890-a1a1314a]
// 把List<String> 转换成 List<String[]>
for (String e : deviceList) {
String[] el = new String[] { e };
col.add(el);
}
return col; // 字符串数组 [[Ljava.lang.String;@b4e29b,
// [Ljava.lang.String;@18941f7, null, null, null]
}
@Test
public void testSearch() throws Exception {
// String remote_driver_url = "http://localhost:5555/h5";
// WebDriverEventListener eventListener = new EventListener();
// WebDriver driver = new EventFiringWebDriver(new RemoteWebDriver(
// new URL(remote_driver_url), DesiredCapabilities.android()))
// .register(eventListener);
/**
* getDefaultUrl: return new URL("http://localhost:8080/wd/hub");
*/
// driver = new AndroidDriver(new URL("http://localhost:" + port
// + "/wd/hub"), DesiredCapabilities.android());
driver = new AndroidDriver();
/**
* 首次打开“首页”
*/
driver.get(Const.urlTaobaoOnline);// 线上
// driver.get(Const.urlPre);//预发
Thread.sleep(2000);
Util.record(driver, deviceId);
/**
* 点击 搜索框
*/
Util.click(driver, "//INPUT[@id=\"J_searchtext\"]");
Util.record(driver, deviceId);
/**
* 在搜索框"//FORM/INPUT[1]"输入query keys
*/
WebElement e = driver
.findElementByXPath("//INPUT[@id=\"J_searchtext\"]");
e.sendKeys("iphone5s");
Util.record(driver, deviceId);// 搜索下拉推荐
// e.submit();// 提交搜索
e.sendKeys(Keys.ENTER);
/**
* 2s等待SRP加载渲染出来
*/
Thread.sleep(2000);
Util.record(driver, deviceId);
/**
* 点击“分类”
*/
Util.click(driver, "//SPAN[@id=\"J_selt\"]");
Thread.sleep(1000);
Util.record(driver, deviceId);
/**
* 子类目可点击
*/
Thread.sleep(1000);
Util.click(driver, "//LI[1]/H2[1]");
Util.record(driver, deviceId);
// //////////////////////////////////////////////////////////////////////////////////
/**
* 打开“首页”
*/
driver.get(Const.urlTaobaoOnline);// 线上
// driver.get(Const.urlPre);//预发
Thread.sleep(2000);
Util.record(driver, deviceId);
/**
* 点击 搜索框
*/
Util.click(driver, "//INPUT[@id=\"J_searchtext\"]");
Util.record(driver, deviceId);
/**
* 在搜索框"//FORM/INPUT[1]"输入query keys
*/
driver.findElementByXPath("//INPUT[@id=\"J_searchtext\"]").sendKeys(
"iphone5s");
Util.record(driver, deviceId);// 搜索下拉推荐
// e.submit();// 提交搜索
e.sendKeys(Keys.ENTER);
/**
* 2s等待SRP加载渲染出来
*/
Thread.sleep(2000);
Util.record(driver, deviceId);
/**
* 点击 筛选 //SPAN[@id="J_sift"]
*/
Util.click(driver, "//SPAN[@id=\"J_sift\"]");
Util.record(driver, deviceId);
/**
* 点击 筛选项目
*/
Util.click(driver, "//LI[1]/LABEL[1]/INPUT[1]");
Util.record(driver, deviceId);
/**
* 设定 “最高价”“最低价”
*/
driver.findElementByXPath("//DIV[3]/DIV[1]/INPUT[1]").sendKeys("2000");
driver.findElementByXPath("//DIV[2]/INPUT[1]").sendKeys("4000");
/**
* 点击“确定”
*/
Util.click(driver, "//BUTTON[@id=\"J_siftSearchBtn\"]");
Util.record(driver, deviceId);
/**
* 点击 销量 //DIV[4]/DIV[1]/UL[1]/LI[2]
*
*/
Util.click(driver, "//DIV[4]/DIV[1]/UL[1]/LI[2]");
Util.record(driver, deviceId);
/**
* 点击 价格排序: //DIV[4]/DIV[1]/UL[1]/LI[3]
*/
Util.click(driver, "//DIV[4]/DIV[1]/UL[1]/LI[3]");
Util.record(driver, deviceId);
/**
* 切大图://DIV[@id="tbh5v0"]/DIV[1]/DIV[4]/DIV[1]/DIV[1]/DIV[1]
*/
Util.click(driver,
"//DIV[@id=\"tbh5v0\"]/DIV[1]/DIV[4]/DIV[1]/DIV[1]/DIV[1]");
Util.record(driver, deviceId);
Util.click(driver,
"//DIV[@id=\"tbh5v0\"]/DIV[1]/DIV[4]/DIV[1]/DIV[1]/DIV[1]");
Util.record(driver, deviceId);
Util.click(driver,
"//DIV[@id=\"tbh5v0\"]/DIV[1]/DIV[4]/DIV[1]/DIV[1]/DIV[1]");
Util.record(driver, deviceId);
}
@After
public void destroy() {
Init.destroy(deviceId);
// driver.quit();
}
}
package ct4taobaoh5.test;
import java.util.List;
import org.junit.runner.JUnitCore;
import org.junit.runner.notification.Failure;
import ct4h5.Install;
import ct4h5.Uninstall;
import ct4h5.config.Const;
import ct4h5.report.GenerateReport;
import ct4h5.util.Util;
/**
* @author 东海陈光剑 2014年2月17日 下午8:58:02
*/
public class TestRunner {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
run();
}
/**
* @throws Exception
*
*/
private static void run() throws Exception {
long start = System.currentTimeMillis();
runTestCases();
long end = System.currentTimeMillis();
report(start, end);
}
private static void report(long start, long end) {
System.out.println("Running Time: " + (end - start) / 1000 + " s"
+ "( " + (end - start) / 1000 / 60 + " min )");
System.out.println("Run timestamp:" + Const.timestamp);
String runningSec = (end - start) / 1000 + "";
String runningMin = (end - start) / 1000 / 60 + "";
// String startReportCmd = "start http://10.73.72.122:88/report.html";
// Util.excuCmd(startReportCmd);
GenerateReport.genReport(Const.timestamp, runningSec, runningMin);
}
/**
* @throws Exception
*
*/
private static void runTestCases() throws Exception {
List<String> classList = Util
.getClassInPackage(Const.packageTaobaoH5Path);
for (String c : classList) {
if (c.endsWith("Test")) {
runClass(c);
}
}
}
public static void runClass(String className) throws Exception {
String fullClassName = Const.packageTaobaoH5Path + "." + className;
Class<?> c = Class.forName(fullClassName);
long start = System.currentTimeMillis();
for (Failure failure : JUnitCore.runClasses(c).getFailures()) {
System.out.println(failure.toString());
}
System.out.println(JUnitCore.runClasses(c).wasSuccessful());
long end = System.currentTimeMillis();
System.out.println(fullClassName + " | Running Time: " + (end - start)
/ 1000 + " s" + "( " + (end - start) / 1000 / 60 + " min )");
}
/**
* 多线程执行安装android-server.apk
*/
private static void install() {
for (String e : Util.getDeviceList()) {
(new Thread(new Install(e))).start();
}
}
/**
* 多线程执行安装android-server.apk
*/
private static void uninstall() {
for (String e : Util.getDeviceList()) {
(new Thread(new Uninstall(e))).start();
}
}
}
基础应用类:
package ct4h5.util;import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.URL;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.Enumeration;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.apache.commons.io.FileUtils;import org.openqa.selenium.By;import org.openqa.selenium.OutputType;import org.openqa.selenium.TakesScreenshot;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebDriverException;import org.openqa.selenium.android.AndroidDriver;import org.openqa.selenium.remote.ScreenshotException;import sun.misc.BASE64Decoder;import com.taobao.sword.android.elements.IAndroidActivity;import ct4h5.config.Const;import ct4h5.dao.InsertDB;import ct4h5.report.GenerateReport;/** * @author 东海陈光剑 2014年2月22日 上午12:16:10 */public class Util { public static List<String> getDeviceList() { // TODO Auto-generated method stub Process process = null; String strBuff = ""; String t = ""; String command = "adb devices"; try { process = Runtime.getRuntime().exec(command); BufferedReader br = new BufferedReader(new InputStreamReader( process.getInputStream(), "utf-8")); while ((t = br.readLine()) != null) { strBuff += t + "\n"; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* * List of devices attached * \nCoolpad5890-a1a1314a\tdevice\nHC34WW907981\tdevice\n\n */ print(strBuff); List<String> deviceList = new ArrayList<String>(5); String regex = "[\\n](.*)[\\t]"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(strBuff); while (matcher.find()) { String deviceId = strBuff.substring(matcher.start(), matcher.end()); deviceId = deviceId.replaceAll("\\s*", ""); deviceList.add(deviceId); } return deviceList; } public static void print(String buff) { // TODO Auto-generated method stub System.out.println(buff); } /*********** * 根据包名来获取此包下所有的类名及其实例 * * @param packagePath * @return */ public static List<String> getClassInPackage(String packagePath) { List<String> classList = new ArrayList(5); String packageName = packagePath; String packageDirName = packageName.replace(".", "/"); Enumeration<URL> dirs = null; try { dirs = Thread.currentThread().getContextClassLoader() .getResources(packageDirName); // 迭代此 Enumeration while (dirs.hasMoreElements()) { URL url = dirs.nextElement(); File file = new File(url.getFile()); // 把此目录下的所有文件列出 String[] classes = file.list(); // 循环此数组,并把.class去掉 ".class".length() = 6 for (String className : classes) { className = className.substring(0, className.length() - 6); classList.add(className); } } } catch (Exception e) { e.printStackTrace(); } return classList; } public static void record(AndroidDriver driver, String deviceId) throws InterruptedException { /** * 考虑到页面加载的时间,线程延时2s */ Thread.sleep(2000); printTitle(driver, deviceId); // GenerateImage(driver, deviceId); screenShot(driver, deviceId); } /** * @param driver * @param deviceId */ public static void printTitle(AndroidDriver driver, String deviceId) { System.out.println(deviceId + " | " + driver.getTitle()); System.out.println(driver.getCurrentUrl()); } public static void printTitle(AndroidDriver driver) { System.out.println(driver.getTitle()); System.out.println(driver.getCurrentUrl()); } /** * @param driver * @param xPath * @throws InterruptedException */ public static void click(AndroidDriver driver, String xPath) throws InterruptedException { // int i = 0; // /** // * 最多等待5s // */ // while (!driver.findElement(By.xpath(xPath)).isDisplayed() && i < 10) // { // Thread.sleep(500); // i++; // } // driver.getTouch().down(x, y); driver.findElement(By.xpath(xPath)).click(); // driver.wait();// 报错:java.lang.IllegalMonitorStateException Thread.sleep(1000); } /** * 截图 * * @param driver * @param imgName */ public void takeScreenShot(WebDriver driver, String imgName) { File scrFile = ((TakesScreenshot) driver) .getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(scrFile, new File("c:\\Learning\\" + imgName)); } catch (IOException e) { e.printStackTrace(); } } /** * 发生异常截图 * * @param e * @return */ public String extractScreenShot(WebDriverException e) { Throwable cause = e.getCause(); if (cause instanceof ScreenshotException) { return ((ScreenshotException) cause).getBase64EncodedScreenshot(); } return null; } /** * 将Base64转换成图片 * * @param activity * @param url * @return */ /** * >adb -s <deviceID> shell /system/bin/screencap -p /sdcard/screenshot.png * >adb -s <deviceID> pull /sdcard/screenshot.png d:/screenshot.png 2990 * KB/s (382785 bytes in 0.125s) * * @param driver * @param deviceId * @return */ public static boolean GenerateImage(AndroidDriver driver, String deviceId) {// 对字节数组字符串进行Base64解码并生成图片 String url = driver.getCurrentUrl(); System.out.println("AndroidDriver 截图 | " + url); String imgStr = driver.getScreenshotAs(OutputType.BASE64); /** * 这里记得加上"/"目录标示符 */ File fp = new File(Const.photoSavePath); if (!fp.isDirectory()) fp.mkdirs(); String imgPath = Const.photoSavePath + "/" + deviceId; File f = new File(imgPath); if (!f.isDirectory()) f.mkdirs(); if (!imgPath.endsWith("/")) imgPath += "/"; String timeChamp = (new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss")) .format(new Date()); /** * url(去除非法字符)+时间戳 命名图片 */ String imgName = url.replaceAll("[\\/:*?\"<>|!#]", "") + "_" + timeChamp + "_driver.jpeg"; if (imgStr == null) // 图像数据为空 return false; BASE64Decoder decoder = new BASE64Decoder(); try { // Base64解码 byte[] bytes = decoder.decodeBuffer(imgStr); for (int i = 0; i < bytes.length; ++i) { if (bytes[i] < 0) {// 调整异常数据 bytes[i] += 256; } } // 生成jpeg图片 f = new File(imgPath); if (!f.isDirectory()) f.mkdirs(); if (!imgPath.endsWith("/")) imgPath += "/"; String imgFullPathName = imgPath + imgName; OutputStream out = new FileOutputStream(imgFullPathName); out.write(bytes); out.flush(); out.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } // @SuppressWarnings("deprecation") // public static boolean GenerateImage(AndroidDriver driver) {// // 对字节数组字符串进行Base64解码并生成图片 // // String url = driver.getCurrentUrl(); // System.out.println("截图 | " + url); // String imgStr = driver.getScreenshotAs(OutputType.BASE64); // String imgPath = Const.photoSavePath + "/"; // String timeChamp = (new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss")) // .format(new Date()); // /** // * url(去除非法字符)+时间戳 命名图片 // */ // String imgName = url.replaceAll("[\\/:*?\"<>|]", "") + "-" + timeChamp // + ".jpeg"; // if (imgStr == null) // // 图像数据为空 // return false; // BASE64Decoder decoder = new BASE64Decoder(); // try { // // Base64解码 // byte[] bytes = decoder.decodeBuffer(imgStr); // for (int i = 0; i < bytes.length; ++i) { // if (bytes[i] < 0) {// 调整异常数据 // bytes[i] += 256; // } // } // // 生成jpeg图片 // File f = new File(imgPath); // if (!f.isDirectory()) // f.mkdir(); // if (!imgPath.endsWith("/")) // imgPath += "/"; // String imgFullPathName = imgPath + imgName; // OutputStream out = new FileOutputStream(imgFullPathName); // out.write(bytes); // out.flush(); // out.close(); // return true; // } catch (Exception e) { // return false; // } // } @SuppressWarnings({ "restriction", "unused" }) public static boolean screenShot(AndroidDriver driver, String deviceId) {// 对字节数组字符串进行Base64解码并生成图片 /** * 这里记得加上"/"目录标示符 */ File fp = new File(Const.photoSavePath); if (!fp.isDirectory()) fp.mkdirs(); String url = driver.getCurrentUrl(); System.out.println("adb screenShot 截图 | " + url); // String imgStr = driver.getScreenshotAs(OutputType.BASE64); String imgPath = Const.photoSavePath + "/" + deviceId; File f = new File(imgPath); if (!f.isDirectory()) f.mkdirs(); if (!imgPath.endsWith("/")) imgPath += "/"; String timeChamp = (new SimpleDateFormat("yyyyMMddhhmmss")) .format(new Date()); /** * url(去除非法字符)+时间戳 命名图片 */ String imgName = url.replaceAll("[\\/:*?\"<>|!#]", "") + "_" + timeChamp + ".jpeg"; String imgFullPathName = imgPath + imgName; String imgSrcPath = Const.photoSrcPath + deviceId + "/" + imgName; InsertDB.insert(Const.timestamp, url, imgName, deviceId, timeChamp); // // /** // * 生成报告 // */ // StringBuffer reportUrl = GenerateReport.genReportUrl(driver, // deviceId, // imgSrcPath); // Const.report.append(reportUrl + "</tr>" + "<tr><th scope=\"row\">" // + deviceId + "</th>"); // StringBuffer reportImgSrc = GenerateReport.genReportImgSrc(driver, // deviceId, imgSrcPath); // Const.report.append(reportImgSrc + "</tr>" + "</table>"); /** * >adb -s <deviceID> shell /system/bin/screencap -p * /sdcard/screenshot.png >adb -s <deviceID> pull /sdcard/screenshot.png * d:/screenshot.png */ String screencapCmd = "adb -s " + deviceId + " shell /system/bin/screencap -p /sdcard/screenshot.png"; String pullScreenShotCmd = "adb -s " + deviceId + " pull /sdcard/screenshot.png " + imgFullPathName; String rmScreenShotCmd = "rm -f /sdcard/screenshot.png"; excuCmd(screencapCmd); excuCmd(pullScreenShotCmd); excuCmd(rmScreenShotCmd); return true; // Process process = null; // try { // process = Runtime.getRuntime().exec(screencapCmd); // BufferedReader br = new BufferedReader(new InputStreamReader( // process.getInputStream(), "utf-8")); // String buff = ""; // String imgStr = ""; // while ((buff = br.readLine()) != null) { // Util.print(buff); // imgStr += buff; // } // // if (imgStr == null) // 图像数据为空 // return false; // BASE64Decoder decoder = new BASE64Decoder(); // // // Base64解码 // byte[] bytes = decoder.decodeBuffer(imgStr); // for (int i = 0; i < bytes.length; ++i) { // if (bytes[i] < 0) {// 调整异常数据 // bytes[i] += 256; // } // } // // 生成jpeg图片 // File f1 = new File(imgPath); // if (!f1.isDirectory()) // f1.mkdir(); // if (!imgPath.endsWith("/")) // imgPath += "/"; // OutputStream out = new FileOutputStream(imgFullPathName); // out.write(bytes); // out.flush(); // out.close(); // return true; // } catch (Exception e) { // e.printStackTrace(); // return false; // } } public static void excuCmd(String cmd) { System.out.println("$" + cmd); Process process = null; String buff = ""; try { /** * adb -s HC34WW907981 install * D:/Android/test/taobao_android.sword.signed.apk */ process = Runtime.getRuntime().exec(cmd); BufferedReader br = new BufferedReader(new InputStreamReader( process.getInputStream(), "utf-8")); while ((buff = br.readLine()) != null) { Util.print(buff); // if (buff.contains("INSTALL_FAILED_ALREADY_EXISTS")) { // Util.print(devName + "已安装"); // } } br.close(); } catch (IOException e) { e.printStackTrace(); } } /** * @param e */ public static void install(String deviceId) { String cmdInstall = "adb -s " + deviceId + " install -r " + Const.apkPath; Util.excuCmd(cmdInstall); }}
Mobile webdriver android-server.apk配置:
package ct4h5;
import ct4h5.config.Const;
import ct4h5.util.Util;
/**
* @author 东海陈光剑 2014年2月22日 上午2:27:35
*/
public class Init {
/**
* @param deviceId
*
*/
public static void init(String deviceId) {
String cmdUninstall = "adb -s " + deviceId
+ " uninstall org.openqa.selenium.android.app";
String cmdInstall = "adb -s " + deviceId + " install -r "
+ Const.apkPath;
/**
* 启动WebDriver
*/
int port = 8080;
String cmdStart = "adb -s "
+ deviceId
+ " shell am start -a android.intent.action.MAIN -n org.openqa.selenium.android.app/.MainActivity -e debug true";
String cmdForward = "adb -s " + deviceId + " forward tcp:" + port
+ " tcp:" + port;
Util.excuCmd(cmdUninstall);
Util.excuCmd(cmdInstall);
Util.excuCmd(cmdStart);
Util.excuCmd(cmdForward);
}
/**
* @param deviceId
*
*/
public static void forward(String deviceId) {
int port = 8080;
String cmdStart = "adb -s "
+ deviceId
+ " shell am start -a android.intent.action.MAIN -n org.openqa.selenium.android.app/.MainActivity -e debug true";
String cmdForward = "adb -s " + deviceId + " forward tcp:" + port
+ " tcp:" + port;
Util.excuCmd(cmdStart);
Util.excuCmd(cmdForward);
}
public static void destroy(String deviceId) {
String cmdUninstall = "adb -s " + deviceId
+ " uninstall org.openqa.selenium.android.app";
Util.excuCmd(cmdUninstall);
}
}
写数据库:
package ct4h5.dao;
import java.sql.*;
import org.testng.internal.remote.SlavePool;
public class InsertDB {
public static void main(String[] args) {
for (int i = 0; i < 10; i++)
insert("2", "2", "2", "2", "2");
}
public static boolean insert(String timestamp, String url, String imgName,
String deviceId, String imgTimeChamp) {
try {
Class.forName("com.mysql.jdbc.Driver"); // 加载MYSQL JDBC驱动程序
System.out.println("Success loading Mysql Driver!");
} catch (Exception e) {
System.out.print("Error loading Mysql Driver!");
e.printStackTrace();
}
try {
Connection connect = DriverManager.getConnection(
"jdbc:mysql://10.73.72.122:3306/test", "root", "isword");
// 连接URL为 jdbc:mysql//服务器地址/数据库名 ,后面的2个参数分别是登陆用户名和密码
System.out.println("Success connect Mysql server!");
Statement stmt = connect.createStatement();
// String insertCmd = "insert into ct_pic values(" + "\‘" +
// timestamp
// + "\‘" + "," + "\‘" + deviceId + "\‘" + "," + "\‘"
// + imgName + "\‘" + "," + "\‘" + url + "\‘" + ")";
String insertCmd = "INSERT INTO ct_pic(run_stamp,device_id,img_name,url,img_timestamp)"
+ " VALUES ("
+ "‘"
+ timestamp
+ "‘,"
+ "‘"
+ deviceId
+ "‘,"
+ "‘"
+ imgName
+ "‘,"
+ "‘"
+ url
+ "‘,‘"
+ imgTimeChamp + "‘)";
System.out.println(insertCmd);
boolean rs = stmt.execute(insertCmd);
return rs;
// while (rs.next()) {
// System.out.println(rs.getString("img_name"));
// }
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
// GRANT ALL ON *.* TO root@"%" IDENTIFIED BY isword;
来自为知笔记(Wiz)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。