【备档】客户端自动化(主Android Appium + python
之前做分享写的文档,备档~
0.移动客户端自动化简介
客户端自动化测试的本质
定位对象 · 操作对象 · 校验对象
对象的定位应该是自动化测试的核心,要想操作、校验一个对象,首先应该识别这个对象。
一个对象具有特定的属性,譬如:文字、类型、位置等等。我们可以通过这些属性找到这对象。
移动客户端自动化测试常见框架
Android
- Monkey
- Monkeyrunner
- UIautomator
- Robotium
iOS
- UIAutomation
通用
- Appium
- Calabash
...
框架选择
- 支持平台,系统版本
- 是否需要源码
- 脚本语言
- 是否支持webview
...
浅谈移动端自动化测试框架和工具
http://blog.csdn.net/meyoung01/article/details/40076511
iOS自动化测试框架对比
http://www.jianshu.com/p/047035416095
1.Appium 思想·原理·环境搭建
Appium 思想
架构原理
- 左边的WebDriver script是我们的selenium测试脚本
- 中间是起的Appium的服务,Appium在这边起了一个Server,Appium Server接收webdriver 标准请求,解析请求内容,调⽤用对应的框架响应操作。如:脚本发送一个点击按钮的请求给appium server
- Appium server会把请求转发给中间件Bootstrap.jar ,它是用java写的,安装在手机上.Bootstrap 接收appium 的命令,最终通过调⽤用UiAutomator的命令来实现
- 最后执⾏行的结果由Bootstrap返回给Appium server
Appium环境搭建python篇(mac系统)
安装时使用VPN可能比淘宝源成功率更高~
2.定位对象 · 操作对象 · 校验对象
定位对象-Android
工具
UiAutomatorview (4.1下版本不支持)
启动方法
➜ ~ uiautomatorviewer
定位方法
查找客户端页面元素方法
以下是Appium给出的所有方法(但不一定支持!)
查找页面中存在的单个元素
|
查找页面中存在多个元素(返回数组)
|
查找方法
|
---|---|---|
find_element |
find_elements |
def find_element(self, by=By.ID, value=None) 被其他find_element方法调用 |
find_element_by_accessibility_id | find_elements_by_accessibility_id |
Accessibility ID在Android上面就等同于contentDescription,这个属性是方便一些生理功能有缺陷的人使用应用程序的。 UiAutomatorview中content-desc |
find_element_by_android_uiautomator | find_elements_by_android_uiautomator | 使用android_uiautomator表达 |
find_element_by_class_name | find_elements_by_class_name | UiAutomatorview中class |
find_element_by_id | find_elements_by_id | UiAutomatorview中resource-id |
find_element_by_ios_uiautomation | find_elements_by_ios_uiautomation | - |
find_element_by_link_text | find_elements_by_link_text | UiAutomatorview中text |
find_element_by_name | find_elements_by_name | Appium 1.5 版本已经被废除 |
find_element_by_partial_link_text | find_elements_by_partial_link_text |
UiAutomatorview中text,可以匹配部分文字 譬如:美食(XX家) |
find_element_by_tag_name | find_elements_by_tag_name | Appium 1.0 版本已经被废除 |
find_element_by_xpath | find_elements_by_xpath | xpath,强烈不推荐 |
find_element_by_android_uiautomator() 举栗子
def autotest_find_name_by_uiautomator(self, name):
return self.driver.find_element_by_android_uiautomator('new UiSelector().text("%s")' % name)
find_element_by_android_uiautomator()中的字符串为Uiautomator的写法,主要有以下几种方法:
new UiSelector().text("%s")
new UiSelector().textContains("%s")
new UiSelector().className("%s")
new UiSelector().resourceId("%s")
textContains类似于find_element_by_partial_link_text,可以做部分文字匹配
操作对象
以下是常用的方法,更多的方法可以通过源码或提示获得
tips:某些方法可能在特定系统不支持
# 点击对象
.click() # 文本框输入文字
.send_keys("%s")
#获取控件文字
.text # 从(startx,starty)滑到(endx,endy),分duration步滑,每一步用时是5毫秒。
driver.swipe(int startx, int starty, int endx, int endy, int duration) # 按手机固定键,key值定义在AndroidKeyCode类中
# keycode http://blog.csdn.net/crisschan/article/details/50419963
driver.send_key_event(int key) # 获取当前的activity
driver.current_activity() # 等待指定的activity出现,interval为扫描间隔1秒
driver.wait_activity(activity, timeout, interval=1) ...
校验对象
在Python环境下,Appium 官方推荐使用unittest来维护测试用例,unittest提供了多种assert方法,我们可以通过这些方法来做校验。
unittest中常用的assert语句
http://www.cnblogs.com/paulwinflo/p/5742142.html
校验方式
- 校验控件是否展示
- 校验控件中的数据(文本)是否正确
- 图片对比
- ...
代码实现
校验元素非空
def assert_element_exist_by_x(self, how, what, msg=None):
"""
通过*方法验证元素非空
:param how:find_element_by_* methods
(By.CLASS_NAME/By.TAG_NAME/By.NAME/By.PARTIAL_LINK_TEXT/By.NAME/By.XPATH/By.ID)
:param what:
:param msg:
"""
try:
if how ==By.NAME:
self.assertIsNotNone(self.autotest_find_name_by_uiautomator(what), msg)
else:
self.assertIsNotNone(self.driver.find_element(by=how, value=what), msg)
return True
except Exception:
print "xxxxx"
3.用例编写
官方栗子
import os
import unittest
from appium import webdriver
from time import sleep # Returns abs path relative to this file and not cwd
PATH = lambda p: os.path.abspath(
os.path.join(os.path.dirname(__file__), p)
) class ContactsAndroidTests(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '4.2'
desired_caps['deviceName'] = 'Android Emulator'
desired_caps['app'] = PATH(
'../../../sample-code/apps/ContactManager/ContactManager.apk'
)
desired_caps['appPackage'] = 'com.example.android.contactmanager'
desired_caps['appActivity'] = '.ContactManager' self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) def tearDown(self):
self.driver.quit() def test_add_contacts(self):
el = self.driver.find_element_by_accessibility_id("Add Contact")
el.click() textfields = self.driver.find_elements_by_class_name("android.widget.EditText")
textfields[0].send_keys("Appium User")
textfields[2].send_keys("someone@appium.io") self.assertEqual('Appium User', textfields[0].text)
self.assertEqual('someone@appium.io', textfields[2].text) self.driver.find_element_by_accessibility_id("Save").click() # for some reason "save" breaks things
alert = self.driver.switch_to_alert() # no way to handle alerts in Android
self.driver.find_element_by_android_uiautomator('new UiSelector().clickable(true)').click() self.driver.press_keycode(3) if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(ContactsAndroidTests)
unittest.TextTestRunner(verbosity=2).run(suite)
setup
在Appium中所有动作的前提是要启动一个session,启动方法就是
http://127.0.0.1:4723/wd/hub/session
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
其中desired_caps是配置信息,它告诉server 本次测试的具体内容,譬如:
- 本次测试是启动浏览器还是启动移动设备?
- 是启动andorid还是启动ios?
- 启动android时,app的package是什么?
- 启动android时,app的activity是什么?
必要的desired_caps参数
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '4.2'
desired_caps['deviceName'] = '022MWW146T007732'
desired_caps['app'] = 'XXX.apk'
- platformName:使用哪种移动平台。iOS, Android, orFirefoxOS?
- deviceName:启动哪种设备,是真机还是模拟器?iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android Emulator, Galaxy S4, etc...
- app:应用的绝对路径,注意一定是绝对路径。如果指定了appPackage和appActivity的话,这个属性是可以不设置的。另外这个属性和browserName属性是冲突的。
- automationName:使用哪种自动化引擎。appium(默认)还是Selendroid?
- appActivity:待测试的app的Activity名字。比如MainActivity, .Settings。注意,原生app的话要在activity前加个"."。
- appPackage:待测试的app的java package。比如com.example.android.myApp, com.android.settings。
teardown
self.driver.quit()
4.其他
- Android 获取当前Activity、包名方法
adb shell dumpsys activity | grep "mFocusedActivity"
adb shell pm list package
- 元素定位不到/没有id的方法
麻烦开发增加特有、不重复的id
【备档】客户端自动化(主Android Appium + python的更多相关文章
- APP H5 混合自动化使用说明 [基于 Appium+Python 系列]
背景 前几天接到H5开发人员那边的业务开发需求单,说想将H5接入到自动化系列中,特此记录分享一下. 环境前置准备 手机与电脑USB连接,开启USB调试模式,通过adb devices可查看到此设备. ...
- Android+appium +python 点击坐标tap方法的封装
当常使用的查找点击元素的方法name.id.classname等无法使用时,我们将会采取坐标的点击来实现操作,同样存在一个问题,当手机的分辨率.屏幕大小不一致时,坐标的定位也会不同,因此将采用相对坐标 ...
- Appium+python自动化27-等待activity出现(android特有的wait_activity)
前言 在启动app的时候,如果直接做下一步点击操作,经常会报错,于是我们会在启动完成的时候加sleep. 那么问题来了,这个sleep时间到底设置多少合适呢?设置长了,就浪费时间,设置短了,就会找不到 ...
- Appium+Python自动化 1 环境搭建(适用windows系统-Android移动端自动化)
一.安装并配置 java jdk ①下载 java jdk后 安装,安装完成后,配置环境变量 打开计算机->系统属性->高级系统设置->环境变量->新建(系统变量),如图所示: ...
- Appium 教您完美win10安装Appium1.7.2支持win客户端自动化
参考内容: https://testerhome.com/topics/10193https://testerhome.com/topics/8223https://testerhome.com/to ...
- Appium+python自动化(十三)- 与Capability完美懈垢之解读(超详解)
简介 Capability又叫Appium Desired Capabilities,前边写了那么多实例代码,小伙伴可以发现一些规律,就是有一部分代码总是重复的出现在你的视线中.这部分就是对Capab ...
- appium+python+Windows自动化测试文档
appium+python自动化测试文档 一.认识appium 1. 什么是appium appium是开源的移动端自动化测试框架: appium可以测试原生的.混合的.以及移动端的web项目: ...
- 移动端自动化自动化(Android&iOS)——Appium
Appium-Python 移动端自动化环境搭建 Appium介绍 Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持iOS.Android及Firefox ...
- Appium+python自动化22-Appium Desktop
Appium Desktop 原滋原味的官方文档 Appium Desktop是一款用于Mac.Windows和Linux的开源应用,它提供了Appium自动化服务器在一个漂亮灵活的UI中的强大功能. ...
随机推荐
- 人生苦短之我用Python篇(socket编程)
socket模块 实现简单的远程连接: 客户端: import socket client = socket.socket()#声明socket类型,同时生成socke连接t对象 client.con ...
- 改变 select下拉框 样式
select{ outline: none; text-indent: 10px; height: 45px; line-height: 45px; width: 100%; border:1px s ...
- cf428c 模拟题
这题说的是给了 n个数然后又 k次 的交换任意位置的 数字的机会 计算最长的连续子序列的和 这要撸 模拟整个 过程 并不能就是算最长的递增序列 如果只是 找最长的 和序列的 话 会存在 很多问题 ...
- readyState与status
XMLHttpRequest对象(Ajax)的状态码(readystate) 当一个XMLHttpRequest初次创建时,这个属性的值是从0开始,知道接收完整的HTTP响应,这个值增加到4.有五种状 ...
- 使用IP连接SQL SERVER或者配置为连接字符串失败
使用IP连接SQL SERVER或者配置为连接字符串失败 情景一:当在webconfig文件中使用 <add key="ConnectionString" value=& ...
- Linux基础命令---which
which 在环境变量PATH中搜索某个命令,返回命令的执行文件或者脚本位置,默认只显示第一个结果.这需要一个或多个参数.对于它的每个参数,它会打印出当在shell提示符下输入该参数时将执行的可执行文 ...
- schema与catalog的理解
sql环境中Catalog和Schema都属于抽象概念,主要用来解决命名冲突问题.一个数据库系统包含多个Catalog,每个Catalog包含多个Schema,每个Schema包含多个数据库对象(表. ...
- 2018年星际争霸AI挑战赛–三星与FB获冠亚军,中科院自动化所夺得季军
雷锋网 AI 科技评论消息,2018 年 11 月 13-17 日,AAAI 人工智能与交互式数字娱乐大会 (AI for Interactive Digital Entertainment) 在阿尔 ...
- UVA10298 Power Strings
UVA10298 Power Strings hash+乘法逆元+一点点数学知识 我们用取余法算出主串的hash,然后从小到大枚举子串的长度 显然,如果若干个子串的复制的hash值之和等于主串的has ...
- luogu P1880石子归并
石子归并 luogu1880 传送门 noi1995 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得 ...