简介:手游弱网与性能测试资料包,面向手游测试工程师、移动端质量保障团队及游戏项目管理人员,解决弱网模拟、性能验收标准缺失与测试报告输出不规范等问题。内容覆盖纯丢包、WCDMA、高铁、地铁等典型网络模型配置,以及二代至五代移动网络与无线局域网环境下的弱网用例设计、前台性能指标(帧率、中央处理器占用、内存、功耗、发热)测试方法,并包含游戏测试验收技术指标、性能测试报告模板和执行指引,可直接用于制定测试方案并落地执行。压缩包共二十个文件,含指导文档、测试用例表、培训演示文稿与网络模型配置等类型,整体约十六兆,便于按模块查阅。已有 1941 人学习,适合希望系统掌握移动端弱网测试流程和性能评估方法的初中级测试人员;借助其中的 GT 安卓工具指南、前台性能测试指导书和验收指标标准,可快速搭建测试环境、复用标准模板并优化游戏发布前的稳定性与体验。
1. 手游弱网、性能测试方法及标准文档:先让线上别再背黑锅
手游弱网、性能测试方法及标准文档,这三件事放在一起看是一条完整链路:先模拟出用户真实遇到的网络条件,再量化游戏在性能和弱网下的表现,最后用一套标准文档拍板能不能发版。很多团队要么只把弱网测试当成“网络不好时截几张图”,要么把性能测试当成“上线前跑一遍数据”,结果线上反馈一堆卡顿、闪退、加载超时,测试阶段却一个都没测出来。弱网不是网络的锅,是测试方法缺失的锅;性能不是玄学,是采样和阈值没定准的锅。这套链路适合刚接手手游测试的从业者,也适合测过但总被开发质疑“数据不真实”的团队。
2. 弱网模拟方法:先理解四个维度,再选工具
2.1 弱网的四个维度与 tc 模拟的落地命令
弱网不是“信号格数少”这一个概念。我一般把它拆成四个维度:带宽、延迟、丢包、抖动。带宽决定单位时间里能传多少数据,延迟决定一次请求往返要多久,丢包决定数据会不会凭空消失,抖动决定网络是不是忽快忽慢。手游里最伤体验的往往不是单纯的带宽低,而是抖动和丢包,因为这两者会让同步逻辑频繁重传,表现为角色瞬移、技能放空、语音断断续续。所以要复现线上问题,不能只把网速调慢,而要精确控制这四个方向。
在 Linux 环境上用 tc(traffic control)做弱网是常见做法,它基于内核的 netem 模块,不需要额外购买商业设备,一台 Linux 网关或带 root 的开发机就能完成。下面是一段我常用的脚本,一次设置延迟、抖动、丢包三个参数:
# 清掉 eth0 上的旧规则,避免重复 add 时报错 tc qdisc del dev eth0 root 2>/dev/null || true # 加入 netem 规则:基础延迟 200ms、波动 20ms、丢包 5%、波动服从正态分布 tc qdisc add dev eth0 root netem delay 200ms 20ms distribution normal loss 5% # 查看配置是否生效 tc qdisc show dev eth0第一行先删除旧规则是必要的,因为 netem 的add在已有 qdisc 时会直接报错,重复叠加会导致参数翻倍。第二行的delay 200ms 20ms表示基础延迟是 200ms,额外附加 20ms 的随机波动;distribution normal让波动更接近真实网络的分布形态;loss 5%表示随机丢弃 5% 的报文。第三行用来确认规则成功挂载。真实弱网很少是恒定值,所以我建议至少要覆盖三组参数:轻度弱网(延迟 100ms、丢包 2%)、中度弱网(延迟 200ms、丢包 5%)、重度弱网(延迟 400ms、丢包 10%)。
需要注意,tc 的 netem 默认作用于出口方向,也就是从本机发出的流量会经过整形,而从外部进来的流量不会。如果只想模拟下载慢而不模拟上传慢,就可以只配本机;但手游大多需要双向同时变化,所以我会在被测手机连入的 Linux 网关上也配一套规则,而不是只在手机端加。想恢复网络执行tc qdisc del dev eth0 root即可。
提示:如果设备有多个网卡(Wi-Fi 与蜂窝同时在线),只配一个接口的规则不会影响另一个接口,确认当前流量真正走的是哪个网卡,否则会出现“明明配了弱网,游戏却完全正常”的假象。
2.2 工具选型:按测试目标决定用哪种方案
弱网工具的选择,本质是在问“你要模拟哪一层的网络”。只做功能冒烟时,用手机系统自带的一键弱网即可;要贴近真实用户链路,就必须在网关或路由器层面做整形;而某些无线网络场景,还可以通过物理衰减器或专用弱网盒子来做,但那套设备价格高、维护成本也高,不是每个团队都愿意投入。我按测试目标把常见做法分成三层。
第一层是本地快速验证。在开发调试时,用系统自带的网络调节能力或模拟器的网络档位来改网络条件,优点是改得快,缺点是只能覆盖本机、波动模型不真实,适合验证“某个界面在弱网下会不会崩”这类粗粒度问题。
第二层是网关固定整形。把测试机接入一台作为网关的 Linux 机器,用 tc 控制上行和下行参数。这个方案最贴近真实链路,也最容易复现问题,因为参数是固定的、可回放的,缺点是配置成本高一些,需要维护一台网关设备。
第三层是云真机平台预设档位。适合做跨机型的回归验证,由于所有用例都跑在同一个平台定义的弱网档位上,数据可对比;但平台的档位模型是预设的,无法精确到 5% 还是 6% 的丢包。如果需要精确定量,不要依赖云平台。
有一个血泪经验:不要只依赖抓包工具做弱网测试。抓包拦截工具工作在高层的转发链路上,对 TCP 流量有效,但手游里很大比例的实时语音、位置同步、状态同步走的是 UDP,一旦走上 UDP,抓包工具的限速基本管不住。我们之前就因为在验证阶段只用抓包工具,漏掉了语音在丢包场景下的表现,结果线上出了“听不到队友说话”的问题,排查了一整周才发现是弱网覆盖不足导致的。
2.3 一套可落地的弱网档位划分
为了让测试结果可对比,我建议团队内统一使用一张弱网档位表。档位不要求多,三档足够,关键是每个档位的参数要写死:
| 档位 | 延迟 | 抖动 | 丢包 | 典型场景 |
|---|---|---|---|---|
| 轻度 | 100ms | 10ms | 2% | 地铁、商圈 |
| 中度 | 200ms | 20ms | 5% | 高铁、电梯 |
| 重度 | 400ms | 50ms | 10% | 地下室、大型活动现场 |
每个档位至少跑一轮完整用例。跑完后记录实际生效的网络参数。标准档位先只控制延迟、抖动、丢包三个变量,带宽限制放到需要复现卡顿详情的场景再单独启用。这套档位表最好挂在测试环境基线文档里,所有执行弱网用例的人都按同一套参数执行,避免一个人测 200ms、另一个人测 150ms,最后数据对不上。
如果你做的项目对弱网有强诉求,比如对战、实时语音、帧同步,那么建议在重度档位之上再加一个“极端弱网”档位,把延迟调到 800ms、丢包调到 20%,用来验证游戏的保护策略——比如超时重连、断线重连、战斗重连是否正常。这个档位不应该作为常规发布门槛,但必须在核心战斗玩法里覆盖到。
3. 性能测试方法:先定指标,再谈工具
3.1 五项核心指标:FPS、帧时间、CPU、内存、发热
手游性能测试最容易犯的错,是把 FPS 当作唯一指标。FPS 是一个平均值,一局对局里哪怕有几十次 200ms 以上的长帧,平均值依然可能落在 55 以上,玩家体感却已经是“明显卡顿”。真正要盯的是帧时间分布,以及单帧耗时超过 100ms、200ms 的次数。我会在报告里同时给 FPS 均值与长帧次数,前者用来做版本间对比,后者用来判断体验是否达标。
CPU 与内存反映资源消耗。CPU 要看整体占用和峰值,同时尽量区分主线程、渲染线程与后台线程的负载,因为有些游戏渲染线程压力大,但主线程很空闲,单纯看整体 CPU 无法定位瓶颈。内存要看进程的 PSS,而不是虚拟内存大小,虚拟内存在 Android 上并不能反映真实物理占用。发热则要结合机身温度看,因为手机一发热就降频,降频后 FPS 断崖式下跌,这种“性能塌陷”如果被当成普通性能问题去排查,方向就错了。
另一个容易被低估的指标是冷启动时间。玩家等待超过 3 秒就开始流失,所以标准文档里应该把“从点击图标到主界面可交互”的耗时作为单独的体验指标。冷启动测试要重复 5 次以上,取中位数和最大值,而不是平均值,因为第一次启动有系统缓存的影响,平均值容易被极端值拉偏。
3.2 Android 真机用 adb 采样 CPU 与内存
性能测试的第一步是拿到可复现的采样数据。Android 真机配合 adb 是成本最低、数据也足够准确的方案。下面这段命令我通常放在自动化脚本里循环执行:
# 每 5 秒记录一次被测进程的 CPU 占用 for i in {1..120}; do echo "$(date +%H:%M:%S) $(adb shell top -n 1 -b | grep 'com.example.game' | awk '{print $9}')" >> cpu_rate.txt sleep 5 done # 记录内存 PSS 数据 adb shell dumpsys meminfo com.example.game | grep "TOTAL PSS" >> mem_pss.txt脚本的逻辑是:top -n 1 -b只取一次快照,避免连续刷屏造成额外负载;grep com.example.game把被测进程的行筛出来;awk '{print $9}'取 CPU 占用百分比。循环 120 次、间隔 5 秒,能覆盖 10 分钟的一整局对战。dumpsys meminfo是系统自带的内存信息接口,TOTAL PSS这一行是判断真实占用量的关键数据。
参数上有几个注意事项。采样间隔不要小于 3 秒,因为 adb 本身会占用设备资源,间隔太短会干扰被测进程,而且容易把峰值藏在极短的时间窗口里;我固定用 5 秒间隔,兼顾数据密度与设备负载。dumpsys meminfo每次调用会触发一次 GC,会暂时降低内存数值,频繁调用会让内存数据长时间偏低,所以内存采样频率要比 CPU 更低,10 秒一次比较合适。采集到的数据要带上时间戳,落库后与帧率、网络日志对齐,否则后续画趋势线时会发现时间轴对不上。
如果测试场景需要长时间压测,比如跑 1 小时以上的内存稳定性,光靠dumpsys每次全量输出会生成非常大的文件。常见做法是先用adb shell dumpsys meminfo --package找到对应的进程 pid,再单独采集这个 pid 的 PSS 字段,避免把整份进程列表都写进日志。压测结束后,还要关注内存是否持续增长,因为持续增长是泄漏的典型信号,而单个高数值可能是纹理加载等正常现象。
3.3 帧率与帧时间的采集:均值会骗人
帧率采集有两种主流途径。一类是厂商或第三方性能分析工具,读取的是系统渲染管线数据,准确度高、带曲线导出,适合出正式报告;另一类是直接读取系统的帧数据显示接口,例如在 Android 上执行dumpsys SurfaceFlinger --latency,它返回的是从前一帧提交到显示的排队时间戳,可以换算成帧时间和掉帧次数。后者不需要额外装工具,更容易嵌进自动化脚本。
我在自动化压测时优先用系统接口,因为可以直接落到同一个时间序列里。但要注意一个黑匣子问题:--latency拿到的往往是当前接口层最新一帧的状态,如果游戏本身锁了帧率上限,你看到的帧时间会被均匀化,比如锁 30 帧时帧时间稳定在 33ms,真实渲染的 100ms 卡顿被掩盖了。所以我会同时记录渲染线程的耗时,或者用能穿透到渲染管线的工具做交叉验证。
帧时间分布比平均值重要得多。某次测试中我们统计的 FPS 均值是 58,玩家却反馈“卡成幻灯片”,后来拉出帧时间分布才发现,超过 200ms 的长帧每局出现 20 多次,只是被平均数据吞掉了。从那以后我建立了一条规矩:每次性能测试必须附上帧时间分布表,按“50ms 以下、50~100ms、100~200ms、200ms 以上”四个区间统计帧数占比,任一区间异常都单独写结论。这条规矩后来救了我们很多次,很多“看起来不卡”的问题都被翻了出来。
4. 标准文档怎么落地:把测试结果变成能拍板的依据
4.1 标准文档的五个核心模块与阈值表
一份能支撑发布决策的性能标准文档,至少要包含五块:环境基线、场景定义、指标阈值、数据采集方式、结论判定规则。环境基线是最容易被跳过的,却也是最关键的后悔药。同样一段代码,同一台设备,系统版本从 A 升级到 B,性能数据能差 15% 以上;如果不把机型、系统版本、分辨率、帧率上限、内存档位、屏幕亮度、网络条件写清楚,任何数据都无法横向对比。
阈值设定要分档位、分场景。旗舰机和中低端机不能用同一套标准,否则要么中低端机天天报红,要么旗舰机的问题被掩盖。场景也要区分:主城挂机场景主要看平均帧率与内存增长;战斗场景看峰值 CPU 与掉帧分布;加载场景看冷启动时间和网络等待时间。标准文档不能只写一句“FPS 不低于 30”,必须明确在什么机型档位、什么场景、多长采样窗口内不低于 30。
下面是我常用来做演示的阈值表结构,实际数值按项目和目标机型调整:
| 指标 | 旗舰机档位 | 中端机档位 | 低端机档位 | 采集方式 |
|---|---|---|---|---|
| 平均 FPS | ≥ 55 | ≥ 45 | ≥ 30 | 10 分钟战斗场景 |
| 200ms 以上长帧 | ≤ 10 次 | ≤ 20 次 | ≤ 40 次 | SurfaceFlinger 时间戳 |
| CPU 占用峰值 | ≤ 60% | ≤ 70% | ≤ 80% | top,5s 间隔 |
| 内存 PSS 增长 | ≤ 150MB | ≤ 200MB | ≤ 300MB | meminfo,10s 间隔 |
| 冷启动到主界面 | ≤ 3s | ≤ 5s | ≤ 8s | 冷启动重复 5 次 |
这张表的关键不在具体数字,而在它为每一行都定义了采集方式。比如 CPU 峰值写的是 top 5s 间隔,那“峰值”就是采样点里的最大值,而不是系统瞬时值;如果换成别的工具或不同间隔,数值会完全不同。任何阈值表都要配套说明数据是怎么来的,否则后面复盘时会发现,两个人用的不同方法根本无法比较。参数设定上,采样窗口定 10 分钟,是因为一局对战的峰值通常出现在第 3~7 分钟;窗口太短采样不到峰值,太长又拉低平均值掩盖问题。
4.2 复现条件记录:把“偶现”变成“可追踪”
弱网和性能问题最怕“偶现”。测试时没复现,线上用户反馈出了问题,开发查设备日志说“本地复现不了”。这种局面的根因,多数是复现条件没记录完整。我在团队里强制要求:每一条问题记录必须回答四个问题——在什么网络参数下出现?用的是哪台设备?做了什么操作?问题在哪个时间点出现?能回答这四个问题的报告,开发定位问题的效率能提升一半,“复现不了”这个理由也会少很多。
标准文档里要附一张复现条件记录表,字段至少包括:测试时间、设备型号、系统版本、网络档位(延迟/丢包/抖动数值)、操作路径、首次出现时间、出现频率、是否在回归中出现。这些字段不是形式主义,而是因为弱网问题的根因往往是组合条件触发的。比如“延迟 200ms + 丢包 5% + 同时点击背包与好友列表”才触发数据错乱,单独记录“弱网下闪退”根本无法指导开发排查。
我在实践中的一个习惯是:问题描述里不允许只写“卡顿”或“闪退”,必须给出时间点和操作步骤。测试人员写清楚每一步操作的间隔时间,因为有些问题只在快节奏操作时触发,慢速点击就复现不了。这些细节在标准文档中一并写入模板,避免执行人凭印象填写。
4.3 结果判定与回归规则:不只看结论,更看趋势
标准文档的判定规则要解决“谁说了算”的问题。我建议把结果划分成三档:通过、有条件通过、不通过。通过是硬性指标全部达标;有条件通过是平均指标达标,但存在可解释的峰值波动,例如后台下载导致的 CPU 尖峰,需要记录归因并限期修复;不通过是核心指标不达标,阻断提测。判定不能只看结论,还要看趋势曲线——性能随版本迭代逐渐变差,比一次突然超标更危险。
回归规则也要写进标准文档。弱网问题必须做两轮回归:第一轮验证修复是否生效,第二轮在相邻版本再次验证,防止同一问题换个场景重新出现。性能问题需要在上一版本的相同环境上进行对比测试,用对比数据证明“是否变差”。这两条规则不复杂,但能把测试结论从“这版能跑”升级成“这版比上版好或坏多少”,对发布决策的参考价值完全不同。
标准文档一旦定下来,还要跟着执行方式一起修订。我见过不少团队文档写得头头是道,落地时却因为流程里没有检查环节而形同虚设。解决方案是把文档与提测流程绑定,没有附上符合格式的测试数据,分支就不能进入提测队列。这一步是流程问题,但决定了文档能否真正落地。
5. 弱网与性能测试的常见问题:五个最容易翻车的坑与排查方法
5.1 弱网只生效了一半:入口与出口流量不对称
现象:在测试机或网关上设置了延迟和丢包,但游戏中出现“上传正常、下载卡死”或者反过来,甚至完全没有效果。
原因:tc 的 netem 默认作用于出口方向,从设备外部进入的流量不会经过这条 netem 规则,所以上行与下行表现不一致。另一个常见原因是设备有多个网络接口,流量实际走的是蜂窝网络,而规则只配在 Wi-Fi 接口上。
解决:在网关与测试机两侧分别配置规则;如果只能在一侧配置,务必在报告里记录本次覆盖的是上行还是下行。排查时先在测试机上运行ping -c 10 网关地址,看延迟是否达到设定值;再用curl -o /dev/null -w '%{speed_download}'拉一次大文件,确认下载速度是否受限。如果 ping 的延迟不对,先检查规则是否挂错接口;如果 ping 延迟对但速度不对,再检查是不是带宽限制挂到了别的接口。
5.2 性能数据波动大,被质疑是“数字玄学”
现象:同一套用例跑两轮,FPS 均值差 10 帧以上,CPU 峰值忽高忽低,开发看到报告第一反应是“这数据不可信”。
原因:后台进程、系统更新、屏幕亮度、是否开启省电、机身温度都在变化,每个变量的状态不同,性能数据自然漂移。采集间隔太短或太长也会放大随机噪声。
解决:把环境基准写死,包括关闭后台推送、统一亮度和音量、关闭省电、固定测试前休息时间让机身回到常温。采样间隔固定 5 秒或 10 秒,窗口长度覆盖至少一局完整对战。数据出异常时先看整条曲线,而不是单点数值;如果曲线中段出现尖峰紧跟低谷,多半是负载打满后触发降频或限流。
5.3 手机发热降频被当成普通性能问题
现象:同一机型连测三局,第一局 FPS 58,第二局 50,第三局 40,报告直接写“性能不达标”。
原因:机身温度超过阈值后,系统会降低 CPU/GPU 频率来保护硬件,这是温控机制在起作用,并不一定是代码性能变差。如果把降频数据当作一般性能问题去排查,会陷入“优化后仍然掉帧”的死循环。
解决:性能测试期间持续记录机身温度,至少记录开始、中期、结束三个时间点的温度值。同时记录“降频节点时间”,即从测试开始到第一次明显降频的耗时。如果降频出现得过早,说明功耗压不住,按功耗问题排查;如果出现在长时间压测的后段,则属于正常温控,报告里要注明。把降频前与降频后的数据分开统计,各自求均值和长帧次数,报告里分别呈现,这样开发能明确知道问题出在温控触发之前的损耗还是触发之后的塌陷。
5.4 弱网用例只跑一次,偶现问题漏出
现象:弱网测试已通过,线上用户在地铁里出现数据不同步,测试同学困惑“我们明明测过弱网”。
原因:只测了一个档位,或者每个用例只执行一次。真实弱网信号是动态变化的,延迟、丢包、抖动同时波动,单一档位覆盖不到组合条件。
解决:按三档弱网分别跑用例,每个用例至少重复 5 次,覆盖登录、主城、战斗、切换场景、商城、语音等核心行为。设计原则是“同一操作在不同网络档位下反复执行”,而不是“不同操作在同一个档位下各执行一次”。用例矩阵的做法是:三档网络 × 五个核心玩法 × 重复 5 次,总共 75 次执行。听起来多,但可以完全自动化执行,配合第 6 章的脚本按档位循环即可。对帧同步、实时对战类玩法,再补一个极端弱网档位验证保护策略。
5.5 标准文档定了没人执行,沦为摆设
现象:团队有完善的性能标准文档,但每版走查时文档里的数据还是旧的,执行人随手填“通过”。
原因:文档缺少执行抓手,没有与提测流程绑定,也没有复核环节,文档自然沦为摆设。
解决:把标准文档与提测流程联动。提测清单中加入“性能与弱网验证记录”作为前置条件,未附数据与复现条件记录的不能进入提测队列。执行人填写结果时必须附带原始数据文件与复现条件记录表,只写结论不附数据的一律退回。这一步是流程问题,但决定了文档能否真正落地。
6. 进阶技巧:把弱网与性能测试串成一条命令
当弱网模拟、性能采样、标准文档都稳定后,最值得投入的方向是把它们连成一条可重复执行的命令。不一定要上重型平台,先写一个固定格式的脚本,让每次跑出来的数据互相可对比,这是后续分析的基础。下面是我常用形态的精简版,聚焦“进入弱网 → 采集 CPU → 跑固定时长 → 恢复网络”:
#!/bin/bash PACKAGE="com.example.game" DURATION=120 tc qdisc add dev eth0 root netem delay 200ms loss 5% for i in $(seq 1 $((DURATION/5))); do echo "$(date +%H:%M:%S) $(adb shell top -n 1 -b | grep ${PACKAGE} | awk '{print $9}')" >> cpu.txt sleep 5 done & adb shell am start -n ${PACKAGE}/.MainActivity sleep ${DURATION} kill %1 tc qdisc del dev eth0 root这段脚本按顺序做了五件事:加入弱网规则、后台循环采集 CPU、拉起游戏主界面、等待固定时长、停采样并清理规则。PACKAGE与DURATION放在顶部,改起来方便。注意kill %1杀掉的是后台采样任务,tc qdisc del恢复网络,sleep时长必须与DURATION一致。这个版本没有加入内存采集,你需要按第 3 章的方式在循环里追加。
验证这条命令是否可靠有一个笨办法:跑完看 cpu.txt 里的时间戳有没有缺失,值有没有成片为 0。有缺失说明 adb 连接不稳定;成片为 0 说明采样进程被系统回收,数据不可用。先画出 CPU 曲线看整体趋势,单点波动没有意义;中段出现尖峰后紧接低谷,通常是负载打满触发降频的迹象,翻日志找那个时间点最有价值。最后想说,环境基线优先是这一整套方法的地基。我第一次独立跟进时,因为没固定环境测了整整一天,数据被质疑后全部重测。从那以后,我每次测试先问三件事:网络参数是什么、用哪台设备、后台还有什么在跑。希望帮到你。
本文还有配套的精品资源,点击获取