专栏文章 多设备兼容脚本,轻松拿捏

fishfish-yu · 2024年06月06日 · 最后由 Jerry li 回复于 2024年06月17日 · 7433 次阅读

此文章来源于项目官方公众号:“AirtestProject”\
版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途

一、前言

有比较多同学有提到说能否一个脚本同时适用于 Android 跟 iOS 设备,也有同学问是否可以根据不同的 Android 厂商设备,去执行不同的操作,那么本周,我们一起探讨一下这个问题,如何让一个脚本兼容更多的机型~

二、如何查询所连接的设备信息

2.1 简单分辨 iOS 设备与 Android 设备

我们在连接完设备后,可以通过下方的语句查询到我们所连接设备时使用的类是什么,并将该类的名称返回。

device().__class__.__name__.lower()

在 Airtest 中,Android 设备以及 iOS 设备所使用的类不同,并以系统名作为类名称,所以我们可以直接通过类的名称将其区分开来。

2.2 分辨不同的 Android 设备厂商以及设备型号

Android 设备厂商比较多,我们可以通过下方的 adb 命令查询的方式去获取我们所连接的设备的相关信息,我们在控制台输入adb shell,进入 linux 命令行,再输入下方命令,可以看到有我们所需要的设备信息

adb shell 
getprop | grep product

但是我们可以根据自己的需求去进行筛选,如我们这里使用到的设备品牌以及设备型号,分别可以通过下方的方式获取

# 获取设备品牌名
adb shell getprop ro.product.brand

# 获取设备型号
adb shell getprop ro.product.model

在代码中,我们试用python3的子进程模块 subprocesssubprocess.check_output([],text=True)方法去执行 adb 命令,其中text=True 参数表示返回的输出结果是一个字符串,可以直接使用

# 获取设备品牌
brand = subprocess.check_output(['adb', 'shell', 'getprop', 'ro.product.brand'], text=True).strip() 
# 获取设备型号
model = subprocess.check_output(['adb', 'shell', 'getprop', 'ro.product.model'], text=True).strip() 

三、分辨 iOS 设备与 Android 设备案例

# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

auto_setup(__file__)


# 定义Android操作函数
def android_operate():
    start_app("com.miui.player")  # 打开小米音乐APP
    sleep(3.0)
    wait(Template(r"tpl1717383819774.png", record_pos=(-0.196, -0.251), resolution=(1080, 2400)))
    touch(Template(r"tpl1717383706465.png", record_pos=(-0.194, -0.242), resolution=(1080, 2400)))
    sleep(3.0)
    print("已打开小米的音乐APP了")


# 定义iOS操作函数
def ios_operate():

    from poco.drivers.ios import iosPoco
    poco = iosPoco()

    poco("播客").click()  # 点击播客
    sleep(1.0)

    poco("女性畅聊健康生活方式 轻松温暖治愈日常烦恼").click()  # 点击女性畅聊健康生活方式
    sleep(1.0)

    print("已打开iphone的播客APP了")



if __name__ == "__main__":
    # 获取连接的设备信息
    platform = device().__class__.__name__.lower()

    if platform == "android":
        print("当前设备是Android")  # 输出当前设备是Android
        sleep(3.0)
        android_operate()

    elif platform == "ios":
        print("当前设备是iOS")  # 输出当前设备是iOS
        sleep(3.0)
        ios_operate()

    else:
        print("当前设备是未知设备")  # 输出当前设备是未知设备

四、Android 设备分辨不同厂商型号案例

# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

auto_setup(__file__)

import subprocess


def get_android_device_info():
    try:
        # 使用 adb shell getprop 获取设备品牌和型号信息
        brand = subprocess.check_output(['adb', 'shell', 'getprop', 'ro.product.brand'], text=True).strip() # 获取设备品牌
        model = subprocess.check_output(['adb', 'shell', 'getprop', 'ro.product.model'], text=True).strip() # 获取设备型号
        return brand, model
    except Exception as e:
        # 捕获异常
        print(f"An error occurred: {e}")
        return None, None


def open_vivo_music():
    start_app("com.android.bbkmusic") # 打开Vivo音乐APP
    sleep(3.0)
    wait(Template(r"tpl1717383100103.png", record_pos=(-0.376, -0.051), resolution=(720, 1440)))
    touch(Template(r"tpl1717383106988.png", record_pos=(-0.375, -0.044), resolution=(720, 1440)))
    sleep(3.0)
    print("已打开Vivo的i音乐APP了")


def open_xiaomi_music():
    start_app("com.miui.player") # 打开小米音乐APP
    sleep(3.0)
    wait(Template(r"tpl1717383819774.png", record_pos=(-0.196, -0.251), resolution=(1080, 2400)))
    touch(Template(r"tpl1717383706465.png", record_pos=(-0.194, -0.242), resolution=(1080, 2400)))
    sleep(3.0)
    print("已打开小米的音乐APP了")


def open_huawei_music():
    start_app("com.android.mediacenter") # 打开华为音乐APP
    sleep(3.0)
    wait(Template(r"tpl1717384154362.png", record_pos=(-0.388, 0.02), resolution=(1080, 2340)))
    touch(Template(r"tpl1717384181392.png", record_pos=(-0.331, 0.439), resolution=(1080, 2340)))
    sleep(3.0)
    print("已打开华为的音乐APP了")


def print_device_info(brand, model):
    if brand and model:
        print(f"当前设备品牌: {brand}") # 打印当前设备品牌
        print(f"当前设备型号: {model}") # 打印当前设备型号
        sleep(3.0)
    else:
        print("无法获取设备品牌和型号") # 打印无法获取设备品牌和型号


if __name__ == "__main__":
    # 获取 Android 设备品牌和型号
    brand, model = get_android_device_info() # 获取设备品牌和型号
    print_device_info(brand, model)

    # 将打开各类品牌手机APP写成一个字典
    music_apps = {
        "HUAWEI": open_huawei_music, # 打开华为音乐APP
        "vivo": open_vivo_music, # 打开Vivo音乐APP
        "Xiaomi": open_xiaomi_music # 打开小米音乐APP
    }

    #在获取完设备品牌后,在字典内找到对应的方法并执行
    music_app = music_apps.get(brand)

    if music_app:
        music_app()
    else:
        print("没有该型号适用的方法") 

五、小结

我们本周推文主要是介绍了如何去分辨所连接的设备是 Android 设备还是 iOS 设备,以及如何分辨 Android 设备的厂商和型号,根据这些方式,我们可以结合自己的需求,进一步优化我们的测试脚本以及编写更具有通用性的脚本。
如果在测试的过程中,遇到了问题,或者有任何想要深入了解的知识点,欢迎在官方交流群(526033840)里告诉我们或者提交 issue,也欢迎大家投稿其他不同的使用小技巧。


AirtestIDE 下载:airtest.netease.com/\
Airtest 教程官网:airtest.doc.io.netease.com/\
搭建企业私有云服务:airlab.163.com/b2b

官方答疑 Q 群:526033840

共收到 7 条回复 时间 点赞

我有点疑问,你这是插上了什么设备就跑什么设备的用例?
我们的测试应该是按需执行的: 比如要发布一个 android 的新包,我们就会去安排对应 android 的回归测试(自动化 + 手工),然后启动对应的 android 脚本执行测试。

Jerry li 回复

是的,我们例子就是这个思路,你可以根据我们提供的一些接口以及方式去改进适合你所需要的脚本,有些应用在 Android 设备上表现基本一致,但有一些部分操作不同,这个时候就可以直接区分开来去执行

fishfish-yu 回复

不好意思,我不是想咨询怎么做兼容性测试,只是好奇你这里举的例子是不是符合真实的项目测试需要。

Jerry li 回复

当然是符合的,你是觉得哪里有不合理的地方吗?

fishfish-yu 回复

从软件测试的角度看你的例子:

  1. 我要测试的对象是明确的,比如要测试网易云音乐, 对应的用例都是针对这个 app 的,不会像你的例子一样,每种不同的手机就打开对应自带的音乐播放器。 也就是测试对象不明确。
  2. 我的测试范围是明确的。 比如我负责的是网易云音乐 app 的测试,就是需要甄选不同的用例列表,然后通过不同的用例集,去启动对应的手机执行这些测试。 也就是我需要测试 iOS 上的云音乐 app,就是去链接某台 iPhone,启动这个 app,然后开始执行;而不会像你例子里的一样,先判断当前连的是什么手机,什么机型,才去执行对应的用例。 举个例子来说,假如练了一百台都是小米的手机,你就把同一个用例在小米手机里面测了一百遍,而其他机型则一次也测不到。 这是不符合实际使用情况的。

所以我认为你这个只能算是 demo, 告诉别人怎么连不同机型,怎么打开不同的 app;但和怎么做兼容性测试没太大关系。

Jerry li 回复

当然是不符合真实项目需求的脚本呀,我们只是针对用户提出的某个知识点,设计的一个小案例而已,我们所有推文都是这个风格的,如果你需要真实项目 demo,可以多上 git 看看,很多大佬会分享一些出来的

fishfish-yu 回复

😂 所以你四楼的答案就是 “不符合” 了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册