如何在Gradle-managed devices中禁用immersive mode下的弹窗?
我想要使用Gradle-managed devices测试我的Android应用,以下是我在build.gradle文件中的配置:
testOptions { animationsDisabled = true managedDevices { devices { pixel2api31(ManagedVirtualDevice) { device = "Pixel 2" apiLevel = 31 systemImageSource = "aosp" } nexus9api26(ManagedVirtualDevice) { device = "Nexus 9" apiLevel = 26 systemImageSource = "aosp" } } groups { phoneAndTablet { targetDevices.add(devices.pixel2api31) targetDevices.add(devices.nexus9api26) } } } }
问题在于应用的部分功能运行在沉浸式模式(immersive mode)时,会触发提示用户退出该模式的弹窗,这干扰了自动化测试。
通过adb命令解决该弹窗的方案已有描述,但Gradle-managed devices无法使用adb命令(Google和android-test仓库存在未解决旧问题)。除了在生产代码中添加BuildConfig.DEBUG == false的判断来禁用immersive mode的临时方案外,是否还有其他解决方案?
使用测试专用资源配置
在src/debug/res/values/下新建config.xml配置文件,添加布尔值配置:<bool name="enable_immersive_prompt">false</bool>同时在
main/res/values/config.xml中对应设置为true。之后在触发弹窗的业务代码中,读取该资源值判断是否显示弹窗:if (resources.getBoolean(R.bool.enable_immersive_prompt)) { // 执行显示退出沉浸式模式弹窗的逻辑 }这种方式让Debug构建(测试用构建变体)自动禁用弹窗,生产构建不受影响,无需修改核心业务逻辑的判断逻辑。
利用测试框架屏蔽弹窗
如果使用Espresso测试框架,可以在测试初始化阶段添加弹窗监测与自动关闭逻辑。比如在测试类的@Before方法中处理:@Before fun setup() { val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) // 等待弹窗出现,若出现则点击关闭按钮 val closeBtnMatcher = onView(withText("关闭")) if (uiDevice.wait(Until.hasObject(By.text("关闭")), 3000)) { closeBtnMatcher.perform(click()) } }该方案完全在测试侧处理,不需要修改任何生产代码。
创建独立测试构建变体
在build.gradle中新增一个专门用于自动化测试的构建变体,比如test:android { buildTypes { test { initWith debug buildConfigField "boolean", "ENABLE_IMMERSIVE_PROMPT", "false" } } }之后在业务代码中通过
BuildConfig.ENABLE_IMMERSIVE_PROMPT判断是否显示弹窗。这种方式可以区分开发用的Debug构建和测试用的构建,Debug构建保留弹窗方便开发调试,测试构建禁用弹窗专供自动化测试使用。
内容的提问来源于stack exchange,提问作者flauschtrud

