airobots的移动端测试,主要是将airtest和appium进行了集成,appium是比较流行的移动端测试框架,airtest是基于图像识别的移动端测试框架,个人体验来看,是比较好用的两个框架吧。appium的环境搭建方面比airtest较为复杂一些,所以,个人推荐优先考虑airtest,我们先来看演示。
下载demo项目(可选)
airobots可直接通过命令执行用例文件或用例目录来进行测试:
airobots -t ios / android 用例文件或用例目录路径
但通常,为了更方便管理我们的测试脚本和开发一些自定义方法,我们都会对用例脚本做一些组织,用不同的目录来区分不同的作用,demo是我在项目中的组织方式,大家也可以按自己的习惯进行。demo下载地址:https://github.com/BSTester/AirobotsDemo
。项目目录结构说明,大家可以看往期文章:如何利用airobots做web自动化测试。
运行示例脚本
运行示例前请先进入项目目录,执行以下命令安装相关依赖包
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
Android端
Android端测试相对比较简单,执行以下命令即可,如果提示没有执行adb的权限,请按提示赋予adb执行权限。
airobots -t android --clean-alluredir --alluredir=Results TestCases/AndroidCase/test_android_hello.py
ps:测试示例为启动魅族手机的计算器,执行1+1操作,如果是其他手机,可能会执行失败,请自行修改测试程序。
IOS端
IOS端的测试相对比较复杂,需要安装xcode,再编译安装wda到测试手机,后面会介绍怎么安装,此处假设已安装成功。
基于airtest
airobots -t ios --clean-alluredir --alluredir=Results TestCases/IOSCase/test_ios_hello.py
基于appium
因appium和airtest不能同时使用,因此,需要修改文件TestCases/IOSCase/__init__.py
中的初始化driver的代码,注释掉poco相关,启用appium部分并启动appium服务。
# 基于poco
# poco = IOSUiautomation(device=connect_device('iOS:///127.0.0.1:8100'), use_airtest_input=True, screenshot_each_action=False)
# 基于appium
driver = AirAppium()
driver.open_application(remote_url='http://localhost:4723/wd/hub', bundleId='com.apple.calculator', platformName='iOS', platformVersion='14.4.1', deviceName="Penn's iPhone", udid='6f004f4eb3528659c9c617836e698cb7e5a21605')
然后执行以下命令启动测试
airobots -t ios --clean-alluredir --alluredir=Results TestCases/IOSCase/test_ios_appium_hello.py
环境搭建
airtest环境
在执行上面的环境初始化命令时,airtest的执行环境就已经安装成功了。为了方便定位元素,airtest有提供一个可视化编辑器,可以录制脚本,也可以方便定位元素。
安装airtest比较简单,到官网http://airtest.netease.com/
下载安装即可,对于android端,没有其他过多的配置。对于快速入门,官网也有详细的文档,大家可移步官网查看:https://airtest.doc.io.netease.com/tutorial/1_quick_start_guide/
。
对于Android,无需过多配置,开启手机调试模式,连接上电脑,在IDE右边的设备窗口即可看到设备,选择连接即可,效果如下:
对于IOS端,需要在Mac环境下操作,下载airtest提供的iOS-Tagent
,用xcode编译后,安装在测试机中,最新版本的airtest也支持appium的wda,对于高版本的ios兼容性较好,也是推荐安装appium版本,github地址:https://github.com/appium/WebDriverAgent
。大家可先按官方文档的步骤部署wda,新手村传送门:https://airtest.doc.io.netease.com/IDEdocs/device_connection/4_ios_connection/
在编译安装WebDriverAgent时,主要有几个坑需要注意:
- 需要先申请开发者证书,有的就跳过。
- 需要修改Product Bundle Identifier,保证唯一。
- 有三个地方需要选择开发者。
- 第一次安装好后,需要在手机中操作信任开发者(设置-通用-描述文件及设备管理-开发者app)。
以上几处配置好后,就可以启动测试,然后启动代理,将手机端口映射到mac。
- 通过 Homebrew 安装iproxy
$ brew install libimobiledevice
- 运行iproxy
$ iproxy 8100 8100
airtest连接iphone的效果
以上配置好后,就可以用airtest的IDE进行录制操作了。
appium环境搭建参考
利用airobots集成的appium进行测试,需要先安装appium服务,具体可参考官网文档进行,网上也有很多资料,推荐安装Appium Desktop,方便可视化操作和定位元素,这里就不再赘述,以下提供一些参考文档链接。
如何编写测试用例(代码解析)
Android
用例文件:TestCases/AndroidCase/test_android_hello.py
from airobots.core.api import *
from unittest import TestCase
from airtest.core.settings import Settings as ST
from TestCases.PageObjects.Android.android_demo import DemoOP
from airobots.poco.android import AndroidUiautomation # Android方法库
import os
# 以上引用依赖库
class AndroidCase(TestCase):
"""Custom launcher."""
@classmethod
def setUpClass(cls):
super(AndroidCase, cls).setUpClass()
cls.poco = AndroidUiautomation(screenshot_each_action=False) # 初始化android设备,基于poco
cls.android = DemoOP(driver=cls.poco) # 实例化POM类
def setUp(self):
"""Custom setup logic here."""
# add var/function/class/.. to globals:
# self.scope["add"] = lambda x: x+1
# exec setup test script:
# self.exec_other_script("setup.air")
# set custom parameter in Settings:
# ST.THRESHOLD = 0.75
super(AndroidCase, self).setUp()
def tearDown(self):
"""Custom tear down logic here."""
# exec teardown script:
# self.exec_other_script("teardown.air")
super(AndroidCase, self).tearDown()
@classmethod
def tearDownClass(cls):
super(AndroidCase, cls).tearDownClass()
# 测试方法,执行1+1
def test_calc(self):
self.android.wake_up_and_open_calc()
self.android.calc_add()
assert_exists(Template(os.path.join(os.path.dirname(__file__), "tpl1602777528520.png"), record_pos=(0.379, -0.267), resolution=(720, 1280)), "计算结果是否等于2")
self.android.calc_c()
self.android.close_calc()
POM文件:TestCases/PageObjects/Android/android_demo.py
from airobots.core.api import *
from unittest import TestCase
import os
# 以上引用依赖库
class DemoOP(TestCase):
def __init__(self, driver):
super(DemoOP, self).__init__()
self.poco = driver
"""Demo page objects."""
def wake_up_and_open_calc(self):
wake() # 唤醒
keyevent("HOME") # 按Home键
# 启动应用
start_app('com.meizu.flyme.calculator')
def calc_add(self):
# 基于图像识别进行点击操作
touch(Template(os.path.join(os.path.dirname(__file__), "tpl1602698317745.png"), record_pos=(-0.351, -0.026), resolution=(720, 1280)))
# 基于元素定位进行点击操作
self.poco(text="1").click()
touch(Template(os.path.join(os.path.dirname(__file__), "tpl1602700388209.png"), record_pos=(0.331, 0.554), resolution=(720, 1280)))
self.poco(text="1").click()
touch(Template(os.path.join(os.path.dirname(__file__), "tpl1602700724083.png"), record_pos=(0.332, 0.76), resolution=(720, 1280)))
sleep(2)
def calc_c(self):
touch(Template(os.path.join(os.path.dirname(__file__), "tpl1602698317745.png"), record_pos=(-0.351, -0.026), resolution=(720, 1280)))
sleep(2)
def close_calc(self):
# 退出应用
stop_app('com.meizu.flyme.calculator')
IOS
基于airtest的IOS端测试,脚本使用关键词跟Android端一样,同时支持图像识别和元素定位操作,这里就不再注释。
appium
文件:TestCases/IOSCase/__init__.py
from airobots.poco.ios import IOSUiautomation
from airobotLibrary import AirAppium # 导入appium依赖库
from airobots.core.api import connect_device
# 基于poco
# poco = IOSUiautomation(device=connect_device('iOS:///127.0.0.1:8100'), use_airtest_input=True, screenshot_each_action=False)
# 基于appium
driver = AirAppium() # 初始化appium服务
# 用指定真机设备打开系统计算器
driver.open_application(remote_url='http://localhost:4723/wd/hub', bundleId='com.apple.calculator', platformName='iOS', platformVersion='14.4.1', deviceName="Penn's iPhone", udid='6f004f4eb3528659c9c617836e698cb7e5a21605')
用例文件:TestCases/IOSCase/test_ios_appium_hello.py
from airobots.core.api import *
from unittest import TestCase
from airtest.core.settings import Settings as ST
from TestCases.PageObjects.IOS.ios_appium_demo import DemoOP
from TestCases.IOSCase import driver
import os
class IOSCase(TestCase):
"""Custom launcher."""
@classmethod
def setUpClass(cls):
super(IOSCase, cls).setUpClass()
cls.ios = DemoOP() # 实例化POM类
def setUp(self):
"""Custom setup logic here."""
# add var/function/class/.. to globals:
# self.scope["add"] = lambda x: x+1
# exec setup test script:
# self.exec_other_script("setup.air")
# set custom parameter in Settings:
# ST.THRESHOLD = 0.75
super(IOSCase, self).setUp()
def tearDown(self):
"""Custom tear down logic here."""
# exec teardown script:
# self.exec_other_script("teardown.air")
super(IOSCase, self).tearDown()
@classmethod
def tearDownClass(cls):
super(IOSCase, cls).tearDownClass()
# 测试用例,执行1+1操作
def test_calc(self):
self.ios.calc_add()
# 断言结果是否正确
driver.element_value_should_be('结果', 2)
self.ios.calc_c()
self.ios.close_calc()
POM文件:TestCases/PageObjects/IOS/ios_appium_demo.py
from airobots.core.api import *
from unittest import TestCase
from TestCases.IOSCase import driver
import os
# 以上引用依赖库,appium不能与airtest语法混合使用,以下全通过appium操作。
class DemoOP(TestCase):
# 通过Appium Desktop识别或录制的元素定位标识
AC = '全部清除' # 基于name
C = '清除'
ADD = '//XCUIElementTypeButton[@name="加"]' # 基于xpath
EQ = '等于'
"""Demo page objects."""
def calc_add(self):
driver.click_button(self.AC) # 点击一个按钮
driver.click_text(1) # 点击一个文本
driver.click_element(self.ADD) # 点击一个元素
driver.click_text(1)
driver.click_button(self.EQ)
def calc_c(self):
driver.click_button(self.C)
def close_calc(self):
driver.quit_application() # 退出应用
这里用到的appium方法,是基于robotframework-appiumLibrary二次封装过,使用更方便。具体方法使用语法,可直接查看源码,每个方法都有使用介绍。
以上为airobots集成airtest和appium后,进行移动端测试的大概过程,后续会根据日常使用场景,对每种方法进行单独的讲解,以上。