app自动化测试(七) 配置化&自动化获取启动参数+多设备运行app自动化

实践中发现,如果需要进行多机并发等情况时
执行机五花八门,各型号,各版本都有
如果配置针对每台机写死,工作量将非常的大,而且代码的通用性也不高。
其中执行机不同的地方在于 设备号及系统版本号。其余的参数是相同的,一份默认参数配置放置于yaml文件中
设备号可以通过adb 命令 "adb devices"中得到
系统版本号经过找了些资料也可以通过adb命令 "adb shell getprop ro.build.version.release" 得到系统版本号


image.png

翻了翻python的库发现 subprocess比os.system库好用,可以返回执行结果和错误信息

yaml文件:设置一个默认配置

automationName: UiAutomator2
platformName: Android
platformVersion: 7.1.2
deviceName: Android Emulator
appPackage: com.autonavi.minimap
appActivity: com.autonavi.map.activity.SplashActivity
noReset: True

实例:
获取设备名列表

In [1]: command = "adb devices"

In [2]: import subprocess

In [4]: out, err = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()

In [5]: print(out)  # bytes格式
b'List of devices attached\r\nemulator-5554\tdevice\r\n\r\n'

In [6]: print(err)
b''

In [7]: out = str(out, encoding="utf8")  # 转化为str格式

In [8]: print(out)
List of devices attached
emulator-5554   device

In [13]: out = out.strip()  # 去除头尾字符、空白符(包括\n、\r、\t、' ',即:换行、回车、制表符、空格)

In [14]: out = out.split("\r\n")  # \r\n → r\n 为换行符,按行为单位进行切片

In [15]: print(out)
['List of devices attached', 'emulator-5554\tdevice']

In [16]: out.remove("List of devices attached")  # 首行也含“device”,所以去除干扰信息

In [17]: uuid = []  # 声明用于存有效信息的列表

In [20]: for item in out:
    ...:     print(item)
    ...:     if "device" in item:  # 判断设备是否为"device"这种正常状态
    ...:         item = item.split("\t")  # 将这行信息进行切片,以 \t制表符为单位
    ...:         print(item)
    ...:         uuid.append(item[0])  # 将切片好的设备名放入列表中
    ...: 
    ...: 
emulator-5554   device
['emulator-5554', 'device']



In [21]: print(uuid)
['emulator-5554']

In [22]: print(uuid[0])  # 使用时对列表进行遍历即可
'emulator-5554'

获取系统版本号列表

In [27]: uuid
Out[27]: ['emulator-5554']

In [28]: command = "adb -s {} shell getprop ro.build.version.release"  # 通过指定设备号获取系统版本

In [33]: for id in uuid:
    ...:     out, err = subprocess.Popen(command.format(id), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
    ...:     print(out)
    ...:     out = str(out, encoding="utf8")
    ...:     b.append(out.strip("\r\n"))
    ...: 
'7.1.2\r\n'

In [34]: b
Out[34]: ['7.1.2']

In [39]: list(zip(uuid, b))
Out[39]: [('emulator-5554', '7.1.2')]  # 设备号与版本号的元组列表

cmd.py : 封装execute command的操作及信息

import subprocess


class Command:

    def cmd_run(self, command):
        try:
            out, err = \
                subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
            out = str(out, encoding="utf8").strip()
            err = str(err, encoding="uft8").strip()
            if err:
                raise Exception("run command error")
        except:
            raise
        else:
            return out

    def devices_and_version(self):
        devices_uuid = self.__get_devices()
        versions = self.__get_version()
        res = list(zip(devices_uuid, versions))
        return res

    def __get_devices(self):
        command = "adb devices"
        res = self.cmd_run(command)
        if "\r\n" in res:  # windows newline == \r\n  针对不同系统
            res = res.split("\r\n")
        if "\n" in res:  # linux newline == \n
            res = res.split("\n")
        res.remove("List of devices attached")
        devices = []
        for item in res:
            if "device" in item:
                device = item.split("\t")[0]
                devices.append(device)
        return devices

    def __get_version(self):
        uuids = self.__get_devices()
        command = "adb -s {} shell getprop ro.build.version.release"
        versions = []
        for uuid in uuids:
            version = self.cmd_run(command.format(uuid))
            versions.append(version)
        return versions


cmd = Command()
print(cmd.devices_and_version())

app自动化与GUI自动化多线程上有一点不同
app每次仅可启动一次,GUI浏览器对象可以启动多个
根据输入参数,灵活应用,自启动appium server服务
前提:安装appium server https://www.jianshu.com/p/2e06d1dc003c
appium server 命令行操作
start.py

import yaml
from appium import webdriver
from appium.webdriver.appium_service import AppiumService  # 用于启动appium server
from command import Command


def base_args(*port, **kwargs):
    file = "./conf/caps.yaml"  # 设定yaml文件
    with open(file, "r") as file:
        caps = yaml.full_load(file)
    cmd = Command()
    info = cmd.devices_and_version()
    n = 0
    if kwargs:
        for key, value in kwargs.items():
            caps[key] = value
    for res in info:  # 若需要多台机可在此处进行多线程操作,本实例只涉及多设备运行
        caps["deviceName"] = res[0]
        caps["platformVersion"] = res[1]
        service = AppiumService()  # 实例化对象
        if not port:  # 如果未指定port则默认
            port = ["4444"]
        service.start(args=["-a", "127.0.0.1", "-p", port[n], "--session-override"], timeout_ms=2000)  # 启动appium server 本来此处打算自己写的 后来发现appium库已经提供方法
        driver = webdriver.Remote(command_executor='http://127.0.0.1:{}/wd/hub'.format(port[n]),
                                  desired_capabilities=caps)
        yield driver  # 将驱动对象return出去
        service.stop()  # 关闭当前appium server

你可能感兴趣的:(app自动化测试(七) 配置化&自动化获取启动参数+多设备运行app自动化)