如何用airobots进行移动端测试

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右边的设备窗口即可看到设备,选择连接即可,效果如下:

Android端

对于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)。

wda配置

以上几处配置好后,就可以启动测试,然后启动代理,将手机端口映射到mac。

  • 通过 Homebrew 安装iproxy
    $ brew install libimobiledevice
  • 运行iproxy
    $ iproxy 8100 8100

wda启动成功

airtest连接iphone的效果

ios端

以上配置好后,就可以用airtest的IDE进行录制操作了。

appium环境搭建参考

利用airobots集成的appium进行测试,需要先安装appium服务,具体可参考官网文档进行,网上也有很多资料,推荐安装Appium Desktop,方便可视化操作和定位元素,这里就不再赘述,以下提供一些参考文档链接。

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后,进行移动端测试的大概过程,后续会根据日常使用场景,对每种方法进行单独的讲解,以上。

发表评论