【备档】客户端自动化(主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中的强大功能. ...
随机推荐
- 借root之名,行流氓之实,劝告,root需谨慎
20160425++++++ 今日再回头看这篇文章,貌似有点偏激了一点,不过xda论坛上有个疑似kingroot开发团队的用户说明了kingroot确实对supersu做了限制,说是supersu在替 ...
- MySQL从删库到跑路_高级(四)——存储过程
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.存储过程简介 1.存储过程简介 存储过程是一组具有特定功能的SQl语句集组成的可编程的函数,经编译创建并保存在数 ...
- wkhtmtopdf--高分辨率HTML转PDF(二)
命令行 wkhtmtopdf有一些很实用的命令,平时如果不用代码,可以直接使用命令行来把你喜欢的任意网页转换为PDF, 命令行参考网址:http://madalgo.au.dk/~jakobt/wkh ...
- python selenium第一个WebDriver脚本
#coding=utf-8from selenium import webdriverimport timeimport osos.environ["webdriver.firefox.dr ...
- JS实现仿腾讯微博无刷新删除微博效果代码
这里演示JS仿腾讯微博无刷新删除效果,将显示在微博列表里的内容删除,运用AJAX技术,无刷新删除微博的内容,参考性强,希望对初学AJAX的朋友有所帮助. 在线演示地址如下: http://demo.j ...
- AtCoder Beginner Contest 086 D - Checker
Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement AtCoDeer is thinking o ...
- IP分片丢失重传
尽管IP分片看起来是是透明的,但有一点让人不想使用它:即使只丢失一片数据也要重传整个数据报.为什么会发生这种情况呢? 因为IP层本身没有超时重传的机制——由更高层来负责超时和重传(TCP有超时 ...
- 手撕vue-cli配置——webpack.base.conf.js篇
在开始写webpack.base.conf.js(简称base)之前,我们先来看一下vue-loader.conf.js这个文件,毕竟在base中我们还会用到: 'use strict' //引入前一 ...
- 20165211 获奖感想及java课程总结
20165211 获奖感想及java课程总结 理论脱离实践是最大的不幸.--达芬奇 这句话,是我在学习Java之前,假期内写的20165211 学习基础和C语言调查里的所引用的一句话,是当时我对Jav ...
- 0x30、0x37
1.write_date(0x30+shi)加0x30是什么意思 答: 将数字0-9转化为字符'0'-'9' 1.write_date(0x37+bai)加0x37是什么意思 答: 将大于9的数字转化 ...