Mac安装配置appium

2017/2/28 posted in  Android

前言

因为公司需求,需要安装Appium来实现对手机APP的自动化测试,提升工作效率。所以来学习并记录一下Appium的安装以及使用的步骤,方便自己以后对App测试环境搭建的操作。

一、安装Appium

(二) 安装Homebrew

  • $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" #下载
  • $ brew update #更新
  • $ brew -v #查看是否安装好,以及其版本号

(三) 安装Node.js

使用homebrew来安装Node.js

  • $ brew install node #安装
  • $ node -v #查看是否安装好,以及其版本号

(四) 安装npm

  • $ brew install npm

(五) 安装appium服务端

推荐使用cnpm来安装:淘宝 NPM 镜像 10分钟同步npmjs.org镜像,使用方式和npm完全一致

  • $ npm install cnpm -g --registry=https://registry.npm.taobao.org
  • $ npm view appium versions #查看appium所有的版本号
  • $ cnpm install -g appium --no-cache $ cnpm install -g appium $ cnpm install -g appium-doctor

(六) 检查appium环境检测

在环境监测中打叉的就是没安装成功或者环境没有配置完全的

  • appium-doctor

1、appium环境常见问题解决

(1) Xcode Command Line Tools are NOT installed!
- `xcode-select --install   #按照提示安装即可`
(2) Carthage was NOT found
- `$ brew install carthage       #carthage:类似cocoapods管理第三方代码,自动将工程编译为动态库,所以仅支持iOS8以上`
(3) ANDROID_HOME is NOT set!
- 使用最新版本Java
- 修改Mac的开发环境
- `vi .bash_profile`
- `export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk(版本记得改)/Contents/Home`
- `export ANDROID_HOME=/Users/YourMacName/Library/Android/sdk`
- `export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:${JAVA_HOME}/bin`
- 修改完配置文件记得保存退出,然后`source .bash_profile`
- 如果有问题记得修改在终端的Shall打开方式,调整为命令

(七) 安装appium客户端(Python为例)

  • brew search python #查看可安装的python版本
  • brew install python3 #安装python3
  • pip install Appium-Python-Client   #安装python客户端  

(八) 安装支持iOS测试的插件

  • $ brew install libimobiledevice --HEAD # install from HEAD to get important updates
  • $ brew install ideviceinstaller # 只是对iOS9有用
  • $ npm install -g ios-deploy # iOS10 以后的版本安装ios-deploy
  • $ sudo gem install xcpretty # 真机需要安装 xcpretty

二、Appium测试

(一) iOS模拟器测试

  • xcodebuild -sdk iphonesimulator   #在xcodeproj项目工程目录下执行,编译生成build文件夹,并在其中生成app文件
  • npm install -g authorize-ios   #安装iOS模拟器启动器
  • sudo authorize-ios   #启动iOS模拟器
  • appium &   #启动appium服务器
  • python ***.py     #另开一个终端执行python脚本
  • iOS模拟器自动开启,安装应用并开始执行测试脚本

(二) Android模拟器测试

  • appium -a 127.0.0.1 -p 4723 -U db3489d --no-reset

三、Appium命令

(一) 服务端启动命令

服务器标志
所有的标志都是可选的,但是有一些标志需要组合在一起才能生效。

标志 默认值 描述 例子
--shell null 进入 REPL 模式
--localizable-strings-dir en.lproj IOS only: 定位 .strings所在目录的相对路径 --localizable-strings-dir en.lproj
--app null iOS: 基于模拟器编译的 app 的绝对路径或者设备目标的 bundle_id; Android: apk 文件的绝对路径--app /abs/path/to/my.app
--ipa null (IOS-only) .ipa 文件的绝对路径 --ipa /abs/path/to/my.ipa
-U, --udid null 连接物理设备的唯一设备标识符 --udid 1adsf-sdfas-asdf-123sdf
-a, --address 0.0.0.0 监听的 ip 地址 --address 0.0.0.0
-p, --port 4723 监听的端口 --port 4723
-ca, --callback-address null 回调IP地址 (默认: 相同的IP地址) --callback-address 127.0.0.1
-cp, --callback-port null 回调端口号 (默认: 相同的端口号) --callback-port 4723
-bp, --bootstrap-port 4724 (Android-only) 连接设备的端口号 --bootstrap-port 4724
-k, --keep-artifacts false 弃用,无效。trace信息现在保留tmp目录下,每次运行前会清除该目录中的信息。 也可以参考 –trace-dir 。
-r, --backend-retries 3 (iOS-only) 遇到 crash 或者 超时,Instrument 重新启动的次数。 --backend-retries 3
--session-override false 允许 session 被覆盖 (冲突的话)
--full-reset false (iOS) 删除整个模拟器目录。 (Android) 通过卸载应用(而不是清除数据)重置应用状态。在 Android 上,session 完成后也会删除应用。
--no-reset false session 之间不重置应用状态 (iOS: 不删除应用的 plist 文件; Android: 在创建一个新的 session 前不删除应用。)
-l, --pre-launch false 在第一个 session 前,预启动应用 (iOS 需要 –app 参数,Android 需要 –app-pkg 和 –app-activity)
-lt, --launch-timeout 90000 (iOS-only) 等待 Instruments 启动的时间
-g, --log null 将日志输出到指定文件 --log /path/to/appium.log
--log-level debug 日志级别; 默认 (console[:file]): debug[:debug] --log-level debug
--log-timestamp false 在终端输出里显示时间戳
--local-timezone false 使用本地时间戳
--log-no-colors false 不在终端输出中显示颜色
-G, --webhook null 同时发送日志到 HTTP 监听器 --webhook localhost:9876
--native-instruments-lib false (IOS-only) iOS 内建了一个怪异的不可能避免的延迟。我们在 Appium 里修复了它。如果你想用原来的,你可以使用这个参数。
--app-pkg null (Android-only) 你要运行的apk的java包。 (例如, com.example.android.myApp) --app-pkg com.example.android.myApp
--app-activity null (Android-only) 打开应用时,启动的 Activity 的名字(比如, MainActivity) --app-activity MainActivity
--app-wait-package false (Android-only) 你想等待的 Activity 的包名。(比如, com.example.android.myApp) --app-wait-package com.example.android.myApp
--app-wait-activity false (Android-only) 你想等待的 Activity 名字(比如, SplashActivity) --app-wait-activity SplashActivity
--android-coverage false (Android-only) 完全符合条件的 instrumentation 类。 作为命令 adb shell am instrument -e coverage true -w 的 -w 的参数 --android-coverage com.my.Pkg/com.my.Pkg.instrumentation.MyInstrumentation
--avd null (Android-only) 要启动的 avd 的名字
--avd-args null (Android-only) 添加额外的参数给要启动avd --avd-args -no-snapshot-load
--device-ready-timeout 5 (Android-only) 等待设备准备好的时间,以秒为单位 --device-ready-timeout 5
--safari false (IOS-Only) 使用 Safari 应用
--device-name null 待使用的移动设备名字 --device-name iPhone Retina (4-inch), Android Emulator
--platform-name null 移动平台的名称: iOS, Android, or FirefoxOS --platform-name iOS
--platform-version null 移动平台的版本 --platform-version 7.1
--automation-name null 自动化工具的名称: Appium or Selendroid --automation-name Appium
--browser-name null 移动浏览器的名称: Safari or Chrome --browser-name Safari
--default-device, -dd false (IOS-Simulator-only) 使用instruments自己启动的默认模拟器
--force-iphone false (IOS-only) 无论应用要用什么模拟器,强制使用 iPhone 模拟器
--force-ipad false (IOS-only) 无论应用要用什么模拟器,强制使用 iPad 模拟器
--language null iOS / Android 模拟器的语言 --language en
--locale null Locale for the iOS simulator / Android Emulator --locale en_US
--calendar-format null (IOS-only) iOS 模拟器的日历格式 --calendar-format gregorian
--orientation null (IOS-only) 初始化请求时,使用 LANDSCAPE (横屏) 或者 PORTRAIT (竖屏) --orientation LANDSCAPE
--tracetemplate null (IOS-only) 指定 Instruments 使用的 tracetemplate 文件 --tracetemplate /Users/me/Automation.tracetemplate
--show-sim-log false (IOS-only) 如果设置了, iOS 模拟器的日志会写到终端上来
--show-ios-log false (IOS-only) 如果设置了, iOS 系统的日志会写到终端上来
--nodeconfig null 指定 JSON 格式的配置文件 ,用来在 selenium grid 里注册 appiumd --nodeconfig /abs/path/to/nodeconfig.json
-ra, --robot-address 0.0.0.0 robot 的 ip 地址 --robot-address 0.0.0.0
-rp, --robot-port -1 robot 的端口地址 --robot-port 4242
--selendroid-port 8080 用来和 Selendroid 交互的本地端口 --selendroid-port 8080
--chromedriver-port 9515 ChromeDriver运行的端口 --chromedriver-port 9515
--chromedriver-executable null ChromeDriver 可执行文件的完整路径
--use-keystore false (Android-only) 设置签名 apk 的 keystore
--keystore-path (Android-only) keystore 的路径
--keystore-password android (Android-only) keystore 的密码
--key-alias androiddebugkey (Android-only) Key 的别名
--key-password android (Android-only) Key 的密码
--show-config false 打印 Appium 服务器的配置信息,然后退出
--no-perms-check false 跳过Appium对是否可以读/写必要文件的检查
--command-timeout 60 默认所有会话的接收命令超时时间 (在超时时间内没有接收到新命令,自动关闭会话)。 会被新的超时时间覆盖
--keep-keychains false (iOS) 当 Appium 启动或者关闭的时候,是否保留 keychains (Library/Keychains)
--strict-caps false 如果所选设备是appium不承认的有效设备,会导致会话失败
--isolate-sim-device false Xcode 6存在一个bug,那就是一些平台上如果其他模拟器设备先被删除时某个特定的模拟器只能在没有任何错误的情况下被建立。这个选项导致了Appium不得不删除除了正在使用设备以外其他所有的设备。请注意这是永久性删除,你可以使用simctl或xcode管理被Appium使用的设备类别。
--tmp null 可以被Appium用来管理临时文件的目录(绝对路径),比如存放需要移动的内置iOS应用程序。 默认的变量为 APPIUM_TMP_DIR ,在 *nix/Mac 为 /tmp 在windows上使用环境便令 TEMP 设定的目录。
--trace-dir null 用于保存iOS instruments trace的 appium 目录,是绝对路径, 默认为 /appium-instruments
--intent-action android.intent.action.MAIN (Android-only) 用于启动 activity 的intent action --intent-action android.intent.action.MAIN
--intent-category android.intent.category.LAUNCHER (Android-only) 用于启动 activity 的intent category --intent-category android.intent.category.APP_CONTACTS
--intent-flags 0x10200000 (Android-only) 启动 activity 的标志 --intent-flags 0x10200000
--intent-args null (Android-only) 启动 activity 时附带额外的 intent 参数 --intent-args 0x10200000
--suppress-adb-kill-server false (Android-only) 如果被设定,阻止Appium杀掉adb实例。

(二) Android测试用例编写

1、例子:

import os

import unittest
from appium import webdriver
from time import sleep

PATH = lambda p: os.path.abspath(
    os.path.join(os.path.dirname(__file__),p)
)

class XingQiuAndroidTests(unittest.TestCase):

    def setUp(self):
        desired_caps = {}
        desired_caps['deviceName'] = 'emulator-5554'  #adb devices查到的设备名
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] = '4.4'
        desired_caps['app'] = PATH(
            '../../../Users/jiangruoming/Desktop/***.apk'
        )
        desired_caps['appPackage'] = 'com.***.***'  #被测App的包名
        desired_caps['appActivity'] = '.****' #启动时的Activity

        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

    #earDown 方法在每个测试方法执行后调用,这个地方做所有清理工作,如退出
    def tearDown(self):
        self.driver.quit()

    #放置的就是我们的测试脚本了,这部分我们并不陌生;因为我们执行的脚本就在这里。
    def test_add_contacts(self):
        el = self.driver.find_element_by_id("com.***.***:id/sign_phone")
        el.click()

        phone_number = self.driver.find_element_by_id("com.***.***:id/et_user_phone")
        code = self.driver.find_element_by_id("com.***.***:id/et_smscode")
        phone_number.send_keys("*********")
        code.send_keys("****")

        btn = self.driver.find_element_by_id("com.***.***:id/btn_finish")
        btn.click()

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(XingQiuAndroidTests)
    unittest.TextTestRunner(verbosity=2).run(suite)

2、测试流程

(1) 启动Appium

appium -a 127.0.0.1 -p 4723 --log /path/to/appium.log

(2) 启动Android模拟器

由于测试apk不支持X86平台,所以Genymotion无法支持运行,原生arm模拟器运行过慢(胃都等疼了)。试过多个模拟器后,最终选定了夜神模拟器,效果还是不错的。但是由于其主要用于PC平台运行Android游戏,所以用于开发平台还是需要进行配置。

a、adb配置

在Mac环境中加入adb的环境变量

vi .bash_profile

export PATH=/Users/Path/To/Android/sdk/platform-tools/:$PATH

source .bash_profile

b、adb连接

之后进入夜神的包内容中在adb所在文件夹运行adb连接命令

adb connect 127.0.0.1:62001
这样adb devices就能显示夜神模拟器的Device ID

(3) 运行脚本

(三) iOS测试用例编写

1、例子:

import unittest
import os
from appium import webdriver
from time import sleep


PATH = lambda p: os.path.abspath(
    os.path.join(os.path.dirname(__file__),p)
)

class XingQiuiOSTests(unittest.TestCase):

    def setUp(self):
        desired_caps = {}
        desired_caps['platformName'] = 'iOS'
        desired_caps['platformVersion'] = '10.2'
        desired_caps['deviceName'] = 'iPhone Simulator'
        desired_caps['app'] = PATH('../../../Users/jiangruoming/Desktop/***.app')

        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

    #def tearDown(self):
        #self.driver.quit()

    def test_add_contacts(self):

        el2 = self.driver.find_elements_by_accessibility_id('Allow')

        if el2:
            el2[0].click()

        el3 = self.driver.find_elements_by_class_name('XCUIElementTypeButton')[0]
        el3.click()

        el4 = self.driver.find_elements_by_class_name('XCUIElementTypeTextField')[0]
        el4.send_keys("15088678313")

        el5 = self.driver.find_elements_by_class_name('XCUIElementTypeTextField')[1]
        el5.send_keys("1234")

        el6 = self.driver.find_elements_by_class_name('XCUIElementTypeButton')[0]
        el6.click()

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(XingQiuiOSTests)
    unittest.TextTestRunner(verbosity=2).run(suite)

2、XCUIElementType

XCUIElementTypeAny,
    XCUIElementTypeUnknown,
    XCUIElementTypeApplication,
    XCUIElementTypeGroup,
    XCUIElementTypeWindow,
    XCUIElementTypeSheet,
    XCUIElementTypeDrawer,
    XCUIElementTypeAlert,
    XCUIElementTypeDialog,
    XCUIElementTypeButton,
    XCUIElementTypeRadioButton,
    XCUIElementTypeRadioGroup,
    XCUIElementTypeCheckBox,
    XCUIElementTypeDisclosureTriangle,
    XCUIElementTypePopUpButton,
    XCUIElementTypeComboBox,
    XCUIElementTypeMenuButton,
    XCUIElementTypeToolbarButton,
    XCUIElementTypePopover,
    XCUIElementTypeKeyboard,
    XCUIElementTypeKey,
    XCUIElementTypeNavigationBar,
    XCUIElementTypeTabBar,
    XCUIElementTypeTabGroup,
    XCUIElementTypeToolbar,
    XCUIElementTypeStatusBar,
    XCUIElementTypeTable,
    XCUIElementTypeTableRow,
    XCUIElementTypeTableColumn,
    XCUIElementTypeOutline,
    XCUIElementTypeOutlineRow,
    XCUIElementTypeBrowser,
    XCUIElementTypeCollectionView,
    XCUIElementTypeSlider,
    XCUIElementTypePageIndicator,
    XCUIElementTypeProgressIndicator,
    XCUIElementTypeActivityIndicator,
    XCUIElementTypeSegmentedControl,
    XCUIElementTypePicker,
    XCUIElementTypePickerWheel,
    XCUIElementTypeSwitch,
    XCUIElementTypeToggle,
    XCUIElementTypeLink,
    XCUIElementTypeImage,
    XCUIElementTypeIcon,
    XCUIElementTypeSearchField,
    XCUIElementTypeScrollView,
    XCUIElementTypeScrollBar,
    XCUIElementTypeStaticText,
    XCUIElementTypeTextField,
    XCUIElementTypeDateField,
    XCUIElementTypeTimeField,
    XCUIElementTypeTextView,
    XCUIElementTypeMenu,
    XCUIElementTypeMenuItem,
    XCUIElementTypeMenuBar,
    XCUIElementTypeMenuBarItem,
    XCUIElementTypeMap,
    XCUIElementTypeWebView,
    XCUIElementTypeIncrementArrow,
    XCUIElementTypeDecrementArrow,
    XCUIElementTypeTimeline,
    XCUIElementTypeRatingIndicator,
    XCUIElementTypeValueIndicator,
    XCUIElementTypeSplitGroup,
    XCUIElementTypeSplitter,
    XCUIElementTypeRelevanceIndicator,
    XCUIElementTypeColorWell,
    XCUIElementTypeHelpTag,
    XCUIElementTypeMatte,
    XCUIElementTypeDockItem,
    XCUIElementTypeRuler,
    XCUIElementTypeRulerMarker,
    XCUIElementTypeGrid,
    XCUIElementTypeLevelIndicator,
    XCUIElementTypeCell,
    XCUIElementTypeLayoutArea,
    XCUIElementTypeLayoutItem,
    XCUIElementTypeHandle,

3、Appium Python API

(1) contexts

contexts(self):

Returns the contexts within the current session.
返回当前会话中的上下文,使用后可以识别H5页面的控件
Usage:

driver.contexts

用法:

driver.contexts

(2) current_context

current_context(self):

Returns the current context of the current session.

返回当前会话的当前上下文

Usage:

driver.current_context

用法:

driver. current_context

(3) context

context(self):

Returns the current context of the current session.

返回当前会话的当前上下文。

Usage:

driver.context

用法:

driver. Context

(4) find_element_by_ios_uiautomation

find_element_by_ios_uiautomation(self, uia_string):

Finds an element by uiautomation in iOS.

通过iOS uiautomation查找元素

Args:

  • uia_string - The element name in the iOS UIAutomation library
    Usage:
    driver.find_element_by_ios_uiautomation('.elements()[1].cells()[2]') 用法:
    dr. find_element_by_ios_uiautomation(‘elements’)
(5) find_element_by_accessibility_id

find_element_by_accessibility_id(self, id):

Finds an element by accessibility id.

通过accessibility id查找元素

Args:

- id - a string corresponding to a recursive element search using the Id/Name that the native Accessibility options utilize

Usage:

driver.find_element_by_accessibility_id()

用法:

driver.find_element_by_accessibility_id(‘id’)

(6) scroll

scroll(self, origin_el, destination_el):
Scrolls from one element to another

从元素origin_el滚动至元素destination_el

Args:

  • originalEl - the element from which to being scrolling
  • destinationEl - the element to scroll to
    Usage:
    driver.scroll(el1, el2) 用法:
    driver.scroll(el1,el2)
(7) drag_and_drop

drag_and_drop(self, origin_el, destination_el):

Drag the origin element to the destination element

将元素origin_el拖到目标元素destination_el

Args:

  • originEl - the element to drag
  • destinationEl - the element to drag to
    用法:
    driver.drag_and_drop(el1,el2)
(8) tap

tap(self, positions, duration=None):

Taps on an particular place with up to five fingers, holding for a certain time

模拟手指点击(最多五个手指),可设置按住时间长度(毫秒)

Args:

  • positions - an array of tuples representing the x/y coordinates of the fingers to tap. Length can be up to five.
  • duration - (optional) length of time to tap, in ms
    Usage:
    driver.tap([(100, 20), (100, 60), (100, 100)], 500) 用法:
    driver.tap([(x,y),(x1,y1)],500)
(9) swipe

swipe(self, start_x, start_y, end_x, end_y, duration=None):

Swipe from one point to another point, for an optional duration.

从A点滑动至B点,滑动时间为毫秒

Args:

- start_x - x-coordinate at which to start
- start_y - y-coordinate at which to start
- end_x - x-coordinate at which to stop
- end_y - y-coordinate at which to stop
- duration - (optional) time to take the swipe, in ms.

Usage:

driver.swipe(100, 100, 100, 400)
用法:

driver.swipe(x1,y1,x2,y2,500)

(10) flick

flick(self, start_x, start_y, end_x, end_y):

Flick from one point to another point.

按住A点后快速滑动至B点

Args:

- start_x - x-coordinate at which to start
- start_y - y-coordinate at which to start
- end_x - x-coordinate at which to stop
- end_y - y-coordinate at which to stop

Usage:

driver.flick(100, 100, 100, 400)
用法:

driver.flick(x1,y1,x2,y2)

(11) pinch

pinch(self, element=None, percent=200, steps=50):

Pinch on an element a certain amount

在元素上执行模拟双指捏(缩小操作)

Args:

  • element - the element to pinch
  • percent - (optional) amount to pinch. Defaults to 200%
  • steps - (optional) number of steps in the pinch action

Usage:

driver.pinch(element)
用法:
driver.pinch(element)

(12) zoom

zoom(self, element=None, percent=200, steps=50):
Zooms in on an element a certain amount

在元素上执行放大操作

Args:

  • element - the element to zoom
  • percent - (optional) amount to zoom. Defaults to 200%
  • steps - (optional) number of steps in the zoom action

Usage:
driver.zoom(element)
用法:
driver.zoom(element)

(13) reset

reset(self):

Resets the current application on the device.

重置应用(类似删除应用数据)

用法:
driver.reset()

(14) hide_keyboard

hide_keyboard(self, key_name=None, key=None, strategy=None):
Hides the software keyboard on the device. In iOS, use key_name to press a particular key, or strategy. In Android, no parameters are used.
隐藏键盘,iOS使用key_name隐藏,安卓不使用参数
Args:

  • key_name - key to press
  • strategy - strategy for closing the keyboard (e.g., tapOutside)

driver.hide_keyboard()

(15) keyevent

keyevent(self, keycode, metastate=None):

Sends a keycode to the device. Android only. Possible keycodes can be found in http://developer.android.com/reference/android/view/KeyEvent.html.

发送按键码(安卓仅有),按键码可以上网址中找到

Args:

  • keycode - the keycode to be sent to the device
  • metastate - meta information about the keycode being sent

用法:
dr.keyevent(‘4’)

(16) press_keycode

press_keycode(self, keycode, metastate=None):

Sends a keycode to the device. Android only. Possible keycodes can be found in http://developer.android.com/reference/android/view/KeyEvent.html.

发送按键码(安卓仅有),按键码可以上网址中找到
Args:

  • keycode - the keycode to be sent to the device
  • metastate - meta information about the keycode being sent

用法:
driver.press_ keycode(‘4’)

dr.keyevent(‘4’)与driver.press_ keycode(‘4’) 功能实现上一样的,都是按了返回键

(17) long_press_keycode

long_press_keycode(self, keycode, metastate=None):

Sends a long press of keycode to the device. Android only. Possible keycodes can be found in http://developer.android.com/reference/android/view/KeyEvent.html.

发送一个长按的按键码(长按某键)

Args:

  • keycode - the keycode to be sent to the device
  • metastate - meta information about the keycode being sent
    用法:
    driver.long_press_keycode(‘4’)
(18) current_activity

current_activity(self):

Retrieves the current activity on the device.

获取当前的activity

用法:
print(driver.current_activity())

(19) wait_activity

wait_activity(self, activity, timeout, interval=1):

Wait for an activity: block until target activity presents or time out.

This is an Android-only method.

等待指定的activity出现直到超时,interval为扫描间隔1秒

即每隔几秒获取一次当前的activity

返回的True 或 False

Agrs:

  • activity - target activity
  • timeout - max wait time, in seconds
  • interval - sleep interval between retries, in seconds

用法:
driver.wait_activity(‘.activity.xxx’,5,2)

(20) background_app

background_app(self, seconds):
Puts the application in the background on the device for a certain duration.

后台运行app多少秒

Args:

  • seconds - the duration for the application to remain in the background
    用法: driver.background_app(5)
    置后台5秒后再运行
(21) is_app_installed

is_app_installed(self, bundle_id):

Checks whether the application specified by bundle_id is installed on the device.

检查app是否有安装

返回 True or False

Args:

  • bundle_id - the id of the application to query

用法:
driver.is_app_installed(“com.xxxx”)

(22) install_app

install_app(self, app_path):

Install the application found at app_path on the device.

安装app,app_path为安装包路径

Args:

  • app_path - the local or remote path to the application to install

用法:

driver.install_app(app_path)

(23) remove_app

remove_app(self, app_id):

Remove the specified application from the device.

删除app

Args:

  • app_id - the application id to be removed

用法:
driver.remove_app(“com.xxx.”)

(24) launch_app

launch_app(self):

Start on the device the application specified in the desired capabilities.

启动app

用法:

driver.launch_app()

(25) close_app

close_app(self):

Stop the running application, specified in the desired capabilities, on the device.

关闭app

用法:

driver.close_app()

启动和关闭app运行好像会出错

(26) start_activity

start_activity(self, app_package, app_activity, **opts):

Opens an arbitrary activity during a test. If the activity belongs to another application, that application is started and the activity is opened.

This is an Android-only method.

在测试过程中打开任意活动。如果活动属于另一个应用程序,该应用程序的启动和活动被打开。

这是一个安卓的方法

Args:

  • app_package - The package containing the activity to start.
  • app_activity - The activity to start.
  • app_wait_package - Begin automation after this package starts (optional).
  • app_wait_activity - Begin automation after this activity starts (optional).
  • intent_action - Intent to start (optional).
  • intent_category - Intent category to start (optional).
  • intent_flags - Flags to send to the intent (optional).
  • optional_intent_arguments - Optional arguments to the intent (optional).
  • stop_app_on_reset - Should the app be stopped on reset (optional)?

用法:

driver.start_activity(app_package, app_activity)

(27) lock

lock(self, seconds):

Lock the device for a certain period of time. iOS only.

锁屏一段时间 iOS专有

Args:

  • the duration to lock the device, in seconds

用法:

driver.lock()

(28) shake

shake(self):

Shake the device.

摇一摇手机

用法:

driver.shake()

(29) open_notifications

open_notifications(self):

Open notification shade in Android (API Level 18 and above)

打系统通知栏(仅支持API 18 以上的安卓系统)

用法:

driver.open_notifications()

(30) network_connection

network_connection(self):

Returns an integer bitmask specifying the network connection type.

Android only.

返回网络类型 数值

Possible values are available through the enumeration appium.webdriver.ConnectionType

用法:

driver.network_connection

(31) set_network_connection

set_network_connection(self, connectionType):

Sets the network connection type. Android only.

Possible values:

Value (Alias) Data Wifi Airplane Mode
0 (None) 0 0 0
1 (Airplane Mode) 0 0 1
2 (Wifi only) 0 1 0
4 (Data only) 1 0 0
6 (All network on) 1 1 0

These are available through the enumeration appium.webdriver.ConnectionType`

设置网络类型

Args:

  • connectionType - a member of the enum appium.webdriver.ConnectionType

用法:

先加载from appium.webdriver.connectiontype import ConnectionType

dr.set_network_connection(ConnectionType.WIFI_ONLY)

ConnectionType的类型有

NO_CONNECTION = 0

AIRPLANE_MODE = 1

WIFI_ONLY = 2

DATA_ONLY = 4

ALL_NETWORK_ON = 6

(32) available_ime_engines

available_ime_engines(self):

Get the available input methods for an Android device. Package and activity are returned (e.g., ['com.android.inputmethod.latin/.LatinIME'])

Android only.

返回安卓设备可用的输入法

用法:

print(driver.available_ime_engines)

(33) is_ime_active

is_ime_active(self):

Checks whether the device has IME service active. Returns True/False.

Android only.

检查设备是否有输入法服务活动。返回真/假。

安卓

用法:
print(driver.is_ime_active())

(34) activate_ime_engine

activate_ime_engine(self, engine):

Activates the given IME engine on the device.

Android only.

激活安卓设备中的指定输入法,设备可用输入法可以从“available_ime_engines”获取

Args:

  • engine - the package and activity of the IME engine to activate (e.g.,'com.android.inputmethod.latin/.LatinIME')

用法:

driver.activate_ime_engine(“com.android.inputmethod.latin/.LatinIME”)

(35) deactivate_ime_engine

deactivate_ime_engine(self):

Deactivates the currently active IME engine on the device.

Android only.

关闭安卓设备当前的输入法

用法:
driver.deactivate_ime_engine()

(36) active_ime_engine

active_ime_engine(self):

Returns the activity and package of the currently active IME engine (e.g.,'com.android.inputmethod.latin/.LatinIME').

Android only.

返回当前输入法的包名

用法:

driver.active_ime_engine

(37) toggle_location_services

toggle_location_services(self):

Toggle the location services on the device. Android only.

打开安卓设备上的位置定位设置

用法:
driver.toggle_location_services()

(38) set_location

set_location(self, latitude, longitude, altitude):

Set the location of the device

设置设备的经纬度

Args:

  • latitude纬度 - String or numeric value between -90.0 and 90.00
  • longitude经度 - String or numeric value between -180.0 and 180.0
  • altitude海拔高度- String or numeric value

用法:

driver.set_location(纬度,经度,高度)

(39) tag_name

tag_name(self):

This element's tagName property.

返回元素的tagName属性

经实践返回的是class name

用法:

element.tag_name()

(40) text

text(self):

The text of the element.

返回元素的文本值

用法:

element.text()

(41) click

click(self):

Clicks the element.

点击元素

用法:

element.click()

(42) submit

submit(self):

Submits a form.

提交表单

用法:

暂无

(43) clear

clear(self):

Clears the text if it's a text entry element.

清除输入的内容

用法:

element.clear()

(44) get_attribute

get_attribute(self, name):

详见@chenhengjie123 的超级链接

Gets the given attribute or property of the element.

1. 获取 content-desc 的方法为 get_attribute("name") ,而且还不能保证返回的一定是 content-desc (content-desc 为空时会返回 text 属性值)  
2. get_attribute 方法不是我们在 uiautomatorviewer 看到的所有属性都能获取的(此处的名称均为使用 get_attribute 时使用的属性名称)
可获取的:
字符串类型:
    `name(返回 content-desc 或 text)`
    `text(返回 text)`
    `className(返回 class,只有 API=>18 才能支持)`
    `resourceId(返回 resource-id,只有 API=>18 才能支持)`

This method will first try to return the value of a property with the given name. If a property with that name doesn't exist, it returns the value of the attribute with the same name. If there's no attribute with that name, None is returned.Values which are considered truthy, that is equals "true" or "false",are returned as booleans. All other non-None values are returned as strings. For attributes or properties which do not exist, None is returned.

Args:

  • name - Name of the attribute/property to retrieve.

Example:
# Check if the "active" CSS class is applied to an element.

is_active = "active" in target_element.get_attribute("class")

用法:

暂无

(45) is_selected

is_selected(self):

Returns whether the element is selected.

Can be used to check if a checkbox or radio button is selected.

返回元素是否选择。

可以用来检查一个复选框或单选按钮被选中。

用法:

element.is_slected()

(46) is_enabled

is_enabled(self):

Returns whether the element is enabled.

返回元素是否可用True of False

用法:

element.is_enabled()

(47) find_element_by_id

find_element_by_id(self, id_):

Finds element within this element's children by ID.

通过元素的ID定位元素

Args:

  • id_ - ID of child element to locate.

用法:

driver. find_element_by_id(“id”)

(48) find_elements_by_id

find_elements_by_id(self, id_):

Finds a list of elements within this element's children by ID.

通过元素ID定位,含有该属性的所有元素

Args:

  • id_ - Id of child element to find.

用法:

driver. find_elements_by_id(“id”)

(49) find_element_by_name

find_element_by_name(self, name):

Finds element within this element's children by name.

通过元素Name定位(元素的名称属性text).
Args:

  • name - name property of the element to find.

用法:
driver.find_element_by_name(“name”)

(50) find_elements_by_name

find_elements_by_name(self, name):

Finds a list of elements within this element's children by name.

通过元素Name定位(元素的名称属性text),含有该属性的所有元素.
Args:

  • name - name property to search for.

用法:
driver.find_element_by_name(“name”)

(51) find_element_by_link_text

find_element_by_link_text(self, link_text):

Finds element within this element's children by visible link text.

通过元素可见链接文本定位.
Args:

  • link_text - Link text string to search for.

用法:
driver.find_element_by_link_text(“text”)

(52) find_elements_by_link_text

find_element_by_link_text(self, link_text):

Finds a list of elements within this element's children by visible link text.
通过元素可见链接文本定位,含有该属性的所有元素.
Args:

  • link_text - Link text string to search for.

用法:
driver.find_elements_by_link_text(“text”)

(53) find_element_by_partial_link_text

find_element_by_partial_link_text(self, link_text):

Finds element within this element's children by partially visible link text.

通过元素部分可见链接文本定位.
Args:

  • link_text - Link text string to search for.

driver. find_element_by_partial_link_text(“text”)

(54) find_elements_by_partial_link_text

find_elements_by_partial_link_text(self, link_text):

Finds a list of elements within this element's children by link text.

通过元素部分可见链接文本定位,含有该属性的所有元素.
Args:

  • link_text - Link text string to search for.

driver. find_elements_by_partial_link_text(“text”)

(55) find_element_by_tag_name

find_element_by_tag_name(self, name):
Finds element within this element's children by tag name.

通过查找html的标签名称定位元素

Args:

  • name - name of html tag (eg: h1, a, span)

用法:

driver.find_element_by_tag_name(“name”)

(56) find_elements_by_tag_name

find_elements_by_tag_name(self, name):

Finds a list of elements within this element's children by tag name.
通过查找html的标签名称定位所有元素

Args:

  • name - name of html tag (eg: h1, a, span).

用法:
driver.find_elements_by_tag_name(“name”)

(57) find_element_by_xpath

find_element_by_xpath(self, xpath):

Finds element by xpath.

通过Xpath定位元素,详细方法可参阅http://www.w3school.com.cn/xpath/
Args:
xpath - xpath of element to locate. "//input[@class='myelement']"
Note: The base path will be relative to this element's location.
This will select the first link under this element.
myelement.find_elements_by_xpath(".//a")
However, this will select the first link on the page.
myelement.find_elements_by_xpath("//a")

用法 find_element_by_xpath(“//*”)

(58) find_elements_by_xpath

find_elements_by_xpath(self, xpath):
Finds elements within the element by xpath.

Args:

  • xpath - xpath locator string.

Note: The base path will be relative to this element's location.

This will select all links under this element.

myelement.find_elements_by_xpath(".//a").
However, this will select all links in the page itself.

myelement.find_elements_by_xpath("//a").

用法:

find_elements_by_xpath(“//*”)

(59) find_element_by_class_name

find_element_by_class_name(self, name):

Finds element within this element's children by class name.

通过元素class name属性定位元素.

Args:

  • name - class name to search for.

用法:

driver. find_element_by_class_name(“android.widget.LinearLayout”)

(60) find_elements_by_class_name

find_elements_by_class_name(self, name):

Finds a list of elements within this element's children by class name.

通过元素class name属性定位所有含有该属性的元素.
Args:

  • name - class name to search for.

用法:

driver. find_elements_by_class_name(“android.widget.LinearLayout”).

(61) find_element_by_css_selector

find_element_by_css_selector(self, css_selector):

Finds element within this element's children by CSS selector.

通过CSS选择器定位元素.
Args:

  • css_selector - CSS selctor string, ex: 'a.nav#home'
(62) send_keys

send_keys(self, *value):

Simulates typing into the element.

在元素中模拟输入(开启appium自带的输入法并配置了appium输入法后,可以输入中英文).
Args:

  • value - A string for typing, or setting form fields. For setting file inputs, this could be a local file path.Use this to send simple key events or to fill out form fields:
    form_textfield = driver.find_element_by_name('username')
    form_textfield.send_keys("admin")
    This can also be used to set file inputs.
    file_input = driver.find_element_by_name('profilePic')
    file_input.send_keys("path/to/profilepic.gif")
    # Generally it's better to wrap the file path in one of the methods
    # in os.path to return the actual path to support cross OS testing.
    # file_input.send_keys(os.path.abspath("path/to/profilepic.gif"))
    driver.element.send_keys(“中英”)
(63) is_displayed

is_displayed(self):

Whether the element is visible to a user.

此元素用户是否可见。简单地说就是隐藏元素和被控件挡住无法操作的元素(仅限 Selenium,appium是否实现了类似功能不是太确定)这一项都会返回 False.
用法:

driver.element.is_displayed()

(64) location_once_scrolled_into_view

location_once_scrolled_into_view(self):

"""THIS PROPERTY MAY CHANGE WITHOUT WARNING. Use this to discover. where on the screen an element is so that we can click it. This method should cause the element to be scrolled into view.Returns the top lefthand corner location on the screen, or None if the element is not visible.

暂不知道用法

(65) size

size(self):

The size of the element.

获取元素的大小(高和宽).

new_size["height"] = size["height"]

new_size["width"] = size["width"]

用法:

driver.element.size

(66) value_of_css_property

value_of_css_property(self, property_name):

The value of a CSS property.

CSS属性

用法 暂不知

(67) location

location(self):

The location of the element in the renderable canvas.

获取元素左上角的坐标

用法:

driver.element.location

返回element的x坐标, int类型

driver.element.location.get('x')

返回element的y坐标, int类型

driver.element.location.get('y')

(68) rect

rect(self):

A dictionary with the size and location of the element.

元素的大小和位置的字典

(69) screenshot_as_base64

screenshot_as_base64(self):

Gets the screenshot of the current element as a base64 encoded string.

获取当前元素的截图为Base64编码的字符串

Usage:

img_b64 = element.screenshot_as_base64

(70) execute_script

execute_script(self, script, *args):

Synchronously Executes JavaScript in the current window/frame.

在当前窗口/框架(特指 Html 的 iframe )同步执行 javascript 代码。你可以理解为如果这段代码是睡眠5秒,这五秒内主线程的 javascript 不会执行

Args:

  • script: The JavaScript to execute.
  • *args: Any applicable arguments for your JavaScript.
    Usage:
    driver.execute_script('document.title')
(71) execute_async_script

execute_async_script(self, script, *args):

Asynchronously Executes JavaScript in the current window/frame.

插入 javascript 代码,只是这个是异步的,也就是如果你的代码是睡眠5秒,那么你只是自己在睡,页面的其他 javascript 代码还是照常执行

Args:

  • script: The JavaScript to execute.
  • *args: Any applicable arguments for your JavaScript.

Usage:

driver.execute_async_script('document.title')

(72) current_url

current_url(self):

Gets the URL of the current page.

获取当前页面的网址。

Usage:

driver.current_url
用法

driver.current_url

(73) page_source

page_source(self):

Gets the source of the current page.

获取当前页面的源

Usage:

driver.page_source

(74) close

close(self):
Closes the current window.

关闭当前窗口

Usage:

driver.close()

(75) quit

quit(self):

Quits the driver and closes every associated window.

退出脚本运行并关闭每个相关的窗口连接

Usage:

driver.quit()

参考资料:

打造心目中理想的自动化测试框(AppiumBooster)

从0到1搭建移动App功能自动化测试平台(1):模拟器中运行iOS应用  

Python-Client的github文档地址