现如今的环境,每个app都要联网,且众所周知,网络环境没法时刻都稳定,作为好的用户体验中的一环,开发者必须测试应用在不稳定和慢速网络环境下的表现。
常见方式
模拟慢速网络
在真实手机中,你可以像下图所示一样改变信号接收模式来模拟慢速网络,既切换到3G网络。左边是模拟器设置,右边是真实手机。

但这种方式有两个弊端:
- 它改变了整个设备的网络,特别是在测试真实手机时,当你要测试其它app时,你都得确保信号接收模式切换回正常的4G/5G,略显麻烦
- 它只能模拟慢速网络,无法模拟不稳定网络
译者注:也无法模拟wifi环境下的慢速和不稳定
Charles/ProxyMan
这两个工具都可以模拟慢速网络,且可以设置自定义接口的reponse,但同样有几个弊端。
- 需要将手机网络连接到对应的设备,如果在测试过程中必须多次配置设置,这又是一个麻烦
- 还是无法模拟不稳定的网络
- ProxyMan中mock响应的接口数量是有限制的
- Charles要付费
注:还需要测试的水平到位,并且不嫌麻烦
Flaker登场
Flaker: A flaky network simulator for your mobile app
有了Flaker,开发者可以:
- 模拟慢速和高延迟网络
- 模拟不稳定的网络
在项目中接入了Flaker之后,flaker会安装一个伴生app(类似leakcanary),可方便地在其中设置app的网络环境。

特性
- 高延迟网络:可以很方便地配置网络延迟,每个测试用例按需配置即可
- 不稳定网络:可以配置
Fail Percentage
和Variance Percentage
,即可模拟不稳定网络 - 精准影响范围:Flaker的设计目标就是只影响app的网络环境,整个手机的网络环境是不受影响的,这意味着你可以在不影响整个设备连接的情况下测试和微调应用程序的性能。

什么是Fail percentage和Variance percetages?
Fail percentage
:它使你能够设置应用程序发起的网络请求失败的百分比Variace percentages
:网络连接的延迟随时间变化的程度,它是一个衡量网络连接不可预测性的指标。指标越高,网络的延迟就更多变,更容易体现出app在这种网络环境下的用户体验问题。
安装和配置
- 添加
mavenCentral
到build.gradle
中的repositories下 - 添加如下依赖到app的
build.gradle
gradle
dependencies {
debugImplementation("io.github.rotbolt:flaker-android-okhttp:${latest_version}")
releaseImplementation("io.github.rotbolt:flaker-android-okhttp-noop:${latest_version}")
}
- 在application的onCreate回调加入如下代码
kotlin
class MainApplication: Application() {
override fun onCreate() {
super.onCreate()
FlakerAndroidOkhttpContainer.install(this)
}
}
- 在OkHttpClient的构造代码处,加一个interceptor
kotlin
val client = OkHttpClient.Builder()
.addInterceptor(FlakerInterceptor.Builder().build())
.build()
- Flaker有一个默认的Fail Response,也可自己定义
kotlin
val flakerFailResponse = FlakerFailResponse(
httpCode = 500,
message = "Flaker is enabled. This is a flaky response.",
responseBodyString = "Test Failure"
)
val flakerInterceptor = FlakerInterceptor.Builder()
.failResponse(flakerFailResponse)
.build()
齐活了,运行应用就可以看到伴生的flaker
了,可以在这个app里面配置网络环境,简单好用。
Flaker工作原理
Flaker是一个高度模块化的开源库,下图是它的模块设计
本文不涉及每个模块的详细解释,感兴趣可以参考官方文档或者仓库地址,本文将会聚焦在几个主要的模块。
-
falaker-okhttp-core
: 这个是核心模块,包含了之前所说的FlakerInterceptor,适用于使用okhttp作为网络请求的安卓项目,意味着适用于现在大多数的安卓项目了 -
flaker-ktor-core
: 这个模块适用于适用ktor
作为网络请求的项目,鉴于ktor
是一个跨平台的开源库,因此flaktor-ktor-core未来也将会适用于iOS(该模块目前仍在开发中) -
flaker-data
: 基本上包含了用户设定的网络环境配置和FlakerInterceptor拦截的网络请求日志,这些日志可会在flaker上展示

flaker-android-okhttp
: 这个是安卓端接入的依赖,它包含了flaker-okhttp-core
和伴生app的代码
FlakerInterceptor原理
这是最关键也是最有趣的一个部分。
本质上FlakerInterceptor使用了一个叫retrofit-mock
的东西,它提供了mock响应(Response)的能力和一个叫NetworkBehaviour
的类,该类提供了配置fail percentage和network variance的能力,如下:
kotlin
val networkbehavior = NetworkBehavior.create();
behavior.setDelay(2000, TimeUnit.MILLISECONDS);
behavior.setFailurePercent(50);
behavior.setVariancePercent(50);
配置了这些参数之后,flaker要做的就是在拦截请求的时候应用这个NetworkBehavior。
还是没明白它如何模拟不稳定网络?
在拦截过程中,flaker会检查flaker-data
层传过来的配置,如果用户启用了模拟网络功能,以下是判断处的代码
kotlin
if (flakerPrefs.shouldIntercept) {
val behavior = NetworkBehavior.create()
behavior.setDelay(flakerPrefs.delay.toLong(), TimeUnit.MILLISECONDS)
behavior.setFailurePercent(flakerPrefs.failPercent)
behavior.setVariancePercent(flakerPrefs.variancePercent)
val calculatedDelay = behavior.calculateDelay(TimeUnit.MILLISECONDS)
delay(calculatedDelay)
if (behavior.calculateIsFailure()) {
val flakerInterceptedResponse = your configured fail response
return@runBlocking flakerInterceptedResponse
}
}
关于不稳定性,Flaker使用NetworkBehaviour计算是否应将该请求视为失败,该计算使用calculateIsFailure()方法,并根据你设置的fail percentage和variance percentage计算失败的响应,基于此,Flaker会返回一个失败的响应(这也是可配置的)。
综上所述,就是这么简单,通过在伴生app上滑动参数条和点击按钮,就可以模拟不稳定网络环境了。
不全面的地方
Flaker目前还处于早期阶段,如其它开源库一样,它也有不全面的地方
- 不支持模拟WebSockets连接的不稳定情况
- 不支持Streaming连接的不稳定情况
展望
目前Flaker只适用于安卓项目,但它的设计是考虑了跨平台的,并且为了同时支持安卓和iOS用Kotlin Multiplatform来开发。
iOS的适配已在开发中,敬请期待。
感谢支持。
原文: [Testing Android apps for flaky network situations with Flaker | by Rohan Maity | RotBolt | Oct, 2023 | ProAndroidDev](Testing Android apps for flaky network situations with Flaker | by Rohan Maity | RotBolt | Oct, 2023 | ProAndroidDev)