一、Appium简介
appium是一款开源的,跨平台的UI自动化测试工具适用于测试原生的或者混合型的移动APP支持IOS,Android,Firefox OS等平台,同时该框架支持JAVA,Python,PHP等语言编写的测试脚本。Appium与Selenium appium类库封装了标准Selenium客户端类库,为用户提供所有常见的JSON格式selenium命令以及额外的移动设备控制相关的命令,如多点触控手势和屏幕朝向。
二、appium运行原理
client端也就是我们 test script,即selenium(webdriver)测试脚本。中间是Appium服务,Appium启动一个Server(4723端口),它提供了一套REST的接口,Appium Server接收web driver client标准rest请求,解析请求内容,调用对应的框架响应操作。appium server会把请求转发给中间件Bootstrap.jar (它是用java写的,安装在手机上)Bootstrap监听4724端口并接收appium 的命令,最终通过调用UiAutomator的命令来实现。最后Bootstrap将执行的结果返回给appium server。appium server再将结果返回给客户端。
三、Appium测试环境搭建
请移步:Appium学前准备
四、脚本开发基本步骤
1. DesiredCapabilities
DesiredCapabilities类提供了一些key value的对象,它告诉appium server这样一些信息:
需要测试的平台是什么:“platformName”,“Android”需要测试的设备名(序列号)是什么:“deviceName”,“Android Emulator”需要测试的平台版本是:“platformVersion”,“4.4.4”需要测试的应用程序(包及首页activity) 设备上app是否需要重复安装:“noReset”,“true” 程序的包名:“appPackage”,“com.xiaomi.shop” 活动页:“appActivity”,“com.xiaomi.shop2.activity.MainActivity”
比如:
DesiredCapabilities des
= new DesiredCapabilities();
des
.setCapability("platformName","Android");
des
.setCapability("deviceName","Android Emulator");
des
.setCapability("platformVersion","4.4.4");
des
.setCapability("noReset","true");
des
.setCapability("appPackage","com.xiaomi.shop");
des
.setCapability("appActivity","com.xiaomi.shop2.activity.MainActivity");
2. 获取DesiredCapabilities参数方法
平台就android\ios\firefoxos获取设备名,就填:“Android Emulator”获取包名和活动页:
使用aapt工具,查看针对有apk安装包的情况,aapt工具在E:\ADT-bundle-windows-x86_64-20140321\adt-bundle-windows-x86_64-20140321\sdk\build-tools\android-4.4.2里aapt dump badging d:\\test.apk
使用adb查看,要先打开app,然后输入以下命令adb shell dumpsys window w | findstr mCurrent
需要测试的平台版本号adb shell getprop ro.build.version.release
3. 创建appuim对象
需要在main函数的()旁边加上异常处理throws MalformedURLException, InterruptedException以下代码为常规写法:AppiumDriver driver
= new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"),des
);
五、定位控件
定位控件有两种方法请移步:Appium学前准备
六、元素识别方法
appium也是以webdriver为基础的,对于元素的定位也基本一致,只是增加一些更适合移动平台的独特方式
1. id定位
主要看resource id的值:函数: driver.findElementById(resource_id的值);比如:
String str1
= dr
.findElementById("com.xiaomi.shop.plugin.homepage:id/main_bottom_tab_discovery_text").getAttribute("text");
2. class定位
主要看class的值函数: driver.findElementByClassName(class的值);比如:
String str2
= dr
.findElementByClassName("android.widget.TextView").getAttribute("text");
3. AndroidUIAutomator定位
主要看text的值函数: driver.findElementByAndroidUIAutomator(“text(\”中文\”)”);比如:
String str3
=dr
.findElementByAndroidUIAutomator("text(\"手机\")").getAttribute("text");
4. Accessibility ID定位
主要看content-desc的值函数: driver.findElementByAccessibilityId(content-desc的值);比如:
String str4
=dr
.findElementByAccessibilityId("XXX").getAttribute("text");
5. Xpath定位
主要看目标元素的位置函数: findElementByXPath(路径) findElementByXPath(“//*[@resource-id=‘xxx’]”)
String str5
= "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout[3]/android.widget.LinearLayout/android.widget.TextView";
String str6
=dr
.findElementByXPath(str5
).getAttribute("text");
七、元素操作方法
1. 常用操作方法
click() 点击sendKeys() 模拟键盘输入clear() 清除getattribute() 获取属性值
2. 针对应用的操作方法
安装应用:installApp();卸载应用:removeApp();关闭应用:closeAPP();启动应用:launchApp()检查应用是否安装:isAppInstalled()将应用置于后台:runAppInBackground()应用重置:resetApp()
3. 模拟手势操作
import io
.appium
.java_client
.TouchAction
;
TouchAction touchAction
= new TouchAction(driver
);
按压控件:press()长按控件:longPress()点击控件:tap()移动:moveTo()暂停:wait()结束操作:release()将操作发送服务器:Perform()
4. 移动设备特有的操作
息屏: lockDevice()当前Activity:currentActivity()收起键盘:hideKeyboard()滑动:swipe()拉出文件:pullFile()推送文件:pushFile()
八、案例
在脚本运行前,需要将appium成打开状态,保证adb环境已经配好,虚拟机也必须打开脚本运行速度很慢,我们需要耐心等待
1. QQ正式版的登录与退出
import io
.appium
.java_client
.AppiumDriver
;
import java
.net
.URL
;
import org
.openqa
.selenium
.remote
.DesiredCapabilities
;
public class A02login {
public static void main(String
[] args
) throws Exception
{
DesiredCapabilities des
= new DesiredCapabilities();
des
.setCapability("platformName","Android");
des
.setCapability("deviceName","Android Emulator");
des
.setCapability("platformVersion","4.4.4");
des
.setCapability("noReset","true");
des
.setCapability("appPackage","com.tencent.mobileqq");
des
.setCapability( "appActivity","com.tencent.mobileqq.activity.LoginActivity");
AppiumDriver dr
= new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"),des
);
dr
.findElementByAccessibilityId("请输入QQ号码或手机或邮箱").clear();
dr
.findElementByAccessibilityId("请输入QQ号码或手机或邮箱").sendKeys("1530247895");
dr
.findElementByAccessibilityId("密码 安全").clear();
dr
.findElementByAccessibilityId("密码 安全").sendKeys("yangheng123456");
dr
.findElementById("com.tencent.mobileqq:id/login").click();
Thread
.sleep(3000);
dr
.findElementById("com.tencent.mobileqq:id/conversation_head").click();
Thread
.sleep(1000);
dr
.findElementByAndroidUIAutomator("text(\"设置\")").click();
dr
.findElementByAndroidUIAutomator("text(\"帐号管理\")").click();
dr
.findElementByAndroidUIAutomator("text(\"退出当前帐号\")").click();
dr
.findElementById("com.tencent.mobileqq:id/dialogRightBtn").click();
Thread
.sleep(3000);
dr
.quit();
}
}
2. 小米商城购物
import io
.appium
.java_client
.AppiumDriver
;
import java
.net
.URL
;
import org
.openqa
.selenium
.remote
.DesiredCapabilities
;
public class A04XiaoMiShop {
public static void main(String
[] args
) throws Exception
{
DesiredCapabilities des
= new DesiredCapabilities();
des
.setCapability("platformName","Android");
des
.setCapability("deviceName","Android Emulator");
des
.setCapability("platformVersion","4.4.4");
des
.setCapability("noReset","true");
des
.setCapability("appPackage","com.xiaomi.shop");
des
.setCapability("appActivity","com.xiaomi.shop2.activity.MainActivity");
AppiumDriver dr
= new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"),des
);
dr
.findElementById("com.xiaomi.shop.plugin.homepage:id/main_bottom_tab_category_txt").click();
dr
.findElementByAndroidUIAutomator("text(\"电视\")").click();
dr
.findElementByAndroidUIAutomator("text(\"激光投影电视\")").click();
dr
.findElementByAndroidUIAutomator("text(\"米家投影仪 青春版2\")").click();
dr
.findElementByAndroidUIAutomator("text(\"加入购物车\")").click();
dr
.findElementByAndroidUIAutomator("text(\"购物车\")").click();
Thread
.sleep(3000);
dr
.quit();
}
}
以上脚本不涉及断言,后续会更新Junit单元测试框架展示加断言的脚本