Appium基础

介绍

安装appium

Mac

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# get node.js
$ brew install node
# get appium
$ npm install -g appium
# get appium client
$ npm install wd
# 启动Appium
$ appium &
# 验证安装
$ npm install -g appium-doctor
# 验证是否正确设置了ios所有依赖项
$ appium-doctor --ios
# 验证是否正确设置了android所有依赖项
$ appium-doctor --android
# 设置Appium客户端
$ cd /Users/iamwlb/Documents/Workspace/appium
$ npm init -f
$ npm install webdriverio

安装可选项

安装opencv4nodejs

图像比较功能。 对于许多自动化任务,图像比较可能很方便。例如:

  • 有必要弄清楚给定的图片示例是否出现在屏幕上
  • 有必要计算某些预定义的屏幕上对象的坐标
  • 有必要验证当前的屏幕上对象状态是否与预期状态相似
1
$ npm i -g opencv4nodejs

安装XCUITest Driver for IOS

1
2
3
4
5
6
7
$ bash brew install carthage
$ brew tap facebook/fb
$ brew install fbsimctl --HEAD
# 真机测试需要
$ brew install libimobiledevice
# 真机测试需要
$ brew install ios-deploy

安装 appium client

Python

pip安装

1
$ pip3 install Appium-Python-Client

源码安装

1
2
3
$ tar -xvf Appium-Python-Client-X.X.tar.gz 
$ cd Appium-Python-Client-X.X
$ python setup.py install

Git安装

1
2
3
$ git clone git@github.com:appium/python-client.git
$ cd python-client
$ python setup.py install

Java

1
2
3
4
5
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>1.3.0</version>
</dependency>

安装WebDriverAgent

Github

1
2
3
4
5
$ cd /Users/iamwlb/Documents/Workspace
$ git clone https://github.com/facebook/WebDriverAgent.git
$ cd WebDriverAgent
$ brew install Carthage
$ ./Scripts/bootstrap.sh

appium client方法

appium client扩展了原生的webdriver client方法,这些方法主要覆盖了3大类:

  • driver扩展:比如增加了resetApp等操作app的方法。
  • action扩展:增加一些移动端的特有的action(相当于是移动端特有的操作),比如swipe,shake(嗯,有了这个方法就可以让代码帮你摇一摇了)等。
  • locator扩展:增加了一些移动端专属的定位策略。
方法 说明
resetApp()
getAppString()
sendKeyEvent()
currentActivity()
pullFile()
pushFile()
pullFolder()
hideKeyboard()
runAppInBackground()
performTouchAction()
performMultiTouchAction()
tap()
swipe()
pinch()
zoom()
getNamedTextField()
isAppInstalled()
installApp()
removeApp()
launchApp()
closeApp()
endTestCoverage()
lockScreen()
shake()
complexFind()
scrollTo()
scrollToExact()
openNotifications()
Context Switching: .context(), .getContextHandles(), getContext())
findElementByAccessibilityId()
findElementsByAccessibilityId()
findElementByIosUIAutomation()
findElementsByIosUIAutomation()
findElementByAndroidUIAutomator()
findElementsByAndroidUIAutomator() -

Desired Capabilities

Desired Capabilities 在启动 session 的时候是必须提供的。 Desired Capabilities 本质上是以 key value 字典的方式存放,客户端将这些键值对发给服务端,告诉服务端我们想要怎么测试。它告诉 appium Server这样一些事情:

  • 本次测试是启动浏览器还是启动移动设备。
  • 是启动Andorid还是启动iOS。
  • 启动Android时,app的package是什么。
  • 启动Android时,app的activity是什么。
  • ...

参考

控件定位

Python

1
2
3
4
5
6
7
8
9
el = self.driver.find_element_by_android_uiautomator('new UiSelector().description("Animation")')
self.assertIsNotNone(el)
els = self.driver.find_elements_by_android_uiautomator('new UiSelector().clickable(true)')
self.assertIsInstance(els, list)

el = self.driver.find_element_by_accessibility_id('Animation')
self.assertIsNotNone(el)
els = self.driver.find_elements_by_accessibility_id('Animation')
self.assertIsInstance(els, list)

总的来说就是在driver里增加了

  • find_element_by_accessibility_id
  • find_elements_by_accessibility_id
  • find_element_by_android_uiautomator
  • find_elements_by_android_uiautomator

等方法。

Java

1
2
3
4
5
6
findElementByAccessibilityId()
findElementsByAccessibilityId()
findElementByIosUIAutomation()
findElementsByIosUIAutomation()
findElementByAndroidUIAutomator()
findElementsByAndroidUIAutomator()

appium API 操作

应用操作

功能 方法 说明
安装应用 installApp() 安装应用到设备中去。需要apk包的路径。
卸载应用 removeApp() 从设备中删除一个应用。 java driver.removeApp("com.example.android.apis");
关闭应用 closeApp() 关闭打开的应用,默认关闭当前打开的应用,所以不需要入参。这个方法并非真正的关闭应用,相当于按home键将应用置于后台,可以通过launchApp()再次启动。
启动应用 launchApp() 启动应用。你一定很迷惑,不是在初始化的配置信息已经指定了应用,脚本运行的时候就需要启动应用,为什么还要有这个方法去启动应用呢?重新启动应用也是一个测试点,该方法需要配合closeApp()使用的。
java driver.closeApp(); driver.launchApp();
检查应用是否安装 isAppInstalled() 检查应用是否已经安装。需要传参应用包的名字。返回结果为Ture或False。
java driver.isAppInstalled('com.example.android.apis');
将应用置于后台 runAppInBackground() 将当前活跃的应用程序发送到后台。这个方法需要入参,需要指定应用置于后台的时长。
driver.runAppInBackground(2);
应用重置 resetApp() 重置当前被测程序到出始化状态。该方法不需要入参。
java driver.resetApp();

上下文操作

功能 方法 说明
获取当前上下文 getContext() 获取当前所有的可用的上下文。该方法不需要入参。
当前所有上下文句柄 getContextHandles() 获取当前所有可用的上下文。该方法不需要入参。
切换上下文 context() 切换到特定的上下文中。需要指定上下文的名称。
java driver.context('NATIVE_APP') driver.context('WEBVIEW_1')

键盘操作

功能 方法 说明
sendKeys() driver.findElements(By.name("Name")).sendKeys("jack");
发送一个键码的操作 pressKeyCode() 该方法Android特有。
需要一个入参。
driver.pressKeyCode(29); // 字母“a”
如果想点击Android的HOME键应该怎么实现的呢?如下
java driver.pressKeyCode(AndroidKeyCode.HOME);

Android keycode参考表:

电话键

  • KEYCODE_CALL 拨号键 5
  • KEYCODE_ENDCALL 挂机键 6
  • KEYCODE_HOME 按键Home 3
  • KEYCODE_MENU 菜单键 82
  • KEYCODE_BACK 返回键 4
  • KEYCODE_SEARCH 搜索键 84
  • KEYCODE_CAMERA 拍照键 27
  • KEYCODE_FOCUS 拍照对焦键 80
  • KEYCODE_POWER 电源键 26
  • KEYCODE_NOTIFICATION 通知键 83
  • KEYCODE_MUTE 话筒静音键 91
  • KEYCODE_VOLUME_MUTE 扬声器静音键 164
  • KEYCODE_VOLUME_UP 音量增加键 24
  • KEYCODE_VOLUME_DOWN 音量减小键 25

控制键

  • KEYCODE_ENTER 回车键 66
  • KEYCODE_ESCAPE ESC键 111
  • KEYCODE_DPAD_CENTER 导航键 确定键 23
  • KEYCODE_DPAD_UP 导航键 向上 19
  • KEYCODE_DPAD_DOWN 导航键 向下 20
  • KEYCODE_DPAD_LEFT 导航键 向左 21
  • KEYCODE_DPAD_RIGHT 导航键 向右 22
  • KEYCODE_MOVE_HOME 光标移动到开始键 122
  • KEYCODE_MOVE_END 光标移动到末尾键 123
  • KEYCODE_PAGE_UP 向上翻页键 92
  • KEYCODE_PAGE_DOWN 向下翻页键 93
  • KEYCODE_DEL 退格键 67
  • KEYCODE_FORWARD_DEL 删除键 112
  • KEYCODE_INSERT 插入键 124
  • KEYCODE_TAB Tab键 61
  • KEYCODE_NUM_LOCK 小键盘锁 143
  • KEYCODE_CAPS_LOCK 大写锁定键 115
  • KEYCODE_BREAK Break/Pause键 121
  • KEYCODE_SCROLL_LOCK 滚动锁定键 116
  • KEYCODE_ZOOM_IN 放大键 168
  • KEYCODE_ZOOM_OUT 缩小键 169

组合键

  • KEYCODE_ALT_LEFT Alt+Left
  • KEYCODE_ALT_RIGHT Alt+Right
  • KEYCODE_CTRL_LEFT Control+Left
  • KEYCODE_CTRL_RIGHT Control+Right
  • KEYCODE_SHIFT_LEFT Shift+Left
  • KEYCODE_SHIFT_RIGHT Shift+Right

基本

  • KEYCODE_0 按键'0' 7
  • KEYCODE_1 按键'1' 8
  • KEYCODE_2 按键'2' 9
  • KEYCODE_3 按键'3' 10
  • KEYCODE_4 按键'4' 11
  • KEYCODE_5 按键'5' 12
  • KEYCODE_6 按键'6' 13
  • KEYCODE_7 按键'7' 14
  • KEYCODE_8 按键'8' 15
  • KEYCODE_9 按键'9' 16
  • KEYCODE_A 按键'A' 29
  • KEYCODE_B 按键'B' 30
  • KEYCODE_C 按键'C' 31
  • KEYCODE_D 按键'D' 32
  • KEYCODE_E 按键'E' 33
  • KEYCODE_F 按键'F' 34
  • KEYCODE_G 按键'G' 35
  • KEYCODE_H 按键'H' 36
  • KEYCODE_I 按键'I' 37
  • KEYCODE_J 按键'J' 38
  • KEYCODE_K 按键'K' 39
  • KEYCODE_L 按键'L' 40
  • KEYCODE_M 按键'M' 41
  • KEYCODE_N 按键'N' 42
  • KEYCODE_O 按键'O' 43
  • KEYCODE_P 按键'P' 44
  • KEYCODE_Q 按键'Q' 45
  • KEYCODE_R 按键'R' 46
  • KEYCODE_S 按键'S' 47
  • KEYCODE_T 按键'T' 48
  • KEYCODE_U 按键'U' 49
  • KEYCODE_V 按键'V' 50
  • KEYCODE_W 按键'W' 51
  • KEYCODE_X 按键'X' 52
  • KEYCODE_Y 按键'Y' 53
  • KEYCODE_Z 按键'Z' 54

TouchAction操作

功能 方法 说明
按压 press() 开始按压一个元素或坐标点(x,y)。通过手指按压手机屏幕的某个位置。
press(WebElement el, int x, int y)
press也可以接收屏幕的坐标(x,y)。
例:
TouchAction(driver).press(x=0,y=308).release().perform()
除了press()方法之外,本例中还用到了别外两个新方法。
release() 结束的行动取消屏幕上的指针。
Perform() 执行的操作发送到服务器的命令操作。
长按 longPress() 开始按压一个元素或坐标点。
longPress(WebElement el, int x, int y, Duration duration)
点击 tap() 对一个元素或控件执行点击操作。
移动 moveTo() 将指针(光标)从过去指向指定的元素或点。
movTo(WebElement el, int x, int y)
暂停 wait() 暂停脚本的执行,单位为毫秒。
Java action.wait(1000);

其它操作

功能 方法 说明
熄屏 lockDevice() 点击电源键熄灭屏幕。
在iOS设备可以设置熄屏一段时间。Android上面不带参数,所以熄屏之后就不会再点亮屏幕了。 java driver.lockDevice(1000); // iOS driver.lockDriice(); //Android
当前Activity(Android only) currentActivity() 得到当前应用的activity。只适用于Android。 例(通讯录): Java String ca = driver.currentActivity(); System.out.print(ca); -------------输出结果为------------- .activities.PeopleActivity
收起键盘 hideKeyboard() 收起键盘,这个方法很有用,当我们对一个输入框输入完成后,需要将键盘收起,再切换到一下输入框进行输入。 Java driver.hideKeyboard(); //收起键盘
滑动 swipe() 模拟用户滑动。将控件或元素从一个位置(x,y)拖动到另一个位置(x,y)。
swipe(int startx, int starty, int endx, int endy, int duration) * start_x:开始滑动的x坐标。 * start_y:开始滑动的y坐标。 * end_x:结束滑动的x坐标。 * end_y:结束滑动的y坐标。 * duration:持续时间。例: Java driver.swipe(75, 500, 75, 0, 800);
拉出文件 pullFile() 从设备中拉出文件。
推送文件 pushFile() 推送文件到设备中去。

定位控件

ID定位

1
driver.findElement(By.id("com.android.calculator2:id/formula"))

name 定位

1
driver.findElement(By.name("9"))

class name 定位

1
WebElement button = driver.findElement(By.className("android.widget.Button"));

XPath定位

1
driver.findElement(By.xpath("//android.view.ViewGroup/android.widget.Button"))  //7

Accessibility ID定位

1
java driver.findElementByAccessibilityId("plus").click();

android uiautomator定位

1
2
3
4
5
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"clr\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"8\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().description(\"plus\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"5\")").click();
driver.findElementByAndroidUIAutomator("new UiSelector().description(\"equals\")").click();

需要注意的是 description() 方法用的是content-desc属性。

appium-desktop

FBSimulatorControl

查看自己模拟器列表

1
$ fbsimctl list

启动多个模拟器

1
$ fbsimctl 设备编号1 设备编号2 设备编号3 boot

启动应用

1
$ fbsimctl launch app的bundleID

常见问题

Carthage was NOT found!

1
2
$ brew install carthage
$ carthage version

参考

坚持原创技术分享,您的支持将鼓励我继续创作!
0%