Appium自动化常用adb操作封装

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: Appium自动化常用adb操作封装

一、前置说明


在Appium自动化中,经常需要使用adb命令与设备进行交互,所以有必要把常用的adb操作封装成一个类


二、代码实现


import os
import platform
import re
import subprocess
from common import path
from common.exception import AndroidSDKUninstalledError, AndroidDevicesNotFoundError
from common.logger import logger
class ADBRunner:
    def __init__(self):
        self._check_adb_is_installed()
    @staticmethod
    def run_adb(command):
        try:
            result = subprocess.run(command, capture_output=True, text=True, check=True, shell=True)
            logger.debug(f"Execute adb command: {command}")
            return result.stdout.strip()
        except subprocess.CalledProcessError as e:
            logger.error(f"Execute adb command failure: {e}")
            return None
    def _check_adb_is_installed(self):
        result = self.run_adb("adb --version")
        if not result:
            raise AndroidSDKUninstalledError('Android SDK is not installed or configured.')
        return result
    def adb_connect_device(self, device):
        return self.run_adb(f'adb connect {device}')
    def get_connected_device_udids(self):
        """
        获取所有连接设备的序列号udid
        """
        res = self.run_adb('adb devices')
        pattern = r'\b((?!of\b)\S+)\s+device'
        devices = re.findall(pattern, res)
        if not devices:
            raise AndroidDevicesNotFoundError('No connected mobile devices found.')
        logger.info(f'Devices found: {devices}')
        return devices
    @property
    def _grep(self):
        if platform.system() == 'Windows':
            return 'findstr'
        else:
            return 'grep'
    def get_activities(self, udid=None):
        """
        获取当前设备的所有top activities, 输出结果示例:
        ['com.android.settings/.Settings c4e2e17 pid=3637',
        'com.mumu.launcher/.Launcher 9392da7 pid=1434',
        'com.android.browser/com.android.settings de68b73 pid=3722']
        """
        if not udid:
            udid = self.get_connected_device_udids()[0]
        command = f'adb -s {udid} shell dumpsys activity top | {self._grep} ACTIVITY'
        tops = self.run_adb(command).split('ACTIVITY')
        tops = [top.strip(' ').strip('\n') for top in tops if top]
        logger.debug(f'The top activities on device {udid} are: {tops}')
        return tops
    def get_app_package_and_activity(self, udid=None):
        """
        从 com.android.settings/.Settings c4e2e17 pid=3637,获取包名和活动页面名称
        输出:['com.android.settings', '.Settings']
        用途:
            capabilities = {
                "platformName": "Android",
                "automationName": "uiautomator2",
                "deviceName": "9YS0220306003185",
                "appPackage": "com.tencent.mm",  # 包名
                "appActivity": ".ui.LauncherUI",  # 活动页面名称
            }
        """
        last_activity_info = self.get_activities(udid)[-1]
        pattern = r'(\S+) (\S+) pid=(\d+)'
        match = re.match(pattern, last_activity_info)
        if match:
            package, activity = match.group(1).split('/')
            return [package, activity]
        else:
            raise
    def get_apk_path(self, package_name, udid=None):
        """
        从设备中使用包名,获取应用程序的APK路径。
        """
        if not udid:
            udid = self.get_connected_device_udids()[0]
        # 使用pm path命令获取应用程序的APK路径
        command = f'adb -s {udid} shell pm path {package_name}'
        result = self.run_adb(command)
        if result and result.startswith('package:'):
            apk_path = result.replace('package:', '').strip()
            return apk_path
        else:
            logger.error(f"APK path for package '{package_name}' not found on the device {udid}.")
            return None
    def get_apk_version(self, package_name, udid=None):
        """
        获取应用程序的版本号。
        """
        if not udid:
            udid = self.get_connected_device_udids()[0]
        # 使用dumpsys package命令获取应用程序的版本号
        command = f'adb -s {udid} shell dumpsys package {package_name} | {self._grep} versionCode'
        result = self.run_adb(command)
        match = re.search(r'versionCode=(\d+)', result)
        if match:
            version_code = match.group(1)
            return version_code
        else:
            logger.error(f"Version code not found for package '{package_name}'.")
            return None
    def pull_apk_from_device(self, package_name, output_dir=None, apk_name=None, udid=None):
        """
        根据包名从当前设备中将应用程序的APK文件复制至本地。
        用于:
            capabilities = {
                "platformName": "Android",
                "automationName": "uiautomator2",
                "deviceName": "9YS0220306003185",
                "app": apk_path,  # 用在这里
                # "appPackage": "com.tencent.mm",
                # "appActivity": ".ui.LauncherUI",
            }
        """
        if not udid:
            udid = self.get_connected_device_udids()[0]
        if not output_dir:
            output_dir = path.get_apk_resources_dir()
        # 获取应用程序的APK路径
        apk_path = self.get_apk_path(package_name)
        apk_name = apk_name if apk_name else package_name
        apk_version = self.get_apk_version(package_name)
        if apk_path:
            # 构建本地输出路径
            local_output_path = os.path.join(output_dir, f"{apk_name}_{apk_version}.apk")
            # 使用adb pull命令将APK复制到本地
            command = f'adb -s {udid} pull {apk_path} {local_output_path}'
            result = self.run_adb(command)
            if result:
                logger.info(f"APK successfully pulled to: {local_output_path}")
                return local_output_path
            else:
                logger.error("Failed to pull APK from device.")
if __name__ == '__main__':
    adb = ADBRunner()
    print(adb.get_connected_device_udids())
    print(adb.get_app_package_and_activity())
    print(adb.get_apk_path('cn.com.open.mooc'))
    print(adb.get_apk_version('cn.com.open.mooc'))
    print(adb.pull_apk_from_device('cn.com.open.mooc'))
相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
目录
相关文章
|
1月前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
86 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
2月前
|
Java 测试技术 C#
自动化测试之美:从Selenium到Appium
【10月更文挑战第3天】在软件开发的海洋中,自动化测试如同一艘航船,引领着质量保证的方向。本文将带你领略自动化测试的魅力,从Web端的Selenium到移动端的Appium,我们将一探究竟,看看这些工具如何帮助我们高效地进行软件测试。你将了解到,自动化测试不仅仅是技术的展示,更是一种提升开发效率和产品质量的智慧选择。让我们一起启航,探索自动化测试的世界!
|
3月前
|
敏捷开发 Java 测试技术
探索自动化测试的奥秘:从Selenium到Appium
【9月更文挑战第14天】软件测试,这个看似枯燥乏味却至关重要的领域,正经历着一场革命。随着技术的进步,自动化测试工具如Selenium和Appium已成为质量保证的利器。本文将带你一探这些工具的神秘面纱,了解它们如何简化测试流程、提升效率,并确保软件产品的质量。准备好,我们将深入自动化测试的世界,解锁其背后的原理和实践技巧。
|
4月前
|
测试技术 Android开发 iOS开发
Appium 是一个开源的自动化测试框架,它支持多种平台和多种编程语言
Appium是一款开源自动化测试框架,支持iOS和Android多平台及多种编程语言。通过WebDriver协议,开发者可编写自动化测试脚本。在iPhone上实现屏幕点击等操作需安装Appium及其依赖,启动服务器,并设置所需的测试环境参数。利用Python等语言编写测试脚本,模拟用户交互行为,最后运行测试脚本来验证应用功能。对于iPhone测试,需准备真实设备或Xcode模拟器。
133 1
|
4月前
|
Java 测试技术 API
探索自动化测试的奥秘:从Selenium到Appium
【8月更文挑战第31天】本文旨在引导读者理解自动化测试的重要性,并逐步深入介绍如何利用Selenium和Appium这两个强大的工具来提升测试效率和质量。文章不仅分享理论知识,还通过具体代码示例,展示如何在Web应用和移动应用测试中实施自动化策略。
|
4月前
|
测试技术 Android开发 iOS开发
探索自动化测试的奥秘:从Selenium到Appium
【8月更文挑战第31天】在软件测试的海洋中,自动化测试如同一艘快艇,带领我们高效地穿越波涛汹涌的手动测试海域。本文将带你从Selenium的网页自动化测试出发,一路驶向Appium的移动应用自动化测试岛屿,揭秘这两种工具如何改变软件测试的航向。你将看到代码示例的灯塔,指引你理解它们如何在实战中发挥作用,以及为什么掌握这些技能对于测试人员来说至关重要。
|
4月前
|
Java 测试技术 Android开发
探索自动化测试之美:从Selenium到Appium
【8月更文挑战第31天】在软件开发的世界中,测试是确保产品质量的关键步骤。随着技术的发展,自动化测试工具如Selenium和Appium成为了开发者的得力助手。本文将通过一个简单的代码示例,带领读者了解如何利用这些工具进行高效的自动化测试,确保软件的稳定性和可靠性,同时也让测试过程变得更加轻松有趣。
|
7月前
|
Shell Android开发
Android系统 adb shell push/pull 禁止特定文件
Android系统 adb shell push/pull 禁止特定文件
594 1
|
7月前
|
Android开发 Python
Python封装ADB获取Android设备wifi地址的方法
Python封装ADB获取Android设备wifi地址的方法
156 0
|
4月前
|
Shell Linux 开发工具
"开发者的救星:揭秘如何用adb神器征服Android设备,开启高效调试之旅!"
【8月更文挑战第20天】Android Debug Bridge (adb) 是 Android 开发者必备工具,用于实现计算机与 Android 设备间通讯,执行调试及命令操作。adb 提供了丰富的命令行接口,覆盖从基础设备管理到复杂系统操作的需求。本文详细介绍 adb 的安装配置流程,并列举实用命令示例,包括设备连接管理、应用安装调试、文件系统访问等基础功能,以及端口转发、日志查看等高级技巧。此外,还提供了常见问题的故障排除指南,帮助开发者快速解决问题。掌握 adb 将极大提升 Android 开发效率,助力项目顺利推进。
106 0