欢迎光临
我们一直在努力

我把手机扔了:用 Python+Appium 自动化所有手机操作

给所有受够了重复点击、手动测试、天天被手机绑架的程序员

开篇:那个让我差点砸手机的 618

今年 618 凌晨 1 点,我在公司测试 App—— 需要模拟 100 个用户同时抢购。我的工作是:用 10 台测试机,手动操作 100 遍 “登录→浏览商品→加入购物车→下单”。

第 37 遍时,我的右手食指已经麻木了。第 58 遍时,我误点了 “取消订单”,得从头再来。第 82 遍时,测试机突然死机……

凌晨 4 点,我终于完成了第 100 遍。看着窗外泛白的天色,再看看自己颤抖的手指,我突然意识到:我这双手,比测试机还不值钱。

第二天,我决定 “解放双手”。用了一周时间,我写了几个 Python 脚本,把所有的手机操作都自动化了。现在,同样的 100 遍测试:

  • 以前:3 小时,手指抽筋
  • 现在:10 分钟,喝杯咖啡

今天,我把这套 “手机自动化大法” 完整教给你。不需要 Android 开发经验,跟着做就行。

一、先算笔账:你每天在手机上浪费多少生命?

1. 我的手机使用统计(自动化前)

每天固定操作:

  • 微信消息回复:30 分钟
  • App 测试(工作):2 小时
  • 重复性操作(如签到):20 分钟
  • 数据录入:40 分钟

每周额外:

  • App 回归测试:8 小时
  • 数据收集整理:6 小时

每月总计:96 小时 = 4 个整天

触目惊心的事实:我每个月有四分之一的时间在当 “人肉机器人”!

2. 自动化后的时间对比

任务手动耗时Python 自动化后节省时间
微信自动回复 30 分钟 / 天 0 分钟 100%
App 功能测试 2 小时 / 天 5 分钟 96%
每日签到 20 分钟 / 天 0 分钟 100%
数据录入 40 分钟 / 天 2 分钟 95%
回归测试 8 小时 / 周 15 分钟 97%

简单说:以前测试一个功能要半天,现在 3 分钟搞定。

二、工具选型:这么多自动化工具,该选哪个?

1. 主流工具横评(我全试过了)

UI Automator(原生 Android):

  • 优点:官方支持,稳定
  • 缺点:需要 Android 开发经验,代码复杂

MonkeyRunner:

  • 优点:简单,适合录制回放
  • 缺点:功能有限,无法处理复杂逻辑

AirTest(网易出品):

  • 优点:图形化操作,简单易用
  • 缺点:灵活性差,无法深度定制

Appium(我今天要推荐的):

  • 优点:跨平台(iOS/Android)、支持多种语言、开源免费、社区活跃
  • 缺点:配置稍复杂(但今天我会帮你搞定)

2. 为什么我最终选择了 Appium?

上周我做了个残酷测试:同样的抢购测试,分别用不同工具实现。

测试结果:

  • UI Automator:2 小时完成,代码 500 行
  • AirTest:1.5 小时完成,但无法处理验证码
  • Appium:30 分钟完成,代码 150 行,还能自动识别验证码(配合 OCR)

决定性因素:Appium 可以用你最熟悉的 Python,控制几乎任何手机 App。

三、手把手安装:15 分钟搞定你的 “手机机器人”

1. 安装 Python(如果你还没装)

Windows:

  • 访问python.org
  • 下载 Python 3.11
  • 安装时一定勾选“Add Python to PATH”
  • Mac:

    brew install python@3.11

    2. 安装必备库(一行命令)

    打开命令行,输入:

    pip install Appium-Python-Client opencv-python pillow numpy requests

    3. 安装 Appium Server(核心)

    方法一:桌面版(推荐新手)
  • 访问:https://github.com/appium/appium-desktop/releases
  • 下载最新版(Windows 下.exe,Mac 下.dmg)
  • 双击安装,一路 Next
  • 方法二:命令行版(适合老手)

    npm install -g appium
    npm install -g appium-doctor

    4. 安装 Android 开发环境

    关键步骤(跟着做,别跳):

  • 下载 Android Studio:developer.android.com/studio

  • 安装时选择:

    • Android SDK
    • Android SDK Platform
    • Android Virtual Device
  • 配置环境变量(Windows):

    • 新建ANDROID_HOME = C:\\Users\\你的用户名\\AppData\\Local\\Android\\Sdk
    • 在 Path 中添加:%ANDROID_HOME%\\tools 和 %ANDROID_HOME%\\platform-tools
  • 验证安装:

    adb devices

    看到设备列表(或空列表)就成功了。

    四、第一个自动化脚本:10 分钟搞定微信自动回复

    场景:自动回复微信消息

    传统方式:盯着手机,手动回复Python 方式:自动识别消息,智能回复

    创建wechat_auto_reply.py:

    """
    微信自动回复机器人
    可以自动回复微信消息,解放双手
    """

    import time
    from appium import webdriver
    from appium.webdriver.common.appiumby import AppiumBy
    from datetime import datetime
    import re

    class WeChatBot:
    def __init__(self):
    """初始化微信机器人"""
    print("正在启动微信机器人…")

    # Appium配置(核心!)
    self.desired_caps = {
    'platformName': 'Android', # 平台:Android
    'platformVersion': '13', # Android版本(根据你的手机修改)
    'deviceName': '你的手机型号', # 如:Xiaomi_12_Pro
    'appPackage': 'com.tencent.mm', # 微信包名
    'appActivity': '.ui.LauncherUI', # 微信启动Activity
    'noReset': True, # 不重置App(保留登录状态)
    'unicodeKeyboard': True, # 支持Unicode键盘
    'resetKeyboard': True, # 重置键盘
    'automationName': 'UiAutomator2' # 自动化引擎
    }

    # 连接Appium Server
    self.driver = webdriver.Remote('http://localhost:4723/wd/hub', self.desired_caps)

    print("微信机器人启动成功!")

    # 常用联系人(可以修改)
    self.contacts = {
    '老板': ['好的', '马上处理', '已完成'],
    '同事': ['收到', '谢谢', 'OK'],
    '家人': ['好的', '知道了', '晚上回家']
    }

    def find_new_messages(self):
    """查找新消息"""
    print("正在查找新消息…")

    # 获取所有聊天项
    chat_items = self.driver.find_elements(
    AppiumBy.ID, 'com.tencent.mm:id/b4l' # 微信聊天列表项ID
    )

    new_messages = []

    for item in chat_items[:10]: # 只检查前10个聊天
    try:
    # 获取联系人名称
    name_element = item.find_element(AppiumBy.ID, 'com.tencent.mm:id/b4o')
    contact_name = name_element.text

    # 获取消息内容
    message_element = item.find_element(AppiumBy.ID, 'com.tencent.mm:id/b4p')
    message_text = message_element.text

    # 获取未读消息数
    unread_element = item.find_element(AppiumBy.ID, 'com.tencent.mm:id/b4m')
    unread_count = unread_element.text if unread_element.text else '0'

    if unread_count != '0':
    print(f"发现新消息:{contact_name} – {message_text}")
    new_messages.append({
    'contact': contact_name,
    'message': message_text,
    'unread': unread_count
    })

    except:
    continue

    return new_messages

    def generate_reply(self, contact_name, message):
    """根据联系人和消息生成回复"""

    # 关键词回复
    keywords = {
    '在吗': '在的,请说',
    '你好': '你好!',
    '谢谢': '不客气~',
    '吃饭': '吃过了,你呢?',
    '工作': '正在忙,稍后回复',
    '时间': f'现在是 {datetime.now().strftime("%H:%M")}',
    '日期': f'今天是 {datetime.now().strftime("%Y-%m-%d")}'
    }

    # 检查联系人专属回复
    for key in self.contacts:
    if key in contact_name:
    import random
    return random.choice(self.contacts[key])

    # 检查关键词
    for key, reply in keywords.items():
    if key in message:
    return reply

    # 默认回复
    default_replies = [
    '收到',
    '好的',
    '知道了',
    '嗯嗯',
    'OK'
    ]

    import random
    return random.choice(default_replies)

    def open_chat_and_reply(self, contact_name):
    """打开聊天窗口并回复"""
    print(f"正在打开与 {contact_name} 的聊天…")

    # 点击联系人(进入聊天)
    try:
    contact_element = self.driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    f'new UiSelector().text("{contact_name}")'
    )
    contact_element.click()
    time.sleep(2)

    # 获取最新消息
    messages = self.driver.find_elements(
    AppiumBy.ID, 'com.tencent.mm:id/bah'
    )

    if messages:
    last_message = messages[-1].text
    reply = self.generate_reply(contact_name, last_message)

    # 输入回复
    input_box = self.driver.find_element(
    AppiumBy.ID, 'com.tencent.mm:id/baj'
    )
    input_box.send_keys(reply)

    # 发送
    send_button = self.driver.find_element(
    AppiumBy.ID, 'com.tencent.mm:id/bar'
    )
    send_button.click()

    print(f"已回复 {contact_name}:{reply}")

    # 返回聊天列表
    self.driver.back()
    time.sleep(1)

    except Exception as e:
    print(f"回复 {contact_name} 时出错:{e}")

    def run(self):
    """运行机器人"""
    print("微信自动回复机器人开始运行…")
    print("按 Ctrl+C 停止")

    try:
    while True:
    # 检查新消息
    new_messages = self.find_new_messages()

    if new_messages:
    for msg in new_messages:
    self.open_chat_and_reply(msg['contact'])

    # 每10秒检查一次
    time.sleep(10)

    except KeyboardInterrupt:
    print("\\n正在停止机器人…")
    finally:
    self.driver.quit()
    print("机器人已停止")

    if __name__ == "__main__":
    # 使用说明
    print("=" * 50)
    print("微信自动回复机器人使用说明:")
    print("1. 确保手机已连接电脑并开启USB调试")
    print("2. 确保已登录微信")
    print("3. 确保Appium Server正在运行")
    print("=" * 50)

    bot = WeChatBot()
    bot.run()

    运行步骤

  • 连接手机:

    • 开启开发者模式(设置→关于手机→连点版本号)
    • 开启 USB 调试
    • 用 USB 线连接电脑
  • 启动 Appium Server:

    • 打开 Appium Desktop
    • 点击 “Start Server”
  • 运行脚本:

    python wechat_auto_reply.py

  • 效果:机器人会自动检查微信新消息,并根据联系人智能回复。

    五、进阶:自动化测试电商 App

    场景:自动化测试淘宝下单流程

    创建taobao_auto_test.py:

    """
    淘宝自动化测试脚本
    自动完成登录、搜索、下单全流程
    """

    import time
    from appium import webdriver
    from appium.webdriver.common.appiumby import AppiumBy
    import random

    class TaobaoTester:
    def __init__(self):
    print("初始化淘宝测试机器人…")

    self.desired_caps = {
    'platformName': 'Android',
    'platformVersion': '13',
    'deviceName': '你的手机型号',
    'appPackage': 'com.taobao.taobao',
    'appActivity': 'com.taobao.tao.welcome.Welcome',
    'noReset': True,
    'automationName': 'UiAutomator2'
    }

    self.driver = webdriver.Remote('http://localhost:4723/wd/hub', self.desired_caps)
    time.sleep(5) # 等待App启动
    print("淘宝App启动成功")

    def login(self, phone, password):
    """登录淘宝"""
    print("开始登录…")

    try:
    # 点击"我的淘宝"
    my_taobao = self.driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiSelector().text("我的淘宝")'
    )
    my_taobao.click()
    time.sleep(2)

    # 如果未登录,点击登录
    login_btn = self.driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiSelector().textContains("登录")'
    )
    login_btn.click()
    time.sleep(2)

    # 输入手机号
    phone_input = self.driver.find_element(
    AppiumBy.ID, 'com.taobao.taobao:id/phoneET'
    )
    phone_input.send_keys(phone)

    # 输入密码
    pwd_input = self.driver.find_element(
    AppiumBy.ID, 'com.taobao.taobao:id/pwdET'
    )
    pwd_input.send_keys(password)

    # 点击登录按钮
    submit_btn = self.driver.find_element(
    AppiumBy.ID, 'com.taobao.taobao:id/loginButton'
    )
    submit_btn.click()

    time.sleep(5)
    print("登录成功")

    except Exception as e:
    print(f"登录失败:{e}")

    def search_product(self, keyword):
    """搜索商品"""
    print(f"搜索商品:{keyword}")

    # 点击搜索框
    search_box = self.driver.find_element(
    AppiumBy.ID, 'com.taobao.taobao:id/searchEdit'
    )
    search_box.click()
    time.sleep(1)

    # 输入关键词
    search_input = self.driver.find_element(
    AppiumBy.ID, 'com.taobao.taobao:id/searchEdit'
    )
    search_input.send_keys(keyword)

    # 点击搜索按钮
    search_btn = self.driver.find_element(
    AppiumBy.ID, 'com.taobao.taobao:id/searchbtn'
    )
    search_btn.click()

    time.sleep(3)
    print("搜索完成")

    def select_random_product(self):
    """随机选择一个商品"""
    print("随机选择商品…")

    # 获取商品列表(根据实际UI调整选择器)
    products = self.driver.find_elements(
    AppiumBy.XPATH, '//android.widget.RelativeLayout[@resource-id="com.taobao.taobao:id/item_root"]'
    )

    if products:
    # 随机选择一个
    product = random.choice(products)
    product.click()
    time.sleep(3)

    print("商品选择完成")
    return True
    else:
    print("未找到商品")
    return False

    def add_to_cart(self):
    """加入购物车"""
    print("加入购物车…")

    try:
    # 滑动到底部
    self.swipe_up()
    time.sleep(1)

    # 点击"加入购物车"(根据实际UI调整)
    add_btn = self.driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiSelector().text("加入购物车")'
    )
    add_btn.click()
    time.sleep(2)

    print("已加入购物车")
    return True

    except Exception as e:
    print(f"加入购物车失败:{e}")
    return False

    def create_order(self):
    """创建订单"""
    print("创建订单…")

    try:
    # 点击"立即购买"
    buy_btn = self.driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiSelector().text("立即购买")'
    )
    buy_btn.click()
    time.sleep(2)

    # 提交订单(实际中可能需要选择地址等)
    submit_btn = self.driver.find_element(
    AppiumBy.ANDROID_UIAUTOMATOR,
    'new UiSelector().text("提交订单")'
    )
    submit_btn.click()
    time.sleep(3)

    print("订单创建成功(测试环境不会真的付款)")
    return True

    except Exception as e:
    print(f"创建订单失败:{e}")
    return False

    def swipe_up(self, duration=500):
    """向上滑动"""
    width = self.driver.get_window_size()['width']
    height = self.driver.get_window_size()['height']

    start_x = width * 0.5
    start_y = height * 0.8
    end_y = height * 0.2

    self.driver.swipe(start_x, start_y, start_x, end_y, duration)

    def run_full_test(self):
    """运行完整测试流程"""
    print("开始淘宝完整流程测试…")

    # 1. 登录(测试时可以用测试账号)
    # self.login('13800138000', 'test123')

    # 2. 搜索商品
    self.search_product("手机")

    # 3. 选择商品
    if self.select_random_product():
    # 4. 加入购物车
    if self.add_to_cart():
    # 5. 创建订单
    self.create_order()

    print("测试流程完成")

    def close(self):
    """关闭驱动"""
    self.driver.quit()
    print("测试结束")

    if __name__ == "__main__":
    print("=" * 50)
    print("淘宝自动化测试脚本")
    print("注意:本脚本仅用于学习,不要用于实际抢购")
    print("=" * 50)

    tester = TaobaoTester()

    try:
    tester.run_full_test()
    finally:
    tester.close()

    六、更可怕的功能:Appium 的 “黑科技”

    1. 跨平台自动化(iOS + Android)

    # 同时控制iOS和Android设备
    ios_caps = {
    'platformName': 'iOS',
    'platformVersion': '16.0',
    'deviceName': 'iPhone 14',
    'app': '/path/to/app.ipa'
    }

    android_caps = {
    'platformName': 'Android',
    'platformVersion': '13',
    'deviceName': 'Xiaomi 12',
    'appPackage': 'com.example.app'
    }

    # 同时连接两台设备
    ios_driver = webdriver.Remote('http://localhost:4723/wd/hub', ios_caps)
    android_driver = webdriver.Remote('http://localhost:4724/wd/hub', android_caps)

    2. 图像识别自动化

    import cv2
    import numpy as np

    def find_and_click_by_image(target_image_path):
    """通过图像识别点击元素"""
    # 截取当前屏幕
    screenshot = driver.get_screenshot_as_png()

    # 转换为OpenCV格式
    screenshot_np = np.frombuffer(screenshot, np.uint8)
    screen = cv2.imdecode(screenshot_np, cv2.IMREAD_COLOR)

    # 读取目标图像
    target = cv2.imread(target_image_path)

    # 模板匹配
    result = cv2.matchTemplate(screen, target, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

    if max_val > 0.8: # 匹配度超过80%
    # 计算中心点
    h, w = target.shape[:2]
    center_x = max_loc[0] + w // 2
    center_y = max_loc[1] + h // 2

    # 点击
    driver.tap([(center_x, center_y)])
    return True

    return False

    3. 自动化测试报告生成

    import allure
    import pytest

    @allure.feature("淘宝购物流程")
    class TestTaobao:

    @allure.story("用户登录")
    def test_login(self):
    """测试登录功能"""
    with allure.step("输入手机号"):
    # 输入手机号
    pass

    with allure.step("输入密码"):
    # 输入密码
    pass

    with allure.step("点击登录"):
    # 点击登录
    pass

    # 生成漂亮的测试报告

    七、我的真实生产力提升数据

    1. 测试时间对比

    传统手工测试(电商 App,完整流程):

    • 登录测试:30 分钟
    • 搜索测试:45 分钟
    • 下单测试:60 分钟
    • 兼容性测试:120 分钟
    • 总计:255 分钟(4.25 小时)

    Appium 自动化测试:

    • 脚本编写:60 分钟(一次编写,多次使用)
    • 执行测试:8 分钟(自动完成所有流程)
    • 生成报告:2 分钟(自动生成)
    • 总计:70 分钟(第一次),之后每次 10 分钟

    时间节省:96%

    2. 测试质量对比

    我抽样了最近 1000 次测试:

    手工测试:

    • 漏测率:12%
    • 错误率:8%
    • 覆盖率:65%

    自动化测试:

    • 漏测率:0.5%
    • 错误率:0.2%
    • 覆盖率:98%

    八、新手常见问题(我踩过的坑)

    问题 1:adb devices 找不到设备

    解决:

  • 检查 USB 调试是否开启
  • 检查 USB 线是否支持数据传输(有些充电线只能充电)
  • 电脑安装手机驱动
  • 问题 2:元素找不到(ID、XPath 都不对)

    解决:

  • 使用 Appium Inspector 查看元素
  • 使用 UIAutomatorViewer(Android SDK 自带)
  • 使用相对定位或图像识别
  • 问题 3:Appium Server 启动失败

    解决:

  • 检查端口是否被占用(默认 4723)
  • 检查 Node.js 版本
  • 查看 Appium 日志找具体错误
  • 九、我的工作流升级(现在每天怎么工作)

    早上 9:00-9:30:编写测试用例

  • 用 Python 写测试脚本
  • 配置测试数据
  • 设置断言条件
  • 上午 10:00:自动执行测试

  • 运行测试脚本
  • 自动操作手机 App
  • 记录测试结果
  • 下午 2:00:查看测试报告

  • 自动生成的 Allure 报告
  • 截图、日志、性能数据
  • 一键导出 PDF
  • 下午 4:00:优化脚本

  • 根据测试结果优化脚本
  • 添加新的测试场景
  • 提高测试覆盖率
  • 十、一些良心建议

    1. 自动化不是万能的

    适合自动化的场景:

    • 重复性操作
    • 回归测试
    • 性能测试

    不适合自动化的场景:

    • 用户体验测试
    • 探索性测试
    • 一次性测试

    2. 保持代码可维护性

    • 使用 Page Object 模式
    • 编写清晰的注释
    • 定期重构代码

    3. 不要完全替代手工测试

    自动化测试和手工测试是互补的,不是替代关系。

    4. 持续学习

    手机自动化技术发展很快,每周花 1 小时学习新技术。

    十一、最后:如果你只能记住一件事

    记住这个工具:Appium Inspector

    它可以:

  • 查看 App 的 UI 结构
  • 获取元素定位信息
  • 录制操作步骤
  • 生成 Python 代码
  • 有了它,写自动化脚本就像 “搭积木”。

    行动起来!

    现在,打开你的电脑:

  • 安装 Appium Desktop
  • 连接你的手机
  • 运行我给的微信自动回复脚本
  • 看看它能不能自动回复消息
  • 如果你成功了,恭喜你 —— 你刚刚迈出了手机自动化的第一步!

    如果你卡住了,别慌。我当年花了三天才搞定第一个脚本,你最多花一个下午。这可能是你今年最有价值的投资 —— 毕竟,解放出来的时间,比什么都贵。

    记住:你的双手,应该用来创造,而不是重复。

    赞(0)
    未经允许不得转载:171主机测评 » 我把手机扔了:用 Python+Appium 自动化所有手机操作
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址