使用Appium进行自动化测试
Appium简介
-
Appium是一个开源测试自动化框架,可用于原生,混合和移动Web应用程序测试。
它使用WebDriver协议驱动iOS,Android和Windows应用程序。 -
appium通过对布局的检测实现控件点击/滑动/输入等事件,因此需要定位控件位置非常精确,否则就会停止工作。
-
支持多种语言,java、python、php、Ruby等等
-
如果你有selenium经验,直接上手
-
我们的电脑(client)上运行自动化测试脚本,调用的是webdriver的接口,appium server接收到我们client上发送过来的命令后他会将这些命令转换为UIautomator认识的命令,然后由UIautomator来在设备上执行自动化,由客户端(Appium Client)和服务器(Appium Server)两部分组成,客户端与服务器端通过JSON Wire Protocol进行通信。
为什么使用appium
在进行UI功能测试时,经常需要对某个test case重复进行以复现某个bug或检测功能是否稳定,一个test case通常包含某几个固定的点击/滑动/输入事件,如果使用自动化测试控制手机模拟test case中的操作,那么应该可以减少工作量。
缺陷
-
自动化测试的最大弊端是沒有应对措施,appium可以重复进行操作,但是缺少灵活性,人为操作时可以进行精细化的控制,比如输入不同的文字/在等待的同时进行其他操作等等,因此appium只适合固定重复操作的场景。
-
appium对手机的控制使用的是python脚本,因此需要再次开发。
安装及配置环境
环境依赖
- Node.js
- Appium
- Appium-desktop
- Appium-doctor
- Appium-Python-Client
- Python
- JDK
- Andriod SDK
安装Node.js
下载地址:https://nodejs.org/en/download/releases/
Appium 安装
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install -g appium
cnpm install appium@1.7.2 -g
安装Appium-desktop
下载地址:https://github.com/appium/appium-desktop/releases
上面提到的问题可以使用前面我们已经介绍了Appium Server来解决,Appium-desktop工具其实也封装了Appium server和Node.js依赖环境。可以直接安装Appium-desktop就不需要重复安装上面的环境。
python环境安装配置
参考python官网或者使用Anaconda/MiniConda
安装Appium-Python-Client
通过命令: pip install Appium-Python-Client 进行安装。
输入命令“from appium import webdriver” 回车,如果控制台没有报错,则说明安装成功。
JDK安装配置
jdk下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
jdk环境变量配置
http://jingyan.baidu.com/article/624e74599e8ad834e8ba5a94.html
Andriod sdk 安装
下载地址:
http://tools.android-studio.org/index.php/sdk
安装 appium-doctor
appium-doctor可以检测Appium整体依赖环境配置情况。
cnpm install appium-doctor -g
在控制台输入命令:appium-doctor 看到如下提示说明整体环境配置成功。
C:\Users\Tao Zhou>appium-doctor
info AppiumDoctor Appium Doctor v.1.4.3
info AppiumDoctor ### Diagnostic starting ###
info AppiumDoctor ✔ The Node.js binary was found at: D:\Program Files\nodejs\node.exe
info AppiumDoctor ✔ Node version is 8.11.3
info AppiumDoctor ✔ ANDROID_HOME is set to: C:\Android\sdk
info AppiumDoctor ✔ JAVA_HOME is set to: C:\Program Files\Java\jdk1.8.0_171
info AppiumDoctor ✔ adb exists at: C:\Android\sdk\platform-tools\adb.exe
info AppiumDoctor ✔ android exists at: C:\Android\sdk\tools\android.bat
info AppiumDoctor ✔ emulator exists at: C:\Android\sdk\tools\emulator.exe
info AppiumDoctor ✔ Bin directory of %JAVA_HOME% is set
info AppiumDoctor ### Diagnostic completed, no fix needed. ###
info AppiumDoctor
info AppiumDoctor Everything looks good, bye!
info AppiumDoctor
如果上面某一项显示为“X”则说明相关环境没有配置好,需要重新安装配置。
Appium capability参数配置简介
什么是Capability
desired capability的功能是配置Appium会话。他们告诉Appium服务器您想要自动化的平台和应用程序。
Desired Capabilities是一组设置的键值对的集合,其中键对应设置的名称,而值对应设置的值。(如:”platformName”: “Android”)Desired Capabilities主要用于通知Appium服务器建立需要的Session。
Session
Appium的客户端和服务端之间进行通信都必须在一个Session的上下文中进行。客户端在发起通信的时候首先会发送一个叫作“Desired Capabilities”的JSON对象给服务器。服务器收到该数据后,会创建一个session并将session的ID返回到客户端。之后客户端可以用该session的ID发送后续的命令。
常用Capability配置
公用Capability
Android独有Capability
desired capability参数json
- platformName - 设备平台
- platformVersion - Android版本
- deviceName - 真机是adb devices给出的id,模拟器是ip
- appPackage - 应用的包
- appActivity - 启动应用的activity
- noReset - 不重置应用状态,默认为false,会导致应用清除数据
{
“platformName”: “Android”,
“platformVersion”: “8.0.0”,
“deviceName”: “d25bb163”,
“appPackage”: “us.zoom.videomeetings”,
“appActivity”: “com.zipow.videobox.LauncherActivity”,
“noReset”: true
}
Inspector元素获取
启动成功之后就可以使用 Inspector来进行元素空间获取了。
注意:默认的元素定位有一些不准,需要切换到第二个坐标点定位选项后再切换回来才能准确定位。
代码演示
通过使用脚本可以实现循环发送消息的功能
#coding=utf-8
import os, subprocess
from time import sleep
import unittest
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.connectiontype import ConnectionType
class SimpleAndroidTests(unittest.TestCase):
# 首先需要在setup中定义capability参数,和之前是差不多的,这里多了unicodeKeyboard和resetKeyboard是为了禁用输入法,便于后面使用sendkeys
def setUp(self):
desired_caps = {}
desired_caps['unicodeKeyboard']='True'
desired_caps['resetKeyboard']='True'
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '8.0.0' # 8.0.0 / 6.0.1
desired_caps['deviceName'] = 'd25bb163' # d25bb163 / 4200024cee07b3b3 / 3d22a523
desired_caps['appPackage'] = 'us.zoom.videomeetings'
desired_caps['appActivity'] = 'com.zipow.videobox.LauncherActivity'
# desired_caps['app'] = r'C:\Users\Tao Zhou\zoom.5.1.25288.0824.apk'
desired_caps['noReset'] = 'True'
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
# 定义一个发送消息的方法,通过self.driver.find_element_by_xpath和self.driver.find_element_by_id找到布局按钮或输入框,
# 使用self.driver.implicitly_wait(1)实现等待,因为某些布局加载需要时间,也可以使用异常捕捉来取代全局等待
def sendMsg(self, msg = 'hahahhah'):
self.driver.find_element_by_xpath('//android.widget.RelativeLayout[@content-desc="联系人选项卡。"]').click()
self.driver.find_element_by_id('us.zoom.videomeetings:id/btnSearch').click()
self.driver.implicitly_wait(1)
self.driver.find_element_by_id('us.zoom.videomeetings:id/edtSearch').send_keys('tao')
self.driver.implicitly_wait(1)
self.driver.find_element_by_id('us.zoom.videomeetings:id/txtTitle').click()
self.driver.implicitly_wait(3)
self.driver.find_element_by_id('us.zoom.videomeetings:id/edtMessage').send_keys(msg)
self.driver.implicitly_wait(1)
self.driver.find_element_by_id('us.zoom.videomeetings:id/btnSend').click()
self.driver.back()
self.driver.back()
# 所有以test开头的方法都视为一个用例,脚本会直接从这个方法进入,那么可以使用一个for循环执行发送消息20次
def test_login(self):
self.driver.implicitly_wait(5)
self.driver.find_element_by_xpath('//android.widget.RelativeLayout[@content-desc="电话标签。"]').click()
self.driver.find_element_by_xpath('//android.widget.RelativeLayout[@content-desc="联系人选项卡。"]').click()
self.driver.implicitly_wait(2)
self.driver.back()
self.driver.implicitly_wait(2)
for i in range(20):
SimpleAndroidTests.sendMsg(self, "hahha %d" % i)
if __name__ == '__main__':
# deviceId = 'd25bb163'
# subprocess.Popen("adb uninstall us.zoom.videomeetings")
# appiumServer = subprocess.Popen("appium -U%s --no-reset" % deviceId, shell=True)
# sleep(5)
suite = unittest.TestLoader().loadTestsFromTestCase(SimpleAndroidTests)
unittest.TextTestRunner(verbosity=2).run(suite)
元素定位
- id
- name
- class
- List定位
- 相对定位
- Xpath定位
- H5页面元素定位
- Uiautomator定位
一般常用xpath和id,定位比较准确,而且可以配合Inspector使用,直接找到对应的控件的id或xpath