在安装好并且调试通的情况下,可以开始使用appium做一些测试了
一般来说在使用python+appium时,还要同时用到adb和Uiautomatorviewer
官方文档在testhome中有翻译版:https://www.kancloud.cn/testerhome/appium_docs_cn
1.首先写好前置代码,示例一段完整的简单代码
1 from appium import webdriver 2 from time import sleep 3 4 #关于手机配置信息 5 desires_caps = {} 6 desires_caps['platformName'] = 'Android' 7 desires_caps['platformVersion'] = '10' 8 desires_caps['deviceName'] = '3EP0219129006133' 9 desires_caps['appPackage'] = 'com.android.settings' 10 desires_caps['appActivity'] = 'com.android.settings.HWSettings' 11 12 #驱动 13 driver = webdriver.Remote('http://localhost:4723/wd/hub',desires_caps) 14 15 #设置静止时间,使现象更明显 16 sleep(5) 17 #退出 18 driver.quit()
其中关于手机配置的代码就是前置代码,也成关键字,下方内容来自https://anikikun.gitbooks.io/appium-girls-tutorial/content/desired_caps.html
关键字 | 描述 | 实例 |
---|---|---|
platformName | 手机操作系统 | iOS,Android,FirefoxOS |
platformVersion | 手机操作系统版本 | 例如: 7.1, 4.4 |
deviceName | 手机类型或模拟器类型 | iPhone Simulator, iPad Simulator, Android Emulator, Galaxy S4等。在 iOS 上,这个关键字的值必须是使用 instruments -s devices 得到的可使用的设备名称之一。在 Android 上,这个关键字目前不起作用。 |
app | .ipa 或者 .apk(也可以使是包含他们的zip)文件所在的本地绝对路径或者远程路径 | Appium会先尝试安装路径对应的应用在适当的真机或模拟器上。针对Android系统,如果你指定app-package和app-activity(具体见下面)的话,那么就可以不指定app。 |
browserName | 需要进行自动化测试的手机 web 浏览器名称。如果是对应用进行自动化测试,这个关键字的值应为空。 | iOS 系统上可以用 ‘Safari‘ ,Android 系统上可以用 ‘Chrome‘, ‘Chromium‘, 或 ‘Browser‘。 |
automationName | 自动化测试引擎 | Appium,Selendroid |
appActivity | 要从应用包中启动的 Android Activity 名称。 | 它通常需要在前面添加 . (如:使用.MainActivity 而不是 MainActivity) MainActivity, .Settings |
appPackage | 你想运行的Android应用的包名 | 比如com.example.android.myApp |
appWaitActivity | 你想要等待启动的 Android Activity 名称 | SplashActivity |
unicodeKeyboard | 是否在测试过程中切换到能支持多国语言输入的输入法 | true 表示是,false 表示否(如果send_keys传入的有中文内容需要配置此项) |
resetKeyboard | 是否在测试完成后自动切换回原有输入法 | true 表示是,false 表示否(如果send_keys传入的有中文内容需要配置此项) |
如果输入无法唤起,可以在系统设置--语言和输入法--把当前的输入法替换为系统输入法或其他输入法
补充:
newCommandTimeout | 用于客户端在退出或者结束session之前,appium等待客户端发送一条新命令所花费的时间(秒为单位) | 例如:60 |
language | (Sim/Emu-only)为模拟器设置语言 | 如 fr |
locale | (Sim/Emu-only)为模拟器设置所在区域 | 如 fr_ca |
udid | 连接真机的唯一设备号 | 需要先用adb devices查找一下 |
orientation | (Sim/Emu-only)为模拟器当前的方向 | 竖屏或者是横屏 |
autoWebview | 直接转到Webview上下文(context),默认值为false | true,false |
noReset | 在当前session下不会重置应用的状态,默认值为false | true,false |
fullReset |
(ios)删除所有的模拟器文件夹。(Android)要清除app里的数据请将应用卸载才能达到重置应用的效果 在安卓里,session完成之后也会将应用卸载掉,默认值为false |
true,false |
IOS独有的:
calendarFormat | (仅支持模拟器)为I0S的模拟器设置日历格式 | 例如 gregorian |
bundleId | 被测应用的bundle ID.用于在真实设备中启动测试,也用于使用其他需要bundle ID的关键字启动测试 ,在使用bundieID在真实设备上执行测试时,你可以不提供pp关键字,但你必须提供udid. |
例如 io.appium.TestApp |
udid | 连接真实设备的唯一设备编号 | |
launchTimeout | 以毫秒为单位,在appium运行失败之前设置一个等待instruments的等待时间 | 例如20000 |
locationServicesEnabled | (仅支持模拟器)强制打开或关闭定位服务,默认值是保持当前模拟器的设定 | true,false |
locationServicesAuthorized |
(仅支持模拟器)通过修改plist文件设定是否允许应用定位服务,从而避免定位服务的警告出现,默认值是保持当前模拟器的设定, 注意使用这个关键字时,需要使用bundle ID关键字来发送你的应用的bundle ID |
true,false |
autoAcceptAlerts |
当弹出警告时,都会自动去点接受,包括隐私访问权限的警告(例如定位,联系人,照片) 默认值为false,不支持基于XCUITest的测试 |
true,false |
autoDismissAlerts |
当弹出警告时,都会自动去点取消,包括隐私访问权限的警告(例如定位,联系人,照片) 默认值为false,不支持基于XCUITest的测试 |
true,false |
2.查看appPackage和appActivity的方法
在命令行输入adb shell dumpsys window | findstr mCurrent,如图
得到的结果中/前的是报名,/之后的是活动的进程名
设备的名称则是通过adb devices得到的
3.关于元素的定位,要和UiautomatorViewer搭配使用
只能获取到屏幕内的内容,滚动可见的不能获取到
定位一个元素,有三种方法
1 """通过id定位元素""" 2 #查找uiautomator的resource-id,确定id_value,语句执行完返回值是定位到的单个元素 3 driver.find_element_by_id(id_value) 4 5 """通过class_name定位一个元素""" 6 #查找uiautomator的class_name,确定class_value,语句执行完返回值是定位到的单个元素 7 driver.find_element_by_class_name(class_value) 8 9 """通过xpath定位一个元素""" 10 #查找uiautomator的特征值,可以是id或classname或文本内容等,确定xpath_value,语句执行完返回值是定位到的单个元素 11 driver.find_element_by_xpath(xpath_value)
定位到元素之后,可以进行点击,输入文本,清除内容,方法和selenium相同(即click,send_keys,clear)
xpath_value的表示,也有三种方法
(1).resource_id = xxxxx
(2).class = xxxxx
(3).//*[@content-desc='xxxxx']
用class_name的方法找到的元素可能不止一个,所以定位时尽量用id或者xpath,确保不会有重复情况的出现
定位一组元素,同样的三种方法,不过用的是find_elements_by......返回值是一个列表,这样可以批量获取具有某种特征的元素。
注意:
用find_element_by......传入一个不存在的特征,会报错Nosuchelementexception的错误
用find_elements_by......传入一个不存在的特征,不会报错,但返回的列表是空的。
如果要定位的文本内容是中文,尽量不要用文本内容定位,虽然保证的特征的独一性,但中文有不能被读取到的可能。
实在找不到独一性的特征情况下,可以考虑用坐标点的方式定位。
4.如果在输入框中输入中文,默认无效但不会报错
需要在前值代码中增加两个参数
desired_caps['unicodeKeyboard'] = Ture
desired_caps['resetKeyboard'] = Ture
5.关于寻找元素时的等待时长
场景:由于网速/服务器/配置出现故障或延迟,想要定位的元素没有立即显示出来,代码就已执行,会提示未找到该元素。
解决:使定位元素的代码在一定时间内重复、多次的尝试寻找
具体方法:元素显式等待/元素隐式等待
元素显式等待:
应用场景:针对所有定位元素的超时时间设置为不同值的时候
使用:①导入包;②创建webdriverwait对象;③调用webdriverwait对象的until方法
示例:
1 """示例:在5s钟内,每1s在 '设置' 中的 '返回' 按钮,如果找到则点击,如果找不到则观察对应错误信息""" 2 3 from selenium.webdriver.support.wait import WebDriverWait 4 5 # 6 配置手机参数 7 # 8 9 #创建等待对象(5是等待时长,poll_frequency是每多少秒找一次) 10 wait = WebDriverWait(driver,5,poll_frequency=1) 11 12 #获取元素并设置超时时间和频率 13 search_button = wait.until(lambda x: x.find_element_by_xpath("//*[contains(@content-desc,'收起')]")) 14 15 #点击搜索按钮 16 search_buttom.click()
元素隐式等待:
场景:针对所有定位元素的超时时间设置为同一个值的时候
使用:driver.implicitly_wait(时长),在指定时长内出现,就进行下一步操作,未出现就报错
两者的区别:显式等待对单个元素有效,灵活性高;隐式等待作用对象是全局元素,设置简单。
补充:
appium-desktop界面介绍:
如图所示是appium-desktop的界面: