两年前在交付一个视频会议项目时,碰到一个很烦人的问题:只要用户在通话过程中从WiFi切到4G,再切回WiFi,大概率会出现十几秒的黑屏或直接断连。开发那边一开始觉得是网络抖动,改了几版也没彻底解决。后来拉上测试和运维一起复现,才发现问题出在切换时SDK没有处理好socket重建和ice重协商的时序。而那段时间我们用来复现的方式极其原始——两台手机,一个人拿着跑到电梯间去切网,另一个人看着日志喊停。这事儿之后,团队开始认真琢磨怎么把网络切换测试做得系统一点,而不是每次都靠肉身模拟。
后来在不同的项目里,这种需求越来越多,不只是视频会议,就连普通的资讯App,产品经理也开始要求在切换网络时不白屏、不重复请求、不丢状态。于是慢慢攒出了一套相对靠谱的测试方法,今天就把它整理出来,给同样被网络切换折磨的同行参考。
先理清到底要测什么
很多人一听到网络切换测试,第一反应就是开关飞行模式。这个动作本身没错,但远远不够。我们需要先把场景拆开,至少要覆盖这么几类:
- 网络类型之间的切换:WiFi ↔ 移动数据,WiFi ↔ 无网,4G ↔ 5G,移动数据 ↔ 无网。
- 同一类型网络内的切换:比如从一个WiFi热点漫游到另一个同SSID但不同BSSID的AP,或者从4G基站A切到基站B。这种对实时性要求高的应用影响尤其大。
- 混合场景:应用在后台时发生网络切换,再切回前台;锁屏唤醒后的网络状态恢复;下载过程中切换网络导致断点续传逻辑被触发等等。
如果只是泛泛地“切一下看看”,大概率会漏掉很多边界情况。我的习惯是先拉一个矩阵,横轴是状态(前台、后台、锁屏),纵轴是切换路径,然后再往里面填预期行为。这个矩阵一开始不用太复杂,但至少能让测试用例有骨架。

纯手动的方法,但有技巧
小团队没精力搭自动化的阶段,手动测试是绕不过去的。但手动不等于低效,有几个办法可以明显提升复现率。
先说WiFi切4G/5G,最原始的办法是直接关掉WiFi,让系统自动切回蜂窝数据。但这个动作太快,很多App来不及感知中间的中间态。后来我会更倾向于用“弱信号驱逐”的方式——比如把手机拿到离路由器很远的角落,或者用微波炉旁边(不嫌麻烦的话),让WiFi信号逐渐减弱直到断开,这样更接近真实用户的切换过程。iPhone上也可以用Mac的蓝牙共享网络,然后调整距离,制造一个缓慢衰减的信号环境。
Android手机就更灵活一些,开发者选项里有一个“蜂窝数据始终处于活跃状态”的开关,打开之后即使连上WiFi,移动网络也保持连接。这个开关在做“WiFi断开瞬间立即切到蜂窝”的场景时很有用,能减少等待时间。另外很多Android机型支持限制后台数据,配合切换可以做省电模式下的网络行为测试。
iOS相对封闭,但连接Xcode后可以通过“Network Link Conditioner”模拟不同的网络环境,虽然它更擅长做弱网模拟而不是动态切换,但在切网测试时可以先用它把当前网络模式改成“Very Bad Network”,然后再关闭这个配置模拟“恢复”,用这种落差来观察应用的重连逻辑。
借助代理工具模拟切换
如果觉得纯手动太累或者不够精确,可以用代理工具来做。Charles和Fiddler都支持断点和限速,但要模拟“切换”这个动作,需要稍微变通一下。
我的做法通常是这样的:把手机代理到Charles上,然后让应用跑在一个正常网络下。需要模拟切换时,直接开启Charles的“Throttle Settings”,把带宽压到一个极低的值,比如下行5kbps、上行1kbps,同时勾选“Only for selected hosts”,这样可以只对特定域名生效。等应用开始表现出弱网症状后,再关闭限速,观察它能不能在“网络恢复”时正确重连。这其实模拟的是一种“网络质量突变”的切换体验,对检验重试策略和心跳超时设置非常有效。
如果是模拟完全断网再恢复,就直接把代理断开再连上,或者更狠一点,在Mac上临时把WiFi关掉再打开,手机侧就会经历一次完整的链路中断。中间还可以配合Charles的Map Remote功能,让某个接口在第一次请求时返回成功,切换后第一次请求返回特定错误码,用来测试业务层面的降级逻辑。
另外,Fiddler的AutoResponder可以延迟返回,也能制造类似效果。这种手段的好处是不用频繁操作手机,坐在工位上就能把大部分切换场景跑一遍,而且可以准确控制断网发生的时间点,方便和日志对齐。
有条件就上自动化的硬手段
当手动和工具辅助都只能覆盖有限场景时,自动化就是不得不走的路了。我之前参与的一个项目里,CI流程会跑一套网络切换的自动化用例,核心思路是通过控制路由器或者修改设备的网络配置来实现。
一种方案是控制WiFi电源:准备一个可控的智能插座,把测试AP的电源插在上面,脚本通过插座API定时通断电,同时用ADB或Xcode命令行监控应用进程的日志,检测重连耗时和是否出现crash。这个方案成本最低,但有机械延迟,不够精确。
另一种更稳的方案是用软路由或者OpenWrt,通过SSH执行iptables规则,动态阻断或限制某个MAC地址的流量,甚至模拟丢包和延迟突变。脚本层面就可以把“阻断5秒后恢复”“限制上行10kbps持续10秒后放开”这类操作写成原子步骤,再把检测断言的逻辑串起来。Android设备可以通过adb shell发送svc wifi disable / enable命令来控制WiFi开关,配合svc data disable也能操作移动数据的启停。iOS这边就需要借助越狱或者私有API,成本会高一些。
无论哪种自动化方式,网络切换测试一定要有明确的时间刻度:什么时刻触发切换,应用应该在多少毫秒内感知到网络变化,又应该在多少秒内完成重连并恢复业务。没有这些数值,自动化用例的断言就变成了“没崩就行”,意义大打折扣。
容易忽略的一些点
即使有了上面的方法,还是有几个地方踩过坑,分享一下:
第一,切换时在途的请求到底怎么处理,是直接取消还是排队等待。很多应用在切网时会堆积大量失败请求,网络恢复后一瞬间全部发出,导致服务器压力尖刺,甚至被限流。这种要靠抓包日志才能发现,测试时一定要留意切换完成后的前几秒请求密度。
第二,后台切换和前台切换是两个完全不同的故事。Android和iOS对后台应用的网络权限限制不同,尤其是在省电模式下,系统可能会直接掐断后台socket。测试时最好覆盖“切网时应用正在后台播放音频”“后台下载”“后台定位”等细分场景,拿不同系统的真机多跑几轮。
第三,双卡手机已经是主流了,切换网络不仅仅是WiFi和蜂窝之间,还可能涉及卡1和卡2的移动数据切换,或者通话时另一张卡的VoLTE接管数据业务。这类场景测试成本很高,但用户反馈一旦出现就很致命。
第四,一些三方的网络库或长连接服务有自己的保活和重连策略,默认参数在频繁切换下不一定合适。测试过程中如果发现重连特别慢,可以建议开发把相关参数暴露成可配置项,允许根据业务容忍度来调整。
写到最后,其实网络切换测试真正的难点不在切换这个动作本身,而在于能不能把切换前后的应用状态完整地串起来观察。日志、抓包、录屏、性能曲线,最好能在一条时间轴上回放,才能真正定位问题。如果团队有条件,把切换事件(比如WiFi断连的系统广播)打入日志中心,会让排查效率上一个台阶。
免责声明
本文内容仅代表个人在特定项目背景下的实践经验,不同设备、系统版本及应用架构可能存在差异,读者请根据实际情况调整测试策略,文中提到的工具与操作可能受限于硬件环境或系统权限。

发表回复