分类

针对智能手机端的应用的自动化测试,目前主要分两类:

一是基于APP的apk自动化测试,

二是浏览器的wap页测试。

目前做的较多的是第一种情况,应用的自动化测试框架也较多,如NativeDriver、Robotium、calabash等;而第二种情况的自动化测试框架就较少了,目前较常用的为Selenium。

用途

测试手机浏览器上的网站

AndroidDriver

测试过程

AndroidDriver测试过程

真机启动:使用数据线将

Android

手机与电脑相连

真机启动:使用数据线将Android手机与电脑相连

手机端需要安装(webdriver)android-server-xxx.apk作为服务端分发http请求命令和显示返回内容

2.  安装完毕后点击启动该应用 

 3、进入可输入命令行的界面,输入 adb devices 回车 ,查看已链接手机

可能遇到的问题:

adb server is out of date.  killing...
ADB server didn't ACK
* failed to start daemon *

解决:关掉qq

出现这种问题一定是你电脑上有别的软件也同时运行了adb导致端口冲突了,所有带有连接android 手机功能的软件都要关掉,比如qq,豌豆荚,阿里旺旺,等等。并且打开任务管理器,找到正在运行的进程中所有adb相关的进程并终止掉,如adb.exe,tadb.exe等等。然后再重新adb 一下应该就可以。

2) 

经常出现android adb devices offline

解决:

adb version问题,adb换成高版本

adb下载:

http://dl.pconline.com.cn/download/359035-1.html

4.  (非必须)配置adb环境变量

android andServer使用教程_System

android andServer使用教程_System_02

测试环境变量已配置成功:

android andServer使用教程_ide_03

selenium-server-standalone-2.25.0.jar

6.   通过命令来打开手机端的webdriver和连接服务端(启动手机端的webdriver)

方法一: ——放在测试用例执行前

方法二:dos下直接输入命令

方法一:

@BeforeTest
	public void setUp() {
		// 启动手机端的webdriver——作为服务端,没有其他前台应用
		try {
			//打开webdriver
			// 配置adb 环境变量http://jingyan.baidu.com/article/17bd8e52f514d985ab2bb800.html
Runtime.getRuntime().exec( "adb shell am start -a android.intent.action.MAIN " +	"-n org.openqa.selenium.android.app/.MainActivity");
/*连接服务端webdriver,连接用的端口为8080,如果本地有开启了或使用了该端口,需要关闭(http://localhost:8080/exit),不然连接不上服务端webdriver   */
 Runtime.getRuntime().exec("adb -s HC51BWWE0103 forward tcp:8080 tcp:8080");
		} catch (IOException e) {
			e.printStackTrace();
		}
		driver = new AndroidDriver();
	}
	
	@AfterTest
	public void tearDown() {
		driver.quit();
	}

方法二:

adb shell am start -a android.intent.action.MAIN  -n org.openqa.selenium.android.app/.MainActivity

adb -s HC51BWWE0103 forward tcp:8080 tcp:8080

android andServer使用教程_ide_04

7.  测试

@Test  
    public void testBaidu() {        
		driver.get("http://m.baidu.com/");
		System.out.println("title:"+driver.getTitle());//title:百度一下
			WebElement element = driver.findElement(By.name("word"));
			element.sendKeys("hello");
			
			element.submit();
			
			System.out.println("title:"+driver.getTitle());//title:hello - 百度
   }

参考

http://wenku.baidu.com/link?url=tV7Nq6KLTkQHrT3pWlQkpiOkLoj-kWa3ODf4n3eUYZW5L1rEauKA5dn3X_U6V6hHGS_jgUGVOr79CT9tM5Qx5rqZ0EWtOHQgDTBsdmaE2Km

http://blogs.360.cn/360qtest/2014/04/01/%E5%88%A9%E7%94%A8selenium%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95android-wap%E9%A1%B5/

例子

https://github.com/xiaohuhuanxiang/chromedev/tree/chrome/seleniumAndroidTest

adb命令

查看设备, 确认是否已经连上

adb devices

这个命令是查看当前连接的设备, 连接到计算机的android设备或者模拟器将会列出显示

2.安装软件

adb install

adb install :这个命令将指定的apk文件安装到设备上

Android系列教程(六) adb操作命令详解

3. 卸载软件

adb uninstall <软件名>

adb uninstall -k <软件名>

如果加 -k 参数,为卸载软件但是保留配置和缓存文件.

4. 进入设备或模拟器的shell:

adb shell

通过上面的命令,就可以进入设备或模拟器的shell环境中,在这个Linux Shell中,你可以执行各种Linux的命令,另外如果只想执行一条shell命令,可以采用以下的方式:

adb shell [command]

如:adb shell dmesg会打印出内核的调试信息。

5. 发布端口

可以设置任意的端口号,做为主机向模拟器或设备的请求端口。如:

adb forward tcp:5555 tcp:8000

6. 从电脑上发送文件到设备

adb push <本地路径> <远程路径>

用push命令可以把本机电脑上的文件或者文件夹复制到设备(手机)

7. 从设备上下载文件到电脑

adb pull <远程路径> <本地路径>

用pull命令可以把设备(手机)上的文件或者文件夹复制到本机电脑

8、查看bug报告

adb bugreport

9、记录无线通讯日志

一般来说,无线通讯的日志非常多,在运行时没必要去记录,但我们还是可以通过命令,设置记录:

adb shell

logcat -b radio

10、获取设备的ID和序列号

adb get-product

adb get-serialno

adb shell

11、 

查看测试代码与server交互

http://localhost:8080/wd/hub/status/

{status:0}

验证cookie

利用cookie自动登录

WebDriver driver = new ChromeDriver();
        driver.get("http://localhost/cookie.php");
        driver.manage().deleteAllCookies();
        Cookie cookie=new Cookie("username","username","/",null);
        driver.manage().addCookie(cookie);
        Cookie cookie1=new Cookie("password","password","/",null);
        driver.manage().addCookie(cookie1);
        driver.get("http://localhost/cookie.php");
         
        Thread.sleep(3000);
        driver.quit();

selenium 操作cookie

Cookie cookie=new Cookie("java","eclipse","/",null);
        driver.manage().addCookie(cookie);
         
        //删除名称为value的cookie
        driver.manage().deleteCookieNamed("value");
        //删除刚才新增的cookie java
        driver.manage().deleteCookie(cookie);
         
        //输出现有cookie
        Set<Cookie> cks=driver.manage().getCookies();
        System.out.println("cookie总数为"+cks.size());
        for(Cookie ck:cks)
            System.out.println("作用域:"+ck.getDomain()+", 名称:"+ck.getName()+
                    ", 值:"+ck.getValue()+", 范围:"+ck.getPath()+
                    ", 过期时间"+ck.getExpiry());
         
        //删除全部cookie
        driver.manage().deleteAllCookies();
        Set<Cookie> c=driver.manage().getCookies();
        System.out.println("cookie总数为"+c.size());

Selenium+Webdriver执行JS脚本(localstorage)

参考:

http://www.tuicool.com/articles/7FvYzu

http://www.open-open.com/lib/view/open1402750704931.html

selenium 1.X的时候常常会用到getEval()方法来执行一段js脚本来对页面进行处理;

selenium webdriver也提供这样的一个方法:executeScript()

在代码中import org.openqa.selenium.JavascriptExecutor;就可以使用executeScript、executeAsyncScript这两个方法了,其中executeScript是同步方法,用它执行js代码会阻塞主线程执行,直到js代码执行完毕;executeAsyncScript方法是异步方法,它不会阻塞主线程执行。

同步执行 JavaScript 和异步执行 JavaScript 的区别(1)同步执行: driver_js.executeScript( js)           如果 JavaScript 代码的执行时间较短,可以选择同步执行,因为 Webdriver 会等待同步执行的结果,然后再运行其它的代码。(2)异步执行: driver_js.executeAsyncScript(js)           如果 JavaScript 代码的执行时间较长,可以选择异步执行,因为 Webdriver 不会等待其执行结果,而是直接执行下面的代码。

注:executeAsyncScript是异步地执行js,可以用来发送ajax请求executeScript方法如果有返回值,有以下几种情况:如果返回一个页面元素(document element), 这个方法就会返回一个WebElement如果返回浮点数字,这个方法就返回一个double类型的数字返回非浮点数字,方法返回Long类型数字返回boolean类型,方法返回Boolean类型如果返回一个数组,方法会返回一个List<Object>其他情况,返回一个字符串如果没有返回值,此方法就会返回null

在WebDriver 中直接执行JS代码来提升效率,一般用到执行js的场景主要分一下两种:

  在页面加载的时候执行JS

  在某个已经定位了的元素上执行js

// Execute JavaScript on page loading
((JavascriptExecutor)driver).executeScript("alert(\"Hello,World!\")");
/*
* Execute JavaScript on web element
*/
WebElement ele = driver.findElement(By.id("js")); // locate web element
((JavascriptExecutor) driver)
.executeScript(
"arguments[0].οnclick=function(){alert('js has been execute!');}",
ele); // add js on the web element

参考: http://www.51testing.com/html/15/n-853215.html

操作html5的localstorage:

String js="var len= window.localStorage.length;return len;";
Long result=(Long)((JavascriptExecutor)driver).executeScript(js);
System.out.println("---input title---"+result);

文本框输入内容

driver.get("http://www.baidu.com");
            //利用webdriver键入搜索关键字
            //driver.findElement(By.id("kw")).sendKeys("yeetrack");
            //利用js代码键入搜索关键字
            ((JavascriptExecutor)driver).executeScript("document.getElementById(\"kw\").value=\"yeetrack\"");
            //利用js代码取出关键字
            String keyword = (String) ((JavascriptExecutor)driver).executeScript("var input = document.getElementById(\"kw\").value;return input");
            System.out.println(keyword);
            driver.findElement(By.id("su")).click();

executeAsyncScript发送ajax请求

Object response = ((JavascriptExecutor) driver).executeAsyncScript(
       "var callback = arguments[arguments.length - 1];" +
       "var xhr = new XMLHttpRequest();" +
       "xhr.open('GET', '/resource/data.json', true);" +
       "xhr.onreadystatechange = function() {" +
       "  if (xhr.readyState == 4) {" +
       "    callback(xhr.responseText);" +
       "  }" +
       "}" +
       "xhr.send();");
   JSONObject json = new JSONObject((String) response);
   assertEquals("cheese", json.getString("food"));

动态载入 jquery

并不是所有的网页都引入了 Jquery ,如果我们要在这些网页上执行 Jquery 代码,就必须动态加载 Jquery source文件。

driver.get("file:///C:/test.html");

boolean flag =(boolean)(driver_js).executeScript("return typeof jQuery =='undefined'");

 if (flag)

 {

          driver_js.executeScript("var jq =document.createElement('script');"

                                + "jq.type ='text/javascript'; "

                                +"jq.src ='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';"

                                +"document.getElementsByTagName('head')[0].appendChild(jq);");

          Thread.sleep(3000);

   }

操作日历控件

h5视频播放

普通的js代码控制

<video id="h5v-video-ID" width="100%" height="100%" preload="meta" x-webkit-airplay="allow" webkit-playsinline="true" autoplay="" src="http://XXX.mp4"><p class="no-support">抱歉,您的浏览器不支持HTML5 video</p></video>

var myVideo=document.getElementById("h5v-video-ID");
myVideo.pause();
myVideo.play();
<span style="font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif; line-height: 27.2px;">myVideo.width=560;//设置视频大小</span>
alert(myVideo.src);//播放源

webdriver控制视频播放:

WebElement video = DriverFactory.findById("h5v-video-ID");
		JavascriptExecutor jse=	(JavascriptExecutor)driver;
		String src=(String)jse.executeScript("return arguments[0].currentSrc", video);

		 Assert.assertEquals("http://XXX.mp4", src);

		jse.executeScript("return arguments[0].play()", video);
		
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		jse.executeScript("return arguments[0].pause()", video);

旋转屏幕

WebDriver driver = new AndroidDriver();
		((Rotatable)driver).rotate(ScreenOrientation.LANDSCAPE);
		driver.get("url");

触摸和滚动

<span >	</span>driver.get("url");
		((Rotatable)driver).rotate(ScreenOrientation.PORTRAIT);
		TouchActions touch = new TouchActions(driver);
		touch.scroll(0, 800).build().perform();//向下滚动800像素