之前做分享写的文档,备档~

0.移动客户端自动化简介

客户端自动化测试的本质

定位对象 · 操作对象 · 校验对象

对象的定位应该是自动化测试的核心,要想操作、校验一个对象,首先应该识别这个对象。

一个对象具有特定的属性,譬如:文字、类型、位置等等。我们可以通过这些属性找到这对象。

移动客户端自动化测试常见框架

Android

  1. Monkey
  2. Monkeyrunner
  3. UIautomator
  4. Robotium

iOS

  1. UIAutomation

通用

  1. Appium
  2. Calabash
    ...

框架选择

  1. 支持平台,系统版本
  2. 是否需要源码
  3. 脚本语言
  4. 是否支持webview
    ...

浅谈移动端自动化测试框架和工具

http://blog.csdn.net/meyoung01/article/details/40076511

iOS自动化测试框架对比

http://www.jianshu.com/p/047035416095

1.Appium 思想·原理·环境搭建

Appium 思想

你无需为了自动化,而重新编译或者修改你的应用。
你不必局限于某种语言或者框架来写和运行测试脚本。
  →Appium 真正的工作引擎其实是第三方自动化框架
  →把这些第三方框架封装成一套 API,WebDriver API.WebDriver(也就是 “Selenium WebDriver") 指定了客户端到服务端的协议。
  →Selenium 是web自动化测试工具集,核心是RC(selenium 1.0)和WebDriver(selenium 2.0)
  →RC和WebDriver 定义客户端脚本与浏览器交互的协议。以及元素定位与操作的接口。
   
一个移动自动化的框架不应该在接口上重复造轮子。
   →WebDriver 已经成为 web 浏览器自动化的标准,也成了 W3C 的标准 —— W3C Working Draft,并扩充了WebDriver 的协议,在原有的基础上添加移动自动化相关的 API 方法
无论是精神上,还是名义上,都必须开源。 

架构原理

  • 左边的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的更多相关文章

  1. APP H5 混合自动化使用说明 [基于 Appium+Python 系列]

    背景 前几天接到H5开发人员那边的业务开发需求单,说想将H5接入到自动化系列中,特此记录分享一下. 环境前置准备 手机与电脑USB连接,开启USB调试模式,通过adb devices可查看到此设备. ...

  2. Android+appium +python 点击坐标tap方法的封装

    当常使用的查找点击元素的方法name.id.classname等无法使用时,我们将会采取坐标的点击来实现操作,同样存在一个问题,当手机的分辨率.屏幕大小不一致时,坐标的定位也会不同,因此将采用相对坐标 ...

  3. Appium+python自动化27-等待activity出现(android特有的wait_activity)

    前言 在启动app的时候,如果直接做下一步点击操作,经常会报错,于是我们会在启动完成的时候加sleep. 那么问题来了,这个sleep时间到底设置多少合适呢?设置长了,就浪费时间,设置短了,就会找不到 ...

  4. Appium+Python自动化 1 环境搭建(适用windows系统-Android移动端自动化)

    一.安装并配置 java jdk ①下载 java jdk后 安装,安装完成后,配置环境变量 打开计算机->系统属性->高级系统设置->环境变量->新建(系统变量),如图所示: ...

  5. Appium 教您完美win10安装Appium1.7.2支持win客户端自动化

    参考内容: https://testerhome.com/topics/10193https://testerhome.com/topics/8223https://testerhome.com/to ...

  6. Appium+python自动化(十三)- 与Capability完美懈垢之解读(超详解)

    简介 Capability又叫Appium Desired Capabilities,前边写了那么多实例代码,小伙伴可以发现一些规律,就是有一部分代码总是重复的出现在你的视线中.这部分就是对Capab ...

  7. appium+python+Windows自动化测试文档

    appium+python自动化测试文档 一.认识appium 1.    什么是appium appium是开源的移动端自动化测试框架: appium可以测试原生的.混合的.以及移动端的web项目: ...

  8. 移动端自动化自动化(Android&iOS)——Appium

    Appium-Python 移动端自动化环境搭建 Appium介绍 Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持iOS.Android及Firefox ...

  9. Appium+python自动化22-Appium Desktop

    Appium Desktop 原滋原味的官方文档 Appium Desktop是一款用于Mac.Windows和Linux的开源应用,它提供了Appium自动化服务器在一个漂亮灵活的UI中的强大功能. ...

随机推荐

  1. 使用点击二分图传导计算query-document的相关性

    之前的博客中已经介绍了Ranking Relevance的一些基本情况(Click Behavior,和Text Match):http://www.cnblogs.com/bentuwuying/p ...

  2. Linux服务器---设置服务启动

    设置服务开关 用户可以设置某项服务开机启动或者关闭,有图形界面和命令两种方式 1.图形界面 1)在终端输入命令setup,在弹出的界面选择“系统服务” 2)也可以直接在终端输入命令“ntsysv”,得 ...

  3. SQL学习之SQL注入总结

    Sql注入定义: 就是通过把sql命令插入到web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行的sql命令的目的. sql注入分类: 基于联合查询 基于错误回显 基于盲注,分时间盲 ...

  4. 深入JAVA注解之方法注解

    以获取数据库连接为例,建立maven项目 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...

  5. c++ sleep(windows/linux)

    c标准中包含了一个sleep用以实现当前线程暂停执行n毫秒,如下所示: 函数名: sleep 功 能: 执行挂起一段时间 用 法: unsigned sleep(unsigned seconds); ...

  6. centos/rhel 6.5(更新至centos 7)下rabbitmq安装(最简单方便的方式)

    vim /etc/hosts 增加 127.0.0.1 hostname 不然启动的时候可能会报如下错误: [root@devel2 rabbitmq]# rabbitmq-server ERROR: ...

  7. HTML 和 JavaScript 编写简单的 404 界面

    编写简单的 404 界面,也可以用来做 500 报错界面,还会飘东西,特别好,蛮漂亮的! <!DOCTYPE html> <html> <head> <met ...

  8. UVa 1471 Defense Lines - 线段树 - 离散化

    题意是说给一个序列,删掉其中一段连续的子序列(貌似可以为空),使得新的序列中最长的连续递增子序列最长. 网上似乎最多的做法是二分查找优化,然而不会,只会值域线段树和离散化... 先预处理出所有的点所能 ...

  9. 重写(override)与重载(overload)的区别

    一.重写(override) override是重写(覆盖)了一个方法,以实现不同的功能.一般是用于子类在继承父类时,重写(重新实现)父类中的方法. 重写(覆盖)的规则: 1.重写方法的参数列表必须完 ...

  10. Linux虚拟内存和物理地址的理解【转】

    本文转载自:http://blog.csdn.net/dlutbrucezhang/article/details/9058583 在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中.这 ...