基于Appium、Python的自动化测试环境部署和实践
第一章 导言
1.1 编制目的
该文档为选用Appium作为移动设备原生(Native)、混合(Hybrid)、移动Web(Mobile Web)应用UI自动化测试的相关自动化测试人员、开发人员等提供参考。
1.2 预期读者
自动化测试人员、测试代表、开发人员等。
第二章 概述
2.1 Appium设计哲学
不需要为了自动化而且重新编译或修改测试app;
不应该让移动端自动化测试限定在某种语言和某个具体的框架;也就是说任何人都可以使用自己最熟悉最顺手的语言以及框架来做移动端自动化测试;
不要为了移动端的自动化测试而重新发明*,重新写一套惊天动地的api;也就是说webdriver协议里的api已经够好了,拿来改进一下就可以了;
移动端自动化测试应该是开源的;
2.2 Appium技术框架(C/S 框架)
Appium的核心是一个暴露了一系列REST API的Server。这个server的主要功能:监听一个端口,然后接收由client发送来的命令(command)。解析这些command,把这些command转成移动设备可以理解的形式发送给移动设备,然后移动设备执行完这些command后把执行结果返回给server, server再把执行结果返回给client。
client就是发起command的设备,一般来说就是我们代码执行的机器,执行appium测试代码的机器。狭义点理解,可以把client理解成是代码,这些代码可以是java/ruby/python/js的,只要它实现了webdriver标准协议就可以。
这样的设计思想带来了一些好处:
1)多语言的支持;
2)可把server放在任意机器上,支持云测试;
图1 Appium架构
图2 Appium Android模型
图3 AppiumiOS模型
2.3 Appium Server/Client
Appium Server即服务器,连接Appium客户端和移动设备。原生的webdriverapi为web端设计,因此扩展到移动端要拓展。Appium官方提供了一套appium client,涵盖多种语言ruby/java/python等。
2.4 会话Session
在webdriver/appium,所有测试都必须在Appium Server和移动设备之间创建会话(Session)后才可以进行。一般来说,通过POST/session这个URL,然后传入会话属性(Desired Capabilities)就可以开启会话了。开启会话后,会返回一个全局唯一的会话ID(session id),之后几乎所有的请求都基于该会话ID,该会话ID代表了你所打开的浏览器或者是移动设备的模拟器,连接执行机器和移动设备。由于每个移动设备的连接会话ID是全局唯一的,那么在同一台机器上启动多个会话就变成了可能,这使多移动设备的并发测试成为可能。
会话属性(Desired Capabilities)包含会话配置信息,以key-value形式存在,可以理解成是java里的map,python里的字典,ruby里的hash以及javascript里的json对象(实际上,Appium Server和移动设备之间的会话属性就是通过json对象传输)
第三章 Appium安装
Appium Windows版仅支持Android设备(手机),Appium Mac版同时支持Android和iOS设备(手机)。
3.1 Windows版安装(64位)
3.1.1 软件列表
1)JDK> 1.6
2)vcredist_x86_c++
3).Net Framework > 4.0
3)Android Developer Tools(ADT-Bundle-windows-x86-64)
4)Appium for windows(最新版1.4.16.1)
5) Appium client(根据使用的语言安装一种即可:Java/Python/Ruby等),对于Java客户端,还需要Selenium包selenium-java-2.46.0.jar , selenium-server-standalone-2.46.0.jar,python的是Appium-python-client(就是一个python类库)
6)Android手机驱动(for windows),windows必须安装任意一个Android手机驱动,否则,adb无法检测无设备。
3.1.2 安装过程
按照JDK、vcredist_x86_c++、.NET Framework、Appium的顺序安装好各软件,ADT直接下载就可以用无需安装
1)JDK安装:设置系统环境变量JAVA_HOME为JDK安装路径:(Java安装和环境变量配置,自行百度)
2)vcredist_x86_c++安装:百度下载vcredist_x86_c++.exe文件,双击安装即可。
3).NET Framework安装:百度一个大于4.0版本的.NET Framework.exe文件。双击安装即可。
4)Appium服务端安装:下一个Appium for windows 1.4.16版本,双击安装即可。(注:Appium分为客服端和服务端,服务端就是Appium工具,又可以分为GUI版本和终端版本。GUI版本是可视化的图像界面工具,终端版本是在终端启动的一个服务而已。客服端就是针对python、java、ruby等语言开发的类库)
5)ADB安装:ADB是ADT的一个工具,所以,在要下一个ADT的安装包(免安装的)解压即可。然后,设置系统环境变量ANDROID_HOME为ADT所在目录(比如D:\Mobile-AutoTest-Software\adt-bundle-windows-x86_64-20130917\sdk),同时把并把ADT里的tools和platform-tools两个目录加入到系统的 Path路径里:注意:adb需要安装adb驱动,一般手机驱动自带adb驱动,所以只要安装一个手机驱动即可
adb安装成功后在终端输入adb devices会弹出PC端连接的设备的udid
6)python安装:下一个python2.7的安装包,双击安装即可。如果需要通过python安装相关的python类库,还要安装pypa-setuptools、pip等工具。
6)Appium客服端安装:安装Appium Client(客户端只需安装一个,比如Python的或者Java的)这里以python为例:
1、需首先安装Python、pypa-setuptools、pip等Python环境(安装过程自行百度),然后通过pip在线(PC需联网)安装Selenium及Python客户端(cmd下切换到Python安装目录C:\Python27\Lib\site-packages\后执行):
python pip install Selenium
python pip install Appium-Python-Client
2、设置环境变量,把Python的目录加到系统的Path路径里
小提示:
安装Appium-Python-Client客户端时有时会遇到setuptools版本问题,运行python pip install –upgrade setuptools升级后再安装:
如果机器没联网,下载Selenium和Appium-Python-Client,并解压把整个目录放到Python安装目录(一般是C:\Python27\Lib\site-packages 目录下),如下图(selenium-2.53.1目录下py目录的selenium目录拷贝到上面的site-packages目录)
Java客户端可直接下载Jar包(比如java-client-3.2.0.jar),在Java工程中添加Jar即可。
其他客户端安装【略】
按照如上步骤安装好各软件后,基本环境就算完成了。启动Appum,填写被测APP路径,Platform选Android,Automation Name选Appium,PlatformVersion根据手机的Android版本选择,DeviceName选择上面adb命令识别的手机udid号;Server地址和端口保持默认:
配置上面两项内容后,点击启动按钮,看到最后一行信息及表示启动成功:
3.2 Mac版安装
3.2.1 软件列表
Mac Pro (OS X 10.10.3)
JDK > 1.6
Appium for Mac(最新版Appium-1.4.13.dmg)
Xcode 7.X
Appium Client(Python、Java等),对于Java客户端,还需要Selenium包selenium-java-2.46.0.jar , selenium -server-standalone-2.46.0.jar
3.2.2 Appium安装过程
- 安装brew :终端输入ruby –e "$(curl –fsSLhttps://raw.githubusercontent.com/Homebrew/install/master/install)"
- 安装node.js:到官网http://nodejs.org下载Mac的pkg安装包,下载完成直接安装即可无需配置任何参数。在终端输入node –version 如有版本号出来这说明成功。(也可以通过brew、来安装:brew install node)
- 获取权限:sudo chmod –R 777 /usr/local/
- 安装ideviceinstaller:brew update ,brew install ideviceinstaller
- 安装Appium服务端:npm install –g appium@1.4.16,npm install wd(还有问题就看这篇文章:www.15yan.com/story/4GbuTwXQKDU/)
- 安装pip:sudo easy_install pip就行。
- 安装appium python client和selenium(客服端):pip install Appium-Python-Client,pip install selenium
过程和Windows基本一致,JDK安装过程自行百度,python咋Mac和Linux环境下是自带的无须安装。环境变量JAVE_HOME和ANDROID_HOME设置,并把ADT里的platform-tools和tools加到系统目录:
最后,启动Appium-doctor检查环境配置,全部打勾说明环境搭建完毕:
3.2.3 针对iOS10升级appium到1.6.3解决方案
由于iOS10放弃了uiautomator,改用XCUITest来进行测试。appium1.6.0之前的版本全部采用uiautomator来进行自动化测试,基于这次iOS的调整,appium1.6.0之后的版本添加了WebDriverAgent依赖来应对这次iOS的调整。这里,我针对appium1.6.3的升级过程做描述。
- 安装carthage,brew install carthage
- 安装xcpretty,gem install xcpretty
- 在安装好appium旧版情况下,卸载appium。npm uninstall –g appium.
- 安装appium1.6.3,npm install –g appium。(这个过程会很难成功,但是,我们能做的就是不停尝试,直到安装成功为止。)
- 安装WebDriverAgent,cd /usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent(如果不在此目录,自行查找)
- mkdir –p Resources/WebDriverAgent.bundle
- sh ./Scripts/bootstrap.sh –d(这步可能会报错,去下一个vpn,开启服务,再次下载就ok了,这里推荐“star vpn”很不错的vpn)
- cd /usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent用xcode打开WebDriverAgent.xcodeproj。修改项目的Bundle identifier.要包Bundle identifier的Facebook改成其他东西。Signing,要选Automatically manage signing,开发者选自己的账号或者用证书进行编译,项目的所有bundle identifier都要该。改完后, build。
- 关闭xcode,在终端cd /usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent。
- xcodebuild –project WebDriverAgent.xcodeproj –scheme WebDriverAgentRunner –destination 'id=真机的udid' test.
- 如果运行结果报错为“Test target WebDriverAgentRunnerencounted an error (Early unexpected exit,operationnever finished bootstrapping –no restart will be attempted)”则忽略不计。
- 到此升级工作完成,注意:在安装WebDriverAgent到手机的时候必须保持手机连接外网。当然,在使用的过程中同样要连接外网。(如果WedDriverAgent是用证书进行编译的则在使用过程中不用连接外网)
- 由于,appium1.6.3为推出GUI版本,这里做元素定位的时候,我们用macaca进行定位,macaca安装教程网上查询。
- app-inspector是macaca的元素定位工具,使用命令,在终端输入:app-inspector –u "设备的udid"
3.3 Linux版安装
3.3.1 软件列表
Linux Ubuntu Destop 14.04以上版本
brew
ruby
git
curl
node
jdk
appium
Android sdk
Python Appium客户端:Appium-Python-Client、Selenium
3.3.2 安装过程
Appium Server 的安装
【参考https://coderwall.com/p/rcvkrq/install-nodejs-using-homebrew-and-install-appium】
1. 删除nodejs : sudo apt-get remove nodejs。但是默认的系统nodejs没有,这一步可做可不做。
2. 安装ruby:sudo apt-get install ruby
确认ruby 安装成功:
ruby -v有ruby的版本信息。
3. 安装git:sudo apt-get install git
4. 安装brew:ruby -e "$(wget -O- https://raw.github.com/Homebrew/linuxbrew/go/install)"
如果上面执行不成功的话可以用下面这句git clone https://github.com/Homebrew/linuxbrew.git ~/.linuxbrew
5. 安装curl:sudo apt-get install curl
6. 安装node.js:一定不能用sudo,直接普通用户安装(确认之前文件环境配置好后,如果安装下载失败多试几次)
brew install node
如果上面执行不成功的话就用这种方法:sudo apt-get install g++。
sudo apt-get install libssl-dev。
wget http://nodejs.org/dist/v5.6.0/node-v5.6.0.tar.gz。
tar zxvf node-v5.6.0.tar.gz。
./configure(注:这句话要切到node的bin目录下执行)。
make。
make install。
sudonpm install –g express-generator@4(全局模式安装)。
可能会比较慢(本机安装15分钟左右),耐心等待nodejs安装成功。
查看安装完成
node -v
7. 安装 Java 虚拟机
下载JDK,下载最新Java SDK
解压安装
我们把JDK安装到这个路径:/usr/lib/jvm
如果没有这个目录(第一次当然没有),我们就新建一个目录
1)cd /usr/lib
2)sudo mkdir jvm
建立好了以后,我们来到刚才下载好的压缩包的目录,解压到我们刚才新建的文件夹里面去,并且修改好名字方便我们管理,(根据版本名自己修改名字)
1)sudo tar zxvf ./jdk-7-linux-i586.tar.gz -C /usr/lib/jvm
2)cd /usr/lib/jvm
3) sudo mv jdk1.7.0_05/ jdk7
配置JAVA环境变量
gedit ~/.bashrc
在打开的文件的末尾添加
export JAVA_HOME=/usr/lib/jvm/jdk7
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
保存退出,然后输入下面的命令来使之生效
source ~/.bashrc
配置默认JDK
由于一些Linux的发行版中已经存在默认的JDK,如OpenJDK等。所以为了使得我们刚才安装好的JDK版本能成为默认的JDK版本,我们还要进行下面的配置。
执行下面的命令:
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk7/bin/java 300
sudo update-alternatives --install /usr/bin/javacjavac /usr/lib/jvm/jdk7/bin/javac 300
注意:如果以上两个命令出现找不到路径问题,只要重启一下计算机在重复上面两行代码就OK了。
执行下面的代码可以看到当前各种JDK版本和配置:
sudo update-alternatives --config java
测试
打开一个终端,输入下面命令:
java -version
显示结果(JDK1.8):
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b05)
Java HotSpot(TM) Server VM (build 23.1-b03, mixed mode)
这表示java命令已经可以运行了。
8. 安装appium
全局安装appium,本机安装的是1.4.16版本(如果不加版本名会自动安装最新版本),通过npm淘宝镜像
通过config命令
npm config set registry https://registry.npm.taobao.org (这里是为下面一句服务的,即把appium的下载数据源指向淘宝库)
npm install -g appium@1.4.16
如果安装失败就用root账号进行安装?安装完之后,
cd /usr/local/lib
sudo chown –R 主机名字 node_modules
然后卸载:
npm uninstall appium –g
之后再普通用户下启动appium
可能会比较慢,耐心等待安装成功,如果安装失败重复执行安装命令(如果之前有安装过错误的版本,提示得删除之前的文件,删除之后在安装)。
安装成功会出现树状依赖关系图
查看版本
appium -v
9. 下载安装Android SDK Starter Package
Android SDK Starter Package这个只是SDK的核心基本工具,有了它,再利用它的管理工具下载其他你需要到部分。看到这个目录中有个android脚本文件了吗?执行它,就会启动Android SDK and AVD Manager,这个工具可以帮你下载其他你需要的部分,还可以创建模拟机。
下载地址是:http://developer.android.com/sdk/index.html,不过国内这个地址被墙掉了,你要想版本下载包了。
一般是下载最新版,我下载的:android-sdk_r21.1-linux.tgz。
wget http://dl.gmirror.org/android/android-sdk_r24.4.1-linux.tgz
接下来当然是解包了:tar zvxf android-sdk_r21.1-linux.tgz
解包完毕,就会在当前目录下出现android-sdk-linux_x86目录了。这个目录下就是sdk的基本工具了。记住这个目录,因为以后你运行工具或者设置ADT的时候,会需要这个目录的!。
注意,需要安装ia32-libs
sudo apt-get install -y libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5 lib32z1
配置 Android SDK
配置 Android 环境变量,将下面的变量添加到环境变量当中去(根据自己sdk存放的文件夹修改路径,注意HOME就为当前用户目录下)
export ANDROID_HOME="$HOME/adt/sdk"
export PATH=${PATH}:~/adt/sdk/tools
export PATH=${PATH}:~/adt/sdk/platform-tools
然后source
source ~/.bashrc
10. 安装Appium客户端(ubuntu系统自带python2.7和python3.4版本)
安装Appium-Python-Client(使用pip安装)
sudo apt-get install python-pip
sudo pip install Appium-Python-Client
(可能会失败,多试几次)
安装 selenium 2.0(/usr/local/lib/python2.7/dist-packages下也有就无需安装)
sudo apt-get install selenium
测试Appium
测试appium环境安装正确与否
appium-doctor
所有环境都打钩为正确配置好环境,查看上面的JAVA_HOME和ANDROID_HOME环境配置是否正确
命令行敲入appium
出现 welcome to appium v1.4.16 代表安装成功
测试项目
将项目放到/python2.7/dist-packages文件夹下测试运行
完成!!!
第四章 控件识别
4.1 控件识别(Windows)
启动Appium后,用Appium Inspector进行控件识别(如下图),可以进行点击和输入操作(Tap、Text),右边的界面会根据操作实时更新,方便连续识别控件。
4.2 控件识别(Mac)
启动Appium后,用Appium Inspector进行控件识别(如下图)。
4.3 tips
Appium终端版本启动命令:
Linux下启动命令:appium -a 127.0.0.1 -p 端口号 -bp 端口号 --session-override --no-reset
Mac下启动命令:appium -a 127.0.0.1 -p 端口号 -bp 端口号 --session-override --no-reset --tmp 绝对路径
Mac下启动多个appium(小于1.6.0的版本)会有冲突,所以必须要对每个appium自定一个不同的数据缓存目录。因此,tmp后面的参数不能相同。appium(大于1.6.0)由于引进了WebDriverAgent,同时运行个appium客户端会导致wda的pc端端口重复,可以在测试脚本中指定setCapability("wdaLocalPort","端口一"),确保每个appium客户端wdaLocalPort端口不同。
Appium长时间运行报错:FATAL ERROR:CALL_AND_RETRY_LAST Allocation failed – process out of memory 已放弃(核心已转储)。判断为node内存溢出。这是node的bug。
第五章 python脚本实例
driver对象类
from appium import webdriver
import time
from selenium.common.exceptions import NoSuchElementException class driverObject:
def __init__(self, host, port, platform, version, deviceName, noReset, unicodeK, resetK, appPath ,appP_bdId, appA_udid, localPort):
#__appP_bdId = "com.yitong.fjnx.mbank.android"
__appP_bdId = appP_bdId
#__appA_udid = ".Splash"
__appA_udid = appA_udid
self.pwmode = 'lower'
self.model='Appium'
self.desired_caps = {}
self.desired_caps['platformName'] = platform
self.desired_caps['platformVersion'] = version
self.desired_caps['noReset'] = noReset
self.desired_caps['unicodeKeyboard'] = unicodeK
self.desired_caps['resetKeyboard'] = resetK
self.desired_caps['app'] = appPath
self.desired_caps['udid'] = deviceName
self.desired_caps['deviceName'] = deviceName # Android - ignored, iOS - iPhone name
if platform == "Android":
self.desired_caps['appPackage'] = __appP_bdId
self.desired_caps['appActivity'] = __appA_udid
if platform == "iOS":
self.desired_caps['bundleId'] = __appP_bdId
self.desired_caps['automationName'] = 'XCUITest'
self.desired_caps['wdaLocalPort'] = localPort
url = "http://" + host + ":" + str(port) + "/wd/hub"
self.driver = webdriver.Remote(url, self.desired_caps)
time.sleep(5)
def get_driver(self):
return self.driver
def quit(self):
self.driver.quit()
主类
from testClass import driverObject
if __name__ == '__main__':
driver = driverObject(参数...)
ele = self.driver.find_elements_by_class_name("android.widget.Button")
ele[0].click()
time.sleep(5)
ele = self.driver.find_elements_by_class_name("android.widget.EditText")
ele[1].send_keys("account")
ele[2].send_keys("password")
ele = self.driver.find_elements_by_class_name("android.widget.Button")
time.sleep(2)
ele[0].click()
driver.quit()
关于Appium、Python的测试脚本公共函数可以查阅Appium-Python-Api文档,里面记录Appium提供给python的公共函数。其实,测试脚本的大部分内容就是找控件、点击控件、输入内容、线程等待这些操作。