Android Uiautomator2 Python Wrapper与Selenium Grid集成:分布式测试方案

Android Uiautomator2 Python Wrapper与Selenium Grid集成:分布式测试方案

【免费下载链接】uiautomator2 Android Uiautomator2 Python Wrapper 【免费下载链接】uiautomator2 项目地址: https://gitcode.com/gh_mirrors/ui/uiautomator2

1. 分布式测试的痛点与解决方案

1.1 移动自动化测试的挑战

在移动应用测试中,单一设备测试面临三大核心痛点:

  • 设备碎片化:Android设备型号、系统版本、分辨率组合超过1000种
  • 测试效率低下:单设备执行1000个用例需8小时,多设备并行可缩短至1小时
  • 资源利用率不足:开发机闲置时测试资源浪费

1.2 集成架构概览

mermaid

2. 环境准备与核心依赖

2.1 软件版本要求

组件最低版本推荐版本
Python3.63.9+
Uiautomator22.0.02.16.0+
Selenium3.141.04.4.3+
Selenium Grid3.141.04.4.3+
Adb1.0.411.0.41+

2.2 安装核心库

# 克隆项目仓库
git clone https://gitcode.com/gh_mirrors/ui/uiautomator2.git
cd uiautomator2

# 安装依赖
pip install -e .
pip install selenium==4.4.3

3. Selenium Grid节点配置

3.1 自定义Uiautomator2远程驱动

from appium import webdriver
from uiautomator2 import Device

class Uiautomator2RemoteDriver:
    def __init__(self, command_executor, desired_capabilities):
        self.command_executor = command_executor
        self.desired_capabilities = desired_capabilities
        self.device = self._init_device()

    def _init_device(self):
        # 从capabilities获取设备序列号
        serial = self.desired_capabilities.get('udid')
        if not serial:
            raise ValueError("设备序列号(udid)必须在capabilities中指定")
            
        # 初始化Uiautomator2设备连接
        d = Device(serial)
        d.wait_ready(timeout=30)
        return d

    def find_element(self, by, value):
        # 实现元素查找逻辑
        if by == 'xpath':
            return self.device.xpath(value).get()
        raise NotImplementedError(f"查找方式 {by} 暂未实现")
        
    def click(self, x, y):
        self.device.click(x, y)
        
    def swipe(self, fx, fy, tx, ty, duration=0.5):
        self.device.swipe(fx, fy, tx, ty, duration)

3.2 Selenium Grid节点配置文件

创建uiautomator2-node-config.json

{
  "capabilities": [
    {
      "browserName": "Android",
      "platformName": "Android",
      "automationName": "Uiautomator2",
      "maxInstances": 5,
      "udid": "emulator-5554",
      "deviceName": "Pixel_6_Pro_API_30"
    },
    {
      "browserName": "Android",
      "platformName": "Android",
      "automationName": "Uiautomator2",
      "maxInstances": 5,
      "udid": "R58M95xxxx",
      "deviceName": "Galaxy_S21"
    }
  ],
  "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
  "maxSession": 10,
  "port": 5555,
  "register": true,
  "registerCycle": 5000,
  "hubHost": "192.168.1.100",
  "hubPort": 4444
}

4. 启动与管理Selenium Grid集群

4.1 启动Hub节点

# 下载Selenium Server
wget https://repo1.maven.org/maven2/org/openqa/selenium/selenium-server/4.4.3/selenium-server-4.4.3.jar

# 启动Hub
java -jar selenium-server-4.4.3.jar hub --port 4444

4.2 启动Uiautomator2节点

# 启动节点(确保已安装Java 8+)
java -jar selenium-server-4.4.3.jar node \
  --config uiautomator2-node-config.json \
  --selenium-manager true

4.3 验证集群状态

访问Grid控制台:http://localhost:4444/ui/index.html,应显示所有注册的Android设备节点。

5. 核心API封装与使用

5.1 分布式测试客户端实现

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class Uiautomator2GridClient:
    def __init__(self, hub_url):
        self.hub_url = hub_url
        self.driver = None
        
    def connect(self, device_name=None, platform_version=None):
        # 配置Desired Capabilities
        caps = DesiredCapabilities.ANDROID.copy()
        caps['automationName'] = 'Uiautomator2'
        caps['platformName'] = 'Android'
        if device_name:
            caps['deviceName'] = device_name
        if platform_version:
            caps['platformVersion'] = platform_version
            
        # 连接到Selenium Grid
        self.driver = webdriver.Remote(
            command_executor=self.hub_url,
            desired_capabilities=caps
        )
        return self.driver
        
    def run_test_case(self, test_func):
        try:
            test_func(self.driver)
            return True, "测试通过"
        except Exception as e:
            return False, str(e)
        finally:
            if self.driver:
                self.driver.quit()

5.2 元素定位与操作示例

def test_wechat_login(driver):
    # 使用XPath定位元素(Uiautomator2核心功能)
    driver.find_element_by_xpath('//*[@text="登录"]').click()
    
    # 输入账号密码(使用Uiautomator2的send_keys方法)
    driver.find_element_by_xpath('//*[@resource-id="com.tencent.mm:id/et_username"]').send_keys("test_account")
    driver.find_element_by_xpath('//*[@resource-id="com.tencent.mm:id/et_password"]').send_keys("test_password")
    
    # 点击登录按钮(使用Uiautomator2的click方法)
    driver.find_element_by_xpath('//*[@text="登录"]').click()
    
    # 验证登录成功
    assert driver.find_element_by_xpath('//*[@text="微信"]').exists()

6. 测试任务分发与并行执行

6.1 动态设备分配策略

from concurrent.futures import ThreadPoolExecutor

def distribute_tests(hub_url, test_cases, max_workers=5):
    client = Uiautomator2GridClient(hub_url)
    
    # 使用线程池并行执行测试
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 提交所有测试任务
        futures = [
            executor.submit(client.run_test_case, test_case)
            for test_case in test_cases
        ]
        
        # 获取执行结果
        results = []
        for future in futures:
            results.append(future.result())
            
    return results

# 测试用例列表
test_suite = [
    test_wechat_login,
    test_wechat_send_message,
    test_wechat_pay
]

# 执行分布式测试
results = distribute_tests("http://192.168.1.100:4444/wd/hub", test_suite)

6.2 负载均衡与任务优先级

mermaid

7. 结果收集与报告生成

7.1 集成HTML测试报告

from uiautomator2.ext.htmlreport import HTMLReport

def run_with_report(driver, test_func, report_dir="distributed_report"):
    # 初始化报告生成器
    report = HTMLReport(driver, report_dir)
    report.patch_click()  # 自动记录点击操作
    
    try:
        # 执行测试并生成报告
        test_func(driver)
        report._addtosteps({"action": "测试完成", "status": "success"})
    except Exception as e:
        report._addtosteps({"action": f"测试失败: {str(e)}", "status": "error"})
        raise
    finally:
        report._flush()  # 生成HTML报告

7.2 分布式日志聚合

import logging
from logging.handlers import RotatingFileHandler

def setup_logging(log_file="distributed_test.log", max_bytes=10*1024*1024, backup_count=5):
    # 配置日志聚合
    logger = logging.getLogger("uiautomator2_grid")
    logger.setLevel(logging.DEBUG)
    
    # 文件处理器
    file_handler = RotatingFileHandler(
        log_file, maxBytes=max_bytes, backupCount=backup_count
    )
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)
    
    # 控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    
    # 添加处理器
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)
    
    return logger

8. 高级优化与最佳实践

8.1 设备状态监控

def monitor_device_health(driver):
    """监控设备CPU、内存和网络状态"""
    device_info = driver.device.info()
    cpu_usage = driver.device.shell("top -n 1 | grep uiautomator").output
    memory_usage = driver.device.shell("dumpsys meminfo uiautomator").output
    
    return {
        "device": device_info,
        "cpu": cpu_usage,
        "memory": memory_usage,
        "timestamp": datetime.now().isoformat()
    }

8.2 异常处理与重试机制

def retry_on_failure(max_retries=3, delay=2):
    def decorator(test_func):
        def wrapper(driver):
            for attempt in range(max_retries):
                try:
                    return test_func(driver)
                except Exception as e:
                    if attempt == max_retries - 1:
                        raise
                    logger.warning(f"尝试 {attempt+1} 失败,重试中...")
                    time.sleep(delay)
        return wrapper
    return decorator

# 应用重试装饰器
@retry_on_failure(max_retries=3)
def test_unstable_feature(driver):
    # 可能不稳定的测试操作
    driver.find_element_by_xpath('//*[@text="不稳定元素"]').click()

9. 常见问题与解决方案

9.1 连接超时问题

问题场景解决方案
Uiautomator2 Server启动失败1. 检查设备是否授权
2. 执行uiautomator2 init重置服务
3. 检查设备存储空间
Selenium节点注册失败1. 验证Hub地址和端口可达性
2. 检查防火墙设置
3. 确保节点配置文件正确
设备响应缓慢1. 降低单个节点并发数
2. 增加设备资源(CPU/内存)
3. 优化测试用例,减少不必要操作

9.2 元素定位失败

  • 解决方案1:使用Uiautomator2的隐式等待

    driver.implicitly_wait(10)  # 设置10秒隐式等待
    
  • 解决方案2:结合XPath和坐标定位

    # 先尝试XPath定位,失败则使用坐标
    try:
        driver.find_element_by_xpath('//*[@text="按钮"]').click()
    except:
        driver.click(500, 1000)  # 直接坐标点击
    

10. 性能优化与扩展方向

10.1 测试效率优化策略

  1. 用例分层:将测试分为单元、集成、UI层,减少UI层测试数量
  2. 元素缓存:复用已定位元素,减少重复查找开销
  3. 并行粒度:按功能模块拆分测试套件,实现细粒度并行

10.2 未来扩展方向

  • 设备农场集成:对接AWS Device Farm、Firebase Test Lab等云设备平台
  • AI测试生成:使用机器学习分析UI变化,自动生成测试用例
  • 实时监控面板:构建设备状态和测试进度的实时可视化平台

【免费下载链接】uiautomator2 Android Uiautomator2 Python Wrapper 【免费下载链接】uiautomator2 项目地址: https://gitcode.com/gh_mirrors/ui/uiautomator2

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值