app 自动化测试 - 多设备并发 -appium+pytest+ 多线程
1、appium+python 实现单设备的 app 自动化测试启动 appium server,占用端口 4723电脑与一个设备连接,通过 adb devices 获取已连接的设备在 python 代码当中,编写启动参数,通过 pytes...
1、appium+python 实现单设备的 app 自动化测试
-
启动 appium server,占用端口 4723
-
电脑与一个设备连接,通过 adb devices 获取已连接的设备
-
在 python 代码当中,编写启动参数,通过 pytest 编写测试用例,来进行自动化测试。
2、若要多设备并发,同时执行自动化测试,那么需要:
-
确定设备个数
-
每个设备对应一个 appium server 的端口号,并启动 appium
-
pytest 要获取到每个设备的启动参数,然后执行自动化测试。
3、实现策略
第一步:从设备池当中,获取当前连接的设备。若设备池为空,则无设备连接。 第二步:若设备池不为空,启动一个线程,用来启动appium server.与设备个数对应。 起始server端口为4723,每多一个设备,端口号默认+4 第三步:若设备池不为空,则启用多个线程,来执行app自动化测试。
4、具体实现步骤
4.1 通过 adb 命令,获取当前已连接的设备数、设备名称、设备的安卓版本号。
定义一个 ManageDevices 类。
1. 重启adb服务。 2. 通过adb devices命令获取当前平台中,已连接的设备个数,和设备uuid. 3. 通过adb -P 5037 -s 设备uuid shell getprop ro.build.version.release获取每一个设备的版本号。 4. 将所有已连接设备的设备名称、设备版本号存储在一个列表当中。 5. 通过调用get_devices_info函数,即可获得4中的列表。
实现的部分代码为:
"""@Title : app多设备并发-appium+pytest@Author : 柠檬班-小简@Email : lemonban_simple@qq.com"""class ManageDevices:
""" 1、重启adb服务。 2、通过adb devices命令获取当前平台中,已连接的设备个数,和设备uuid. 3、通过adb -P 5037 -s 设备uuid shell getprop ro.build.version.release获取每一个设备的版本号。 4、将所有已连接设备的设备名称、设备版本号存储在一个列表当中。 5、通过调用get_devices_info函数,即可获得4中的列表。 """
def __init__(self):
self.__devices_info = []
# 重启adb服务
self.__run_command_and_get_stout("adb kill-server")
self.__run_command_and_get_stout("adb start-server")
def get_devices_info(self):
""" 获取已连接设备的uuid,和版本号。 :return: 所有已连接设备的uuid,和版本号。 """
self.__get_devices_uuid()
print(self.__devices_info)
self.__get_device_platform_vesion()
return self.__devices_info
4.2 定义一个设备配置池。
设备启动参数管理池。 每一个设备:对应一个启动参数,以及appium服务的端口号。 1. desired_caps_config/desired_caps.yaml文件中存储了启动参数模板。 2. 从1中的模板读取出启动参数。 3. 从设备列表当中,获取每个设备的设备uuid、版本号,与2中的启动参数合并。 4. 每一个设备,指定一个appium服务端口号。从4723开始,每多一个设备,默认递增4 5. 每一个设备,指定一个本地与设备tcp通信的端口号。从8200开始,每多一个设备,默认递增4. 在启动参数当中,通过systemPort指定。 因为appium服务会指定一个本地端口号,将数据转发到安卓设备上。 默认都是使用8200端口,当有多个appium服务时就会出现端口冲突。会导致运行过程中出现socket hang up的报错。
实现的部分代码:
def devices_pool(port=4723,system_port=8200):
""" 设备启动参数管理池。含启动参数和对应的端口号 :param port: appium服务的端口号。每一个设备对应一个。 :param system_port: appium服务指定的本地端口,用来转发数据给安卓设备。每一个设备对应一个。 :return: 所有已连接设备的启动参数和appium端口号。 """
desired_template = __get_yaml_data()
devs_pool = []
# 获取当前连接的所有设备信息
m = ManageDevices()
all_devices_info = m.get_devices_info()
# 补充每一个设备的启动信息,以及配置对应的appium server端口号
if all_devices_info:
for dev_info in all_devices_info:
dev_info.update(desired_template)
dev_info["systemPort"] = system_port
new_dict = {
"caps": dev_info,
"port": port
}
devs_pool.append(new_dict)
port += 4
system_port += 4
return devs_pool
特别注意事项:
2 个及 2 个以设备并发时,会遇到设备 socket hang up 的报错。
原因是什么呢:
在 appium server 的日志当中,有这样一行 adb 命令:
adb -P 5037 -s 08e7c5997d2a forward tcp\:8200 tcp\:6790
什么意思呢?
将本地 8200 端口的数据,转发到安卓设备的 6790 端口
所以,本地启动多个 appium server,都是用的 8200 端口,就会出现冲突。
解决方案:
应该设置为,每一个 appium server 用不同的本地端口号,去转发数据给不同的设备。
启动参数当中:添加 systemPort= 端口号 来设置。
这样,每个设备都使用不同的本地端口,那么可解决此问题。