Linux下Appium+Python+headless移动APP自动化测试实战
本文主要阐述了Linux下进行Appium+Python+Headless的移动应用自动化测试的实操。 这项工作非常有助于在DevOps流程中执行持续集成。
Linux下Appium+Python+Headless移动APP自动化测试实战
文章目录
Linux系统由于其出色的稳定性而备受欢迎。为了方便linux用户进行android自动化测试,这篇文章主要讲述一下在linux下准备appium+python自动化测试环境的相关步骤和要求(我用的是linux mint 19.3)。
这里强烈建议大家不要在虚拟机上搞,可能会碰到各种这样那样的问题。我当时在linux主机上一次性顺利完成所有期望的配置和安装。为了写这篇文章,我在虚拟机上重新操作了一遍,结果卡在了手机模拟器启动的环节。因此读者看到的这篇文章的截图来源于两个linux计算机,一部分是我在linux主机的截图,一部分是我在linux虚拟机的截图。不过不影响阅读和参照。
1. 环境准备
1.1 安装配置JDK
linux终端下运行java -version看有没有相关的输出。另外可以执行以下的命令看看有没有JAVA_HOME环境变量的设置。
# echo $JAVA_HOME
如果这些都没有的话,请自行在linux下安装jdk并设置环境变量,这里不再赘述。
不过有一点需要说明,有的linux下自己带了openjdk,并且版本不一定适合,建议删除后再安装自己的jdk(这里建议安装JDK的1.8版本,后面会说相关原因)。
linux mint下的卸载命令如下,如果第三行命令中的目录不存在的话,第四行命令也不需要执行
# sudo apt-get purge openjdk*
# sudo apt-get purge icedtea-* openjdk-*
# cd /usr/lib/jvm
# sudo dpkg --list | grep -i jdk
1.2 安装配置Android SDK
现在官网已经没有了独立的Android SDK的下载了,新提供的是Android Studio套件,其中囊括了所有需要的工具。
当前使用的是 https://developer.android.google.cn/studio下面的最新版本4.2.2如下图
解压以后放到指定的目录下面
# tar -zxvf android-studio-ide-202.7486908-linux.tar.gz
# sudo mv android-studio /usr/local/share/
然后通过下面的命令在/etc/profile中添加Android Studio环境变量。
# sudo vi /etc/profile
在文件的最后添加如下的内容(具体路径根据自己的实际情况刷新)
export JAVA_HOME=/opt/jdk1.8.0_291
export JRE_HOME=${JAVA_HOME}/jre
export ANDROID_HOME=/home/mint/Android/Sdk
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:/usr/local/share/android-studio/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/tools:${ANDROID_HOME}/emulator:$PATH
如下图
添加完成后,保存退出。 source一下,使新添加的环境变量生效。
# source /etc/profile
这个时候发现命令行前面的当前用户信息和机器信息由绿色变成了白色,说明已经生效。
直接在命令行中执行studio.sh,会启动已经安装好的android Studio。
# studio.sh
首先打开的是启动画面,如下图。
如果是无法正常链接google服务器(国内大多数网络)的话,请按照如下的步骤走
然后出现是到如android srudio的对话框,如下图
选择不导入,点击OK按钮,接下来是上报用户数据对话框,根据自己的偏好选择即可,我选择不上传。
选择不上传以后,会出现错误,如下图
Android Studio第一运行的时候,会链接官方服务器去下载Android SDK,但是由于众所周知的原因,这一步在国内会失败。解决办法是在 Android Studio 安装目录 bin/idea.properties 文件最后添加如下一行内容。
disable.android.first.run=true
这里说明一下,这个办法不治本,仅仅是不让弹出这个错误而已,Android SDK并没有下载下来。
这样,下一次运行的时候,就不会出现这个错误提示了,会直接进入下面的界面,直接点击Create New Project,如下图
这时候提示Android SDK不存在(很正常,上面刚刚解释过),如下图
选择打开SDK Manager,进入下面的界面
点击上面设置Android SDK路径的、选项后面的Edit,打开设置Android SDK路径页面,如下图默认是在当前用户的家目录下创建“Android/Sdk”目录,保持默认即可
点击Next,确认配置
再点击Next开始下载,如下图
下载过程中报了一个如下的错误,还是因为网络不稳定原因。
一般情况下多试几次就好,下载完成后,如下图
点击Finish按钮,页面显示已经安装好了一个Android SDK,如下图。
通过命令行查看,相关内容确实已经安装到~/Android/Sdk目录下,如下图
如果是能够正常链接google服务器的话,请按照如下的步骤走
之后出现的是Setup Wizard页面,step by step结束以后出现组件下载界面,组件下载结束以后,显示如下的页面,点击Finish按钮,结束安装配置。
到目前为止,Android SDK被安装到了~/Android/Sdk目录下面。
如果读者安装的目录不是这个,或者这个目录下面找不到对应的内容,请自行搜索找到对应的Android SDK安装目录。
现在,不管用哪种方法都安装好了Android SDK,这里开始,下面步骤都是一样的
到这里,尽管Android SDK已经安装完成,但是使用还有点不方便,接下来吧SDK对应的工具包添加到环境变量中。
# sudo vi /etc/profile
保存退出后,source一下,使新的环境变量生效。这时候adb命令可以正常使用了,如下图。
1.3 安装配置Python3
这里没有什么好讲的,自行安装配置python3和pip3就可以了,略。
1.4 安装配置NodeJs
appium是基于nodejs的,linux mint下通过下面两行命令就可以顺利安装NodeJs(我当时安装的10.16.0版本,最新的appium需要nodejs 12或者以上)。
如果是安装nodejs 10.x,请用下面的脚本
# curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
# sudo apt-get install -y nodejs
如果是安装nodejs12.x,请用下面的脚本
# sudo apt-get -y install curl dirmngr apt-transport-https lsb-release ca-certificates
# curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
# sudo apt-get install -y nodejs
读者也可以通过官网下载对应的版本的压缩包,直接解压到指定的目录下,配置一下环境变量就可以使用了。
安装好后,用node -v和npm -v验证一下,如下图所示能够相应的版本信息,则说明已经安装好。
1.5 安装配置Appium
通过npm安装appium
# npm install -g appium
安装过程中可能会报权限不足的错误,这时候加上sudo重新执行一下即可。
# sudo npm install -g appium
这里描述一下我碰到的问题。之前在物理机上安装的时候,执行对应的命令一次性顺利完成安装。但是我在虚拟机上安装的时候,一直报错如下错误。
网上对这个问题有各种解决方法,但是对我来说都没有生效。虽然报错是权限问题,但是就算给对应目录777的权限,也还是报错。最终发现一个可以用的npm选项 --unsafe-perm=true --allow-root。
# sudo npm install -g appium --unsafe-perm=true --allow-root
成功安装appium,问题解决。 appium -v可以查看版本信息。
不过我还是有些不安,这样虽然安装成功,但是不排除后面还隐藏着坑。初步猜测这个错误可能跟虚拟机有一定的关系。
接下来安装appium-doctor
# sudo npm install -g appium-doctor
顺利安装完成,运行appium-doctor进行状态检查。
# appium-doctor
存在红叉叉。作为一个重度强迫症患者,这个是不可忍受的。直接whereis java,把找到的结果放到环境变量里面即可。再次运行appium-docker,红叉叉消失。
接下来安装 Appium-Python-Client
# sudo pip3 install Appium-Python-Client
到此为止,Appium+Python的移动应用自动化测试环境基本上准备完毕。
2. 配置Android Studio开发环境
对于App的运行环境,无非就是Android模拟器或者安卓实体手机。
2.1 使用Android虚拟机
对于App的运行环境,无非就是Android模拟器或者安卓实体手机。
Android模拟器的使用很简单,运行Android Studio,进入AVD Manager,启动已有的Android虚拟机或者配置新的Android虚拟机即可,如下图,这里略过。
不过这里有可能会碰到一个问题,那就是因为权限问题导致Android虚拟机启动失败,如下图。
解决方法也很简单,给对应的/dev/kvm分配owner给当前用户即可,不会配置的自己问度娘。
配置结束后,启动Android虚拟机,运行adb命令,可以看到链接到linux计算机的Android虚拟机设备。
2.2 使用Android物理手机
这里重点介绍一下,linux机器下,如何配置运行Android实体机器。
2.2.1 获取Android设备信息
在Android手机没有通过数据线链接linux主机的时候,执行一下lsusb命令,然后手机通过USB线链接到linux主机,再次运行lsusb命令。
细心的你会发现,命令输出结果里面多了一行,如下图。
这里面记录了你的Android手机链接linux主机的相关信息,请详细拷贝下来,备用。
2.2.2 Linux下配置Android手机的配置文件
通过下面的命令,创建Android主机配置文件,如果对应文件已经存在的话,请添加对应Android手机的信息。
# sudo vi /etc/udev/rules.d/51-Android.rules
在配置文件中添加如下的内容。
SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="107e",MODE="0666", GROUP="plugdev", OWNER="billson"
如下图。
这里用到了前面步骤中获取的Android手机相关信息,做一下说明,idVendor对应的字段代表手机厂商,我的华为手机这里对应的是12d1,idProduct对应的可以理解为手机型号, OWNER对应linux主机当前的用户名。有的资料里面没有加OWNER信息,但是我这里添加上了,因为我的主机不添加找不到手机。
对应内容确认无误后保存退出,然后执行下面的命令修改配置文件对应的权限。
# sudo chmod a+rx /etc/udev/rules.d/51-Android.rules
2.2.3 linux下配置ADB的USB配置文件
执行下面的命令,创建配置文件。
# sudo vi ~/.android/adb_usb.ini
在文件中以十六进制的形式添加手机对应的厂商信息和型号信息,比如对应文章中我的Android手机的配置信息为0x12D1107E。
如下图,保存退出。
2.2.4 打开Android手机调试选项
对于华为或者荣耀手机,依次进入“设置/系统/关于手机”, 如下图。
在“版本号”那一行快速点击至少5下(具体应该几下我没有数),如果手机有锁屏密码这个时候会弹出输入锁屏密码的界面,输入锁屏密码屏幕上会提示您已处于开发者模式。对于其他android手机,请自行查找进入开发者模式的方法。
然后进入手机“开发人员选项”配置页面,华为手机在“设置/系统/开发人员选项”下面,依次打开“开发人员选项”和“USB调试”开关。
这个时候将手机通过数据线链接linux主机,手机上弹出是否允许计算机进行手机调试的页面,如下图,打勾确认即可。
然后linux主机运行adb命令,可以看到连接到linux计算机的Android手机设备。
3. 元素定位与测试用例编写
有很多童鞋环境搭建好了却没有进行下一步,是因为缺少step by step的资料。 互联网上appium环境准备的资料多如牛毛,但是step by step操作的资料却少了很多。春节前的最后一个工作日事情不是很多,顺便把这一块总结整理一下,分享给需要的人。
下面所有的操作都是基于你已经准备好前面描述的所有安装部件的情况。
3.1 操作前的准备
3.1.1 启动appium server
命令行中直接运行appium,启动appium服务。
appium
出现如下图所示的相关信息的时候,表示appium server已经成功启动。
3.1.2 启动DDMS(Android Monitor)
在 A N D R O I D S D K H O M E / t o o l s 目 录 下 , 运 行 m o n i t o r 。 或 者 在 你 正 确 设 置 了 A n d r o i d S D K 环 境 变 量 并 生 效 的 情 况 下 , 在 任 意 个 命 令 行 或 者 目 录 下 , 直 接 执 行 {ANDROID_SDK_HOME}/tools目录下,运行monitor。 或者在你正确设置了Android SDK环境变量并生效的情况下,在任意个命令行或者目录下,直接执行 ANDROIDSDKHOME/tools目录下,运行monitor。或者在你正确设置了AndroidSDK环境变量并生效的情况下,在任意个命令行或者目录下,直接执行{ANDROID_SDK_HOME}/tools/monitor命令即可。
${ANDROID_SDK_HOME}/tools/monitor
如果没有异常的话,会出现如下图所示的界面。
这个时候的界面空空,什么内容都没有。
如果出现如下图所示的异常,请参照我之前的帖子处理。链接如下:
linux下Android Monitor启动失败问题
3.1.3 启动Android模拟器
运行android studio,依次进入“Configure/AVD Manager”,运行已经配置好的Android模拟器。
这里执行速度视机器性能而定,Android模拟器启动完成以后,回到Android Monitor, 这时候发现左边的devices列表中多了一个Android 模拟器,状态是Online,如下图。
这里要多啰嗦几句。一定要先启动Android Monitor,再启动Android模拟器,否则会出现Android模拟器状态一直是offline的情况。这里我没有深究具体原因,但是在我的linux系统下,如果先启动模拟器再启动monitor的话,这个问题必然出现。
3.1.4 运行被测试APP
这里以Android模拟器自带的计算机为例子进行讲解。
在Android模拟器上运行Calculator程序,只要进入主界面就可以了,如下图所示。
在Android Monitor界面,选中devices列表中的模拟器,然后点击中间那个小手机图标(Dump View Jierarchy for UI Automator),如下图。
信息加载完成以后,模拟器上运行的计算器程序界面展示在了Monitor中,如下图。
从上图中可以看出计算器APP的包名是com.android.calculator2。
3.1.5 获取App的包信息
命令行中运行adb shell dumpsys package YOUR_PACKAGE_NAME即可获取对应的包信息。
adb shell dumpsys package com.android.calculator2
如下图
等会儿编写测试代码的时候,要用到这些信息。
3.2 获取界面元素并编写测试用例
3.2.1 获取界面元素
在Android Monitor上面,每点选一个界面元素,右边就会显示对应的控件的ID,可以直接拷贝控件ID用于在测试用例中识别界面元素,如下图。
3.2.2 编写测试用例脚本
创建一个名称为Calculator.py的python脚本,内容如下。
#!/usr/bin/python3
import selenium
import time
import pytest
from appium import webdriver
my_dc = dict()
my_dc['platformName'] = 'Android' #平台为Android
my_dc['platformVersion'] = '7.1.1' #平台版本为7.1.1
my_dc['deviceName'] = 'Android_SDK_built_for_x86 device' # 取一个机器名字
my_dc['appPackage'] = 'com.android.calculator2' # 被测试App的包名
my_dc['appActivity'] = '.Calculator' # 被测试App的主Activity
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", my_dc) # 链接Appium服务器创建webdriver实例
###下面的测试用例定义的时候,一定要以test开头,否则pytest不认为是测试用例。
# 计算器 加法测试用例
def test_addition():
driver.find_element_by_id("com.android.calculator2:id/digit_3").click() #点击3
driver.find_element_by_id("com.android.calculator2:id/op_add").click() #点击+
driver.find_element_by_id("com.android.calculator2:id/digit_7").click() #点击7
driver.find_element_by_id("com.android.calculator2:id/eq").click() #点击=
result = driver.find_element_by_id("com.android.calculator2:id/result").text #获取计算结果并赋值给变量result
assert result == "10" #计算结果跟预期结果相符
# 计算器 减法测试用例
def test_subtraction():
driver.find_element_by_id("com.android.calculator2:id/digit_9").click()
driver.find_element_by_id("com.android.calculator2:id/op_sub").click()
driver.find_element_by_id("com.android.calculator2:id/digit_7").click()
driver.find_element_by_id("com.android.calculator2:id/eq").click()
result = driver.find_element_by_id("com.android.calculator2:id/result").text
assert result == "2"
# 计算器 乘法测试用例
def test_multiplication():
driver.find_element_by_id("com.android.calculator2:id/digit_9").click()
driver.find_element_by_id("com.android.calculator2:id/op_mul").click()
driver.find_element_by_id("com.android.calculator2:id/digit_7").click()
driver.find_element_by_id("com.android.calculator2:id/eq").click()
result = driver.find_element_by_id("com.android.calculator2:id/result").text
assert result == "63"
# 计算器 除法测试用例
def test_divition():
driver.find_element_by_id("com.android.calculator2:id/digit_9").click()
driver.find_element_by_id("com.android.calculator2:id/op_div").click()
driver.find_element_by_id("com.android.calculator2:id/digit_3").click()
driver.find_element_by_id("com.android.calculator2:id/eq").click()
result = driver.find_element_by_id("com.android.calculator2:id/result").text
assert result == "3"
上面的脚本内容不做详细解释。 仅仅注意下面两点。
(1)界面元素的定位,使用了 driver.find_element_by_id方法,ID就是上面2.1中获取的界面元素ID。
(2)测试脚本中引用了pytest库进行测试用例编写。pytest库要求每个测试用例都是以test_开头。
3.2.3 执行测试用例
命令行中通过下面的命令执行测试用例。
pytest calculator.py
运行结果如下图。
运行过程中,你会看到模拟器的手机界面上,按照测试用例预期的顺序依次点击了各个界面元素,并且得到了预期的测试结果。
最后,附上,测试用例执行过程中,模拟器界面,以及Appium服务器上的动态效果视频。
https://v.youku.com/v_show/id_XNTEwMTk5NDI1Mg==.html
4.Appium自动化测试的headless模式
通过前面的几篇文章,相信基本上都能够上手appium+python进行android应用的自动化测试工作了。但是在当今DevOps大行其道的日子里,如果要让这种自动化框架在CICD的持续集成环境里面顺利跑起来,可能还是有点问题的。首先,CICD的服务器以Linux居多;其次,Linux服务器一般情况下都是运行在命令行模式下;最后,传统的android emulator运行的时候占用了大量的系统资源。 这个时候,Android Emulator的headless模式就是比较好的选择了。从28.0.25版本开始,Android Emulator支持headless模式运行。这篇文章将带领大家使用Emulator的headless模式。
4.1 关于Emulator
我没有研究过Google的意图是什么,竟然在Anndroid SDK下面设置了两个emulator可执行程序。一个是${ANDROID_SDK_HOME}/tools/emulator
, 另一个是${ANDROID_SDK_HOME}/emulator/emulator
,可能Google有它自己的考虑。这里要说的的是,一般情况下命令行运行android模拟器,用的是${ANDROID_SDK_HOME}/emulator/emulator
,我本地linux下验证的时候,${ANDROID_SDK_HOME}/tools/emulator
会报各种异常。 为了保证emulator能够正常运行,在设置PATH环境变量的时候,emulator最好要放在tools的前面。
4.2 关于Headless模式
网络上有各种关于headless的方法和描述,比如emulator-headless, -no-skin,isHeadless=true等等。在最新的Android Emulator 30.3.5下(注意这里是Android Emulator的版本,不是Android Studio的版本),这些都不靠谱,直接添加参数-no-window即可。
emulator -avd EMULATOR_NAME -no-window
这个时候你可能会碰到如下图所示的一些类似audio等相关的错误提示,如果被测内容不相关的话,可以忽略。
4.3 关于linux下程序的后台执行
这个不再赘述,无非就是用&还是用nohup。具体的区别大家自己问问度娘或者狗狗。
4.4 整体的执行脚本
这个也很简单,根据正常运行的顺序,执行相关的命令即可。将如下内容写入到shell脚本automation_test.sh中,并赋予其执行权限。
# 修改/dev/kvm的属主为当前用户,否则因为权限问题启动android模拟器失败
sudo chown -R ${USER}:${USER} /dev/kvm
sleep 5s
# 后台启动appium服务用于监听界面操作,并把相关内容输出到文件appium_out.txt中
appium > ./appium_out.txt &
sleep 5s
# 后台启动android模拟器,并把相关内容输出到文件emulator_out.txt中
emulator -avd Nexus_4_API_25 -no-window > ./emulator_out.txt &
sleep 20s
# 后台运行自动化测试用例,并输出结果到test_result.txt中
pytest calculator.py > ./test_result.txt &
命令行下直接执行automation_test.sh脚本。
$ bash automation_test.sh
执行如下图。
执行过程中,可以看到整个屏幕没有相关界面弹出。执行结束后,目录下多了几个txt文件,查看相关输出文件内容,重点查看测试结果输出文件即可。
如下图,可见本次执行的4个测试用例全部通过。
更多推荐
所有评论(0)