You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Test Lab中Location API及谷歌地图异常的解决咨询

Firebase Test Lab中使用位置服务的可行方案及问题排查

核心结论

Firebase Test Lab(FTL)支持位置服务,但需要适配FTL的特殊测试环境,同时修正密钥配置和测试Mock逻辑的问题。

一、修正测试中的位置Mock逻辑

你目前Mock了IsUserLocal用例,但FusedLocationProviderClient的回调仍无响应,说明Mock没有覆盖到FTL中实际触发的位置请求路径:

  • 确保完全Mock FusedLocationProviderClient的相关方法,而不仅仅是业务层的IsUserLocal判断。比如在Instrumented测试中,用Mockito或自定义Fake类替代真实的客户端:
    // 示例:用Mockito Mock FusedLocationProviderClient
    val mockLocationClient = mock(FusedLocationProviderClient::class.java)
    val mockLocation = Location("mock_provider").apply {
        latitude = 37.7749
        longitude = -122.4194
    }
    `when`(mockLocationClient.lastLocation).thenReturn(Task.forResult(mockLocation))
    // 将Mock实例注入到你的位置服务依赖中
    
  • 避免在测试中依赖真实的Location API回调,FTL测试设备可能限制了后台位置服务的主动触发,直接Mock返回预期位置或业务结果更可靠。

二、解决API密钥的安全异常

日志中的包名和SHA256不匹配问题,是FTL测试设备的特殊签名导致的:

  • FTL运行测试时,会使用Firebase测试签名证书重新签名你的APK,而非你本地的开发/发布签名。你需要把FTL的SHA256指纹添加到Google Cloud控制台的API密钥限制中:
    1. 从FTL测试日志的安全异常信息里,提取测试设备使用的SHA256指纹;
    2. 打开Google Cloud控制台的「API和服务 -> 凭据」页面,找到你的Maps/位置API密钥,添加该SHA256指纹+应用包名的组合到密钥限制列表。
  • 不要直接取消密钥限制(存在安全风险),优先添加FTL的签名指纹。

三、适配FTL的位置服务环境

即使配置正确,FTL的测试设备可能默认禁用了位置服务,需要在测试代码中主动启用:

  • 在Instrumented测试的@Before方法中,通过系统设置启用高精度定位:
    @Before
    public void setupLocationSettings() {
        ContentResolver resolver = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver();
        Settings.Secure.putString(resolver, Settings.Secure.LOCATION_MODE, String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY));
    }
    
  • 确保测试APK已声明ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,同时用Espresso自动处理权限弹窗:
    // 处理位置权限授权弹窗
    Espresso.onView(ViewMatchers.withId(android.R.id.button1)).perform(ViewActions.click())
    

四、解决地图空白问题

地图空白除了密钥问题,还可能是FTL设备的组件兼容问题:

  • 确保应用使用最新版的Google Maps SDK for Android,旧版本可能和FTL设备的系统版本不兼容;
  • 用Espresso的IdlingResource等待地图加载完成,避免测试操作过早执行:
    class MapIdlingResource(private val googleMap: GoogleMap?) : IdlingResource {
        private var callback: IdlingResource.ResourceCallback? = null
        override fun getName() = "MapIdlingResource"
        override fun isIdleNow(): Boolean {
            val isIdle = googleMap?.isLoaded == true
            if (isIdle) callback?.onTransitionToIdle()
            return isIdle
        }
        override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
            this.callback = callback
        }
    }
    
    // 测试中使用
    val mapIdlingResource = MapIdlingResource(supportMapFragment.map)
    IdlingRegistry.getInstance().register(mapIdlingResource)
    // 执行测试操作
    IdlingRegistry.getInstance().unregister(mapIdlingResource)
    

内容的提问来源于stack exchange,提问作者Barry Irvine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:08:08