一、前置说明
在自动化测试中,经常需要验证多台设备的兼容性,Appium可以用同一套测试运例并行测试多个设备,以达到验证兼容性的目的。
解决思路:
- 查找已连接的所有设备;
- 为每台设备启动相应的Appium Server;
- 使用多线程执行 pytest 命令;
二、核心代码
# test_multi_devices.py import pytest from driver.appium.manager import port_manager @pytest.fixture(scope="session") def devicename(request): return request.config.getoption("--devicename") @pytest.fixture def driver(devicename): from driver.appium.driver import WebDriver server_port = port_manager.get_server_port(devicename) trans_port = port_manager.get_trans_port(devicename) # appium 多设备并行注意事项: # 1. server_port: 必须传值,它是 appium server 的监听端口号,在启动多个 appium server的情况下,用于指定当前driver与哪个 server 进行通信; # 2. uuid: 必须传值,它是每个设备的唯一标识,用于appium server区分与哪台设备在通信,确保测试执行不会混淆; # 3. systemPort: 必须传值,是UiAutomator2 Server的6790端口绑定至本地的端口号,该端口用于在本地监听并接收从 UiAutomator2 Server 发出的请求; appium_server_url = f'http://localhost:{server_port}' capabilities = { "platformName": "Android", "automationName": "uiautomator2", "deviceName": devicename, "udid": devicename, "app": "D:\\resources\\ApiDemos-debug.apk", "systemPort": trans_port } driver = WebDriver(command_executor=appium_server_url, capabilities=capabilities) yield driver driver.quit() def test_runner(driver): driver.smart_find_element(by='text', value='App').click() driver.smart_find_element(by='text', value='Notification').click() driver.smart_find_element(by='text', value='NotifyWithText').click() driver.smart_find_element(by='text', value='SHOW SHORT NOTIFICATION').click() element = driver.get_toast('Short notification') assert element.text == 'Short notification'
# main.py import threading import pytest from driver.appium.manager import MobileDevicesManager, AppiumServersManager, device_manager from driver.appium.manager import port_manager PY_RUNNER = 'tests/test_multi_devices.py' def start_server_and_run_pytest(devicename): """ 启动Appium Server,并且执行pytest """ port = port_manager.get_server_port(devicename) # 为每台设备启动一个appium server server_manager = AppiumServersManager(port) server_manager.start_server() # 执行pytest pytest.main([PY_RUNNER, '-s', '-v', '--devicename', devicename]) def run_multi_devices(): """ 多设备并行测试 """ devices = device_manager.get_connected_devices() threads = [] for devicename in devices: thread = threading.Thread(target=start_server_and_run_pytest, args=(devicename,)) threads.append(thread) # 启动线程 thread.start() # 等待所有线程完成 for thread in threads: thread.join() if __name__ == '__main__': import logging.config logging.config.fileConfig('conf/logging.conf') # 执行并发测试 run_multi_devices()
三、Demo验证
当前有3台设备连接,执行代码,会启动3个appium server:
3台设备会同时执行测试(有1台为手机,不方便截图):
四、appium 多设备并行注意事项
# 1. server_port: 必须传值,它是 appium server 的监听端口号,在启动多个 appium server的情况下,用于指定当前driver与哪个 server 进行通信; # 2. uuid: 必须传值,它是每个设备的唯一标识,用于appium server区分与哪台设备在通信,确保测试执行不会混淆; # 3. systemPort: 必须传值,是UiAutomator2 Server的6790端口绑定至本地的端口号,该端口用于在本地监听并接收从 UiAutomator2 Server 发出的请求; appium_server_url = f'http://localhost:{server_port}' capabilities = { "platformName": "Android", "automationName": "uiautomator2", "deviceName": devicename, "udid": devicename, "app": "D:\\resources\\ApiDemos-debug.apk", "systemPort": trans_port } driver = WebDriver(command_executor=appium_server_url, capabilities=capabilities)