【测试】移动APP测试操作手册

文章目录

  • 移动APP测试实战
    • [一、ADB:Android 调试](#一、ADB:Android 调试)
      • [1.1 环境准备](#1.1 环境准备)
      • [1.2 安装与卸载](#1.2 安装与卸载)
      • [1.3 文件与日志](#1.3 文件与日志)
      • [1.4 应用管理](#1.4 应用管理)
      • [1.5 专项操作](#1.5 专项操作)
      • [1.6 ADB 常用场景速查](#1.6 ADB 常用场景速查)
    • [二、Charles:抓包 + 弱网](#二、Charles:抓包 + 弱网)
      • [2.1 HTTPS 抓包完整配置](#2.1 HTTPS 抓包完整配置)
      • [2.2 抓包实战技巧](#2.2 抓包实战技巧)
      • [2.3 弱网模拟配置](#2.3 弱网模拟配置)
    • 三、PerfDog:性能测试
      • [3.1 安装和连接](#3.1 安装和连接)
      • [3.2 核心指标解读](#3.2 核心指标解读)
      • [3.3 实战:检测内存泄漏](#3.3 实战:检测内存泄漏)
      • [3.4 标签功能(打点记录关键操作)](#3.4 标签功能(打点记录关键操作))
    • 四、Appium:UI自动化
      • [4.1 环境搭建](#4.1 环境搭建)
      • [4.2 编写第一个测试](#4.2 编写第一个测试)
      • [4.3 元素定位实战](#4.3 元素定位实战)
      • [4.4 Page Object 模式](#4.4 Page Object 模式)
      • [4.5 运行测试](#4.5 运行测试)
    • [五、JMeter 后端性能压测](#五、JMeter 后端性能压测)
      • [5.1 创建测试计划](#5.1 创建测试计划)
    • 六、一个版本的测试周期
    • 七、常用命令速查总表

移动APP测试实战

ADB命令调试、Charles抓包与弱网模拟、PerfDog性能监测、Appium自动化编写与执行、Battery Historian耗电分析、JMeter后端压测

一、ADB:Android 调试

ADB(Android Debug Bridge)是连接电脑和 Android 设备的桥梁。不管使用什么测试工具,底层都在调 ADB。能欧掌握ADB就是掌握了一切 Android 调试的入口。

1.1 环境准备

第一步:下载 Platform Tools

第二步:手机端开启 USB 调试

复制代码
设置 → 关于手机 → 连续点击"版本号"7次 → 开启"开发者选项"
→ 开发者选项 → 开启"USB调试"
→ 连接电脑 → 手机上弹出"允许USB调试" → 勾选"始终允许" → 确定

第三步:验证连接

bash 复制代码
# 查看已连接设备
adb devices

# 输出示例:
# List of devices attached
# 8BDAX00A32     device        ← 正常连接
# 8BDAX00A32     unauthorized  ← 手机上未点"允许"
# 8BDAX00A32     offline       ← 设备离线或ADB服务挂了

ADB 服务管理

bash 复制代码
adb kill-server       # 杀掉ADB服务(连接异常时先kill再start)
adb start-server      # 启动ADB服务
adb reconnect         # 重新连接设备(免拔线)

1.2 安装与卸载

bash 复制代码
# 安装APK
adb install app.apk                        # 普通安装
adb install -r app.apk                     # 覆盖安装(保留数据)
adb install -d app.apk                     # 降级安装
adb install -g app.apk                     # 安装时自动授予所有权限

# 卸载
adb uninstall com.example.app              # 卸载
adb uninstall -k com.example.app           # 卸载但保留数据和缓存

1.3 文件与日志

bash 复制代码
# 文件传输
adb push local_file /sdcard/               # 电脑→手机
adb pull /sdcard/remote_file ./            # 手机→电脑

# 截图和录屏
adb shell screencap /sdcard/screen.png     # 截图到手机
adb pull /sdcard/screen.png               # 拉到电脑
adb shell screenrecord /sdcard/video.mp4   # 录屏(Ctrl+C停止)

# 日志查看
adb logcat                                  # 实时日志(刷屏)
adb logcat -c                               # 清空日志缓冲区
adb logcat -s TAG                           # 只看指定TAG的日志
adb logcat | grep "ERROR"                   # 过滤ERROR日志
adb logcat -v time > crash_log.txt          # 带时间戳保存到文件
adb logcat -b crash                         # 只看崩溃日志

# APP专属日志
adb logcat --pid=$(adb shell pidof com.example.app)  # 只看目标APP的日志

1.4 应用管理

bash 复制代码
# 查看已安装应用列表
adb shell pm list packages                  # 所有应用
adb shell pm list packages | grep "某个关键词" # 过滤

# 查看当前前台应用
adb shell dumpsys window | grep mCurrentFocus

# 启动应用
adb shell am start -n com.example.app/.MainActivity

# 停止应用(强制杀掉)
adb shell am force-stop com.example.app

# 清除应用数据(等同于"清除缓存+清除数据")
adb shell pm clear com.example.app

1.5 专项操作

bash 复制代码
# 模拟输入
adb shell input text "13800138000"          # 输入文字
adb shell input keyevent 4                  # 按返回键(KEYCODE_BACK)
adb shell input keyevent 3                  # 按Home键
adb shell input keyevent 26                 # 电源键(锁屏/唤醒)
adb shell input tap 500 1500                # 点击坐标(x,y)
adb shell input swipe 500 1500 500 500      # 滑动(startX,startY,endX,endY)

# 模拟系统事件
adb shell am broadcast -a android.intent.action.BATTERY_LOW  # 低电量广播

# 查看系统信息
adb shell getprop ro.build.version.sdk      # SDK版本
adb shell getprop ro.build.version.release  # 系统版本号
adb shell wm size                           # 屏幕分辨率
adb shell wm density                        # 屏幕密度DPI
adb shell dumpsys battery                   # 电池信息

# 修改系统设置(测试用)
adb shell settings put global airplane_mode_on 1      # 开飞行模式
adb shell settings put global airplane_mode_on 0      # 关飞行模式

# Monkey 随机压力测试
adb shell monkey -p com.example.app -v 500             # 随机500次操作
adb shell monkey -p com.example.app -v --throttle 300 500  # 间隔300ms

1.6 ADB 常用场景速查

测试场景 ADB 命令
安装测试包 adb install -r app-debug.apk
卸载+清理 adb uninstall 包名 && adb shell pm clear 包名
看实时日志 `adb logcat
截图存证 adb shell screencap /sdcard/bug.png && adb pull /sdcard/bug.png
模拟返回键 adb shell input keyevent 4
查看当前页面 `adb shell dumpsys window
强制杀APP adb shell am force-stop 包名
模拟低电量 adb shell dumpsys battery set level 15
恢复电量 adb shell dumpsys battery reset

二、Charles:抓包 + 弱网

Charles 是 APP 测试的必备工具,注意:看请求内容和模拟弱网

2.1 HTTPS 抓包完整配置

第一步:电脑端安装并信任证书

第二步:开启 SSL Proxying

第三步:手机配置代理

第四步:手机安装证书

iOS 额外步骤

复制代码
设置 → 通用 → 关于本机 → 证书信任设置 → 开启 Charles 证书

验证是否成功:打开爱听外语APP随便操作,在 Charles 中应能看到 HTTPS 请求且 Contents 标签有明文 JSON 数据。

2.2 抓包实战技巧

过滤请求

复制代码
Charles 左下角 Filter 输入框:
ai.ting     -> 只看包含 ai.ting 的请求
!Google     -> 排除包含 Google 的请求
/api/user   -> 精确匹配路径

断点修改请求/响应(Breakpoints)

复制代码
右键目标请求 ->Breakpoints -> 重新触发请求
-> 弹窗显示 Request 内容 -> 可修改参数 → Execute
-> 弹窗显示 Response 内容 -> 可修改返回值 → Execute

适用场景:测试服务端返回异常数据时APP会不会崩

Map Local(本地文件替换返回)

复制代码
右键请求 ->Map Local → 选择一个本地的 JSON 文件
-> 此后该请求的返回值全部被替换为本地文件内容

适用场景:服务端还没开发好接口时,用 Mock 数据验证前端处理。

Rewrite(自动修改请求/响应)

复制代码
Tools ->Rewrite -> Add ->设置规则
例如:
Type: Body, Where: Response,
  Replace: "isVip":false → "isVip":true
作用:测试VIP和非VIP用户看到的内容差异,不需要切换账号

2.3 弱网模拟配置

复制代码
Charles → Proxy → Throttle Settings → 勾选 Enable Throttling

预设场景可以直接选:
56 kbps Modem(模拟2G)
- 256 kbps ISDN(模拟3G)
512 kbps DSL(模拟弱3G)
2 Mbps ADSL(模拟4G弱信号)

也可以自定义(常用配置):
场景 下行 上行 延迟 丢包 Charles配置
2G极限 50 20 500 10% 选 Modem 预设
弱3G 384 128 200 3% 接近 ISDN 预设
弱4G/地铁 5000 1000 100 2% 自行调整
网络抖动 20000 5000 200-1000 5% 勾选 Random

执行弱网测试的步骤

复制代码
1. 手机连接 Charles 代理
2. Charles → Throttle Settings → 选择或自定义一个网络配置
3. 在手机APP上执行目标操作
4. 观察:
    是否出现 Loading 状态
   超时时间是否合理
   超时后提示文案是否可理解
   网络恢复后能否自动继续
5. 切换不同网络配置,逐档记录表现
6. 关闭 Throttle → 恢复正常

弱网测试报告模板

测试场景 网络配置 操作 实际表现 是否通过 备注
首页加载 2G 冷启动 白屏20秒后提示"网络加载失败" ⚠️ 建议提前展示骨架屏
音频播放 弱4G 点击播放 缓冲8秒后正常播放 ---
表单提交 3G 点击登录 Loading2秒后登录成功 ---
网络切换 弱4G→正常 播放中切网络 自动切换音质 ⚠️ 应提前缓冲

三、PerfDog:性能测试

PerfDog 是腾讯出品的跨平台性能测试工具,支持 Android + iOS,无需 root 也无需越狱

3.1 安装和连接

复制代码
1. 下载并安装 PerfDog:https://perfdog.qq.com/
2. 手机连接到电脑(USB)→ 确认 adb devices 能看到设备
3. iOS 需要另外安装 iTunes 或 Xcode
4. 打开 PerfDog → 选择设备 → 选择要监控的APP进程
5. 点击"开始"录制

3.2 核心指标解读

指标 含义 参考标准
FPS 帧率,屏幕每秒刷新次数 滑列表 > 55,静置 = 0
Jank 卡顿次数(每10分钟) < 10次
CPU CPU占用百分比 空闲 < 5%,操作 < 30%
Memory 内存占用 视APP类型
Network 上行/下行流量速度 ---
Battery 电流消耗(mA) 后台 < 50mA,前台 < 300mA
Temperature 电池温度 < 40℃

3.3 实战:检测内存泄漏

复制代码
操作步骤:
1. PerfDog 开始录制
2. 启动APP → 静置30秒 → 记录基线内存(假设200MB)
3. 反复执行目标操作(如打开关闭详情页)20次
4. 回到首页 → 手动触发GC(Android: adb shell dumpsys meminfo 包名)
5. 观察最终内存值是否为基线附近

判定:
210MB -> 正常波动,无泄漏
260MB(+30%)->  疑似泄漏,需进一步确认
350MB(+75%)->  明显泄漏,提单

3.4 标签功能(打点记录关键操作)

PerfDog 支持在录制过程中打标签,方便事后分析"某个操作时性能如何":

复制代码
执行某个操作前 → PerfDog界面点"添加标签" → 输入标签名(如"冷启动")
→ 事后在图表上能看到标签对应位置的性能数据

四、Appium:UI自动化

Appium 是目前使用最广泛的移动端 UI 自动化框架,一套代码同时支持 Android 和 iOS。

4.1 环境搭建

需要的组件

复制代码
1. JDK 11+(Java开发环境)
2. Android SDK(含 adb)
3. Node.js(Appium Server 基于 Node)
4. Appium Server
5. Appium-Python-Client(Python客户端库)
6. Appium Inspector(元素定位辅助工具)

安装命令

bash 复制代码
# 安装 Appium Server
npm install -g appium

# 安装 UIAutomator2 驱动(Android)
appium driver install uiautomator2

# 安装 XCUITest 驱动(iOS)
appium driver install xcuitest

# 安装 Python 客户端
pip install Appium-Python-Client

# 安装 Appium Inspector(桌面应用,单独下载)
# 下载地址:https://github.com/appium/appium-inspector/releases

启动 Appium Server

bash 复制代码
# 命令行启动
appium

# 输出:
# [Appium] Welcome to Appium v2.x.x
# [Appium] Appium REST http interface listener started on http://0.0.0.0:4723

4.2 编写第一个测试

python 复制代码
# test_app_login.py
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 连接设备的Desired Capabilities
desired_caps = {
    # 平台信息
    "platformName": "Android",
    "platformVersion": "14",
    "deviceName": "Pixel_7",

    # APP信息
    "appPackage": "com.aitingwaiyu.app",
    "appActivity": ".ui.login.LoginActivity",

    # 测试配置
    "noReset": True,              # 不清除APP数据(保留登录态)
    "autoGrantPermissions": True, # 自动授予权限
    "newCommandTimeout": 300,     # 命令超时5分钟
    "unicodeKeyboard": True,      # 使用Appium输入法支持中文输入
    "resetKeyboard": True         # 测试结束后恢复原输入法
}

# 连接Appium Server
driver = webdriver.Remote("http://localhost:4723", desired_caps)

# 设置显式等待
wait = WebDriverWait(driver, 10)

try:
    # 1. 输入手机号
    phone_input = wait.until(
        EC.presence_of_element_located(
            (AppiumBy.ID, "com.aitingwaiyu.app:id/etPhone")
        )
    )
    phone_input.clear()
    phone_input.send_keys("13800138000")

    # 2. 点击"获取验证码"
    code_btn = driver.find_element(
        AppiumBy.ID, "com.aitingwaiyu.app:id/btnGetCode"
    )
    code_btn.click()

    # 3. 等待并输入验证码(模拟环境固定验证码)
    time.sleep(2)
    code_input = driver.find_element(
        AppiumBy.ID, "com.aitingwaiyu.app:id/etCode"
    )
    code_input.send_keys("000000")

    # 4. 勾选用户协议
    agree_cb = driver.find_element(
        AppiumBy.ID, "com.aitingwaiyu.app:id/cbAgree"
    )
    if not agree_cb.get_attribute("checked"):
        agree_cb.click()

    # 5. 点击登录
    login_btn = driver.find_element(
        AppiumBy.ID, "com.aitingwaiyu.app:id/btnLogin"
    )
    login_btn.click()

    # 6. 验证登录成功------等待首页元素出现
    home_element = wait.until(
        EC.presence_of_element_located(
            (AppiumBy.XPATH, "//android.widget.TextView[@text='首页']")
        )
    )
    assert home_element is not None, "登录失败:未跳转到首页"
    print("✓ 登录成功")

except Exception as e:
    # 失败截图
    driver.save_screenshot("login_error.png")
    print(f"✗ 测试失败: {e}")
    raise

finally:
    driver.quit()

4.3 元素定位实战

Appium Inspector 定位元素------它能看到页面上所有元素的结构树和属性。

定位优先级

优先级 定位方式 示例 场景
1 accessibility id (AppiumBy.ACCESSIBILITY_ID, "登录按钮") iOS/Android通用
2 resource-id (AppiumBy.ID, "com.xx:id/btn") Android专用
3 UIAutomator 选择器 (AppiumBy.ANDROID_UIAUTOMATOR, 'text("登录")') 按文本找控件
4 class name (AppiumBy.CLASS_NAME, "android.widget.Button") 控件唯一时可用
5 xpath (AppiumBy.XPATH, "//Button[@text='登录']") 兜底,最慢

4.4 Page Object 模式

实际项目不会把所有代码写在一个文件里,用 Page Object 封装:

python 复制代码
# pages/login_page.py
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.wait = WebDriverWait(driver, 10)

        # 元素定位器
        self.PHONE_INPUT = (AppiumBy.ID, "com.aitingwaiyu.app:id/etPhone")
        self.CODE_BTN = (AppiumBy.ID, "com.aitingwaiyu.app:id/btnGetCode")
        self.CODE_INPUT = (AppiumBy.ID, "com.aitingwaiyu.app:id/etCode")
        self.AGREE_CB = (AppiumBy.ID, "com.aitingwaiyu.app:id/cbAgree")
        self.LOGIN_BTN = (AppiumBy.ID, "com.aitingwaiyu.app:id/btnLogin")

    def input_phone(self, phone):
        el = self.wait.until(EC.presence_of_element_located(self.PHONE_INPUT))
        el.clear()
        el.send_keys(phone)

    def click_get_code(self):
        self.driver.find_element(*self.CODE_BTN).click()

    def input_code(self, code):
        self.driver.find_element(*self.CODE_INPUT).send_keys(code)

    def agree_protocol(self):
        cb = self.driver.find_element(*self.AGREE_CB)
        if cb.get_attribute("checked") != "true":
            cb.click()

    def click_login(self):
        self.driver.find_element(*self.LOGIN_BTN).click()
        return HomePage(self.driver)

# pages/home_page.py
class HomePage:
    def __init__(self, driver):
        self.driver = driver
        self.TITLE = (AppiumBy.XPATH, "//android.widget.TextView[@text='首页']")

    def is_displayed(self):
        return WebDriverWait(self.driver, 5).until(
            EC.presence_of_element_located(self.TITLE)
        ) is not None

# tests/test_login.py
def test_login_success(driver):
    login_page = LoginPage(driver)
    login_page.input_phone("13800138000")
    login_page.click_get_code()
    login_page.input_code("000000")
    login_page.agree_protocol()
    home_page = login_page.click_login()
    assert home_page.is_displayed(), "登录失败"

4.5 运行测试

bash 复制代码
# 启动 Appium(保持运行)
appium &

# 运行测试脚本
python -m pytest tests/ -v --tb=short

# 生成 Allure 报告
python -m pytest tests/ --alluredir=./allure_results
allure serve ./allure_results

五、JMeter 后端性能压测

APP 的流畅度不仅取决于前端,后端接口的性能同样关键。用 JMeter 做接口压力测试的完整步骤:

5.1 创建测试计划

第一步:线程组

复制代码
线程数:100(模拟100并发用户)
Ramp-Up时间:10秒(10秒内逐步启动)
循环次数:勾选"永远"
持续时间:300秒(5分钟)

第二步:HTTP请求默认值

复制代码
协议:https
服务器IP:api.aitingwaiyu.com
端口:443

第三步:HTTP Header 管理器

复制代码
Content-Type: application/json
Authorization: Bearer ${token}

第四步:登录请求 + Token 提取

复制代码
方法:POST
路径:/api/user/login
Body Data: {"phone":"13800138000","code":"000000"}

变量名:token
JSON路径:$.data.token

第五步:业务请求

复制代码
路径:/api/course/list
参数:page=1&size=20
自动携带 ${token}

第六步:断言

复制代码
JSON路径:$.code
期望值:200

第七步:监听器

复制代码
监听器 -> 聚合报告 -> 核心报表
监听器 -> 查看结果树 -> 调试用(正式压测时禁用)
监听器 -> TPS图  -> 吞吐量趋势

第八步:命令行执行

bash 复制代码
# 正式压测不要用 GUI(GUI 本身消耗资源影响结果)
jmeter -n -t aitingwaiyu.jmx -l result.jtl -e -o report/

# -n  非GUI模式
# -t  测试脚本文件
# -l  原始结果文件
# -e  生成HTML报告
# -o  报告输出目录

第九步:分析结果

打开 report/index.html,重点关注:

指标 关注点
Average (ms) 整体 < 1000ms
90% Line 90%用户感受
Throughput (TPS) 系统处理能力峰值
Error % 必须 = 0%

六、一个版本的测试周期

复制代码
Day 1:收到提测邮件
  ├── 拉取测试分支 → adb install 安装测试包
  ├── 阅读需求文档 → 确认测试范围
  └── 编写/补充测试用例

Day 2:功能与接口测试
  ├── 手工跑核心流程用例(在自备真机上)
  ├── Charles 抓包验证接口参数和返回值
  ├── Postman 或 JMeter 单接口验证
  └── 发现的 bug 提交到 TAPD / Jira

Day 3:专项测试
  ├── Charles Throttle 弱网模拟(2G/3G/4G/断网/切换)
  ├── 中断测试(来电/短信/锁屏/低电量/后台)
  ├── 横竖屏切换 + 不同输入法测试
  └── 安装/覆盖/升级/卸载测试

Day 4:兼容性+性能
  ├── PerfDog 录制性能(启动/内存/帧率/耗电)
  ├── 多台真机(至少华为+小米+OPPO+iPhone)跑冒烟
  ├── 云测平台补充10-20台兼容性验证
  └── JMeter 后端接口压测

Day 5:回归+报告
  ├── 执行自动化脚本回归
  ├── 整理测试报告
  ├── 遗留bug评估
  └── 发送测试通过/阻塞结论

七、常用命令速查总表

bash 复制代码
# ---- ADB ----
adb devices                                     # 设备列表
adb install app.apk                             # 安装
adb uninstall 包名                               # 卸载
adb logcat | grep "ERROR"                       # 看错误日志
adb shell am force-stop 包名                     # 杀进程
adb shell input keyevent 4                      # 返回键
adb shell screencap /sdcard/s.png && adb pull /sdcard/s.png  # 截图

# ---- Appium ----
appium                                          # 启动Server
appium driver list                              # 查看已安装驱动
pip install Appium-Python-Client                # 安装客户端

# ---- JMeter ----
jmeter -n -t test.jmx -l result.jtl -e -o report/   # 命令行执行
jmeter -g result.jtl -o report/                      # 从已有结果生成报告

# ---- PerfDog ----
(GUI工具,无命令行)

# ---- Charles ----
(GUI工具)