繁体   English   中英

Android UI 测试与 Espresso + MockK 在模拟器上使用 SIGSEGV 崩溃,在物理设备上很好

[英]Android UI tests with Espresso + MockK crash with SIGSEGV on emulators, fine on physical devices

我刚刚开始使用MockK在基于 MVP 的应用程序中模拟所有存储库/服务逻辑以进行 UI 测试。

我有一些运行登录活动的 UI 测试,其中 Espresso 输入登录名和密码并使用 MockK 我可以伪造登录失败与否的各种情况。

所有服务和存储库都是标准的 Kotlin object,所以我使用mockkobjectevery/coEvery来覆盖和处理登录请求和任务。

在我的物理设备上,测试完全没有问题,但是当我尝试在运行 Android P+ 并带有推荐图像的模拟器上运行它们时,它们会在随机时间不断崩溃。 在极少数情况下,他们可以存活足够长的时间来工作。

查看日志,我得到了各种 SIGSEGV:

A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 10425 (e.android.debug) 中的故障地址 0x0,pid 10425 (e.androiddebug)。

A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 10968 (HeapTaskDaemon) 中的故障地址 0xc,pid 10957 (e.android.debug)

A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 15050 (firebase-instal) 中的故障地址 0x0,pid 14972 (e.android.debug)

A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 8902(测量工作)中的故障地址 0xd,pid 8858(e.android.debug)

A/libc:致命信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR),tid 22004 (Binder:21832_5) 中的故障地址 0x0,pid 21832 (e.android.debug)


但更深入地研究日志,我相信我找到了罪魁祸首:

InputDispatcher: 通道 '9fa7335 my.company.com.android.debug/my.company.com.ui.login.Login 将被销毁(无法恢复)

寻找解决方案,这似乎是由于 memory 泄漏而发生的?

无论如何,我确保在@Before方法中启动被测活动,在该方法中,当我清除此类模拟并在@After方法中进行验证时,所有模拟都会发生。

显然,我相信测试确实可以正常工作,但 Espresso 或所有发生的 mocking 肯定有问题......

[编辑 1]

进一步查看之前的日志,这可能是存在 memory 泄漏的原因:

ActivityThread: Service com.google.android.gms.autofill.service.AutofillService has leaked IntentReceiver com.google.android.gms.autofill.smsretriever.TracingSmsBroadcastReceiver@ce00658 that was originally registered here. 您是否错过了对 unregisterReceiver() 的调用? android.app.IntentReceiverLeaked: Service com.google.android.gms.autofill.service.AutofillService has leaked IntentReceiver com.google.android.gms.autofill.smsretriever.TracingSmsBroadcastReceiver@ce00658 that was originally registered here. 您是否错过了对 unregisterReceiver() 的调用?

我在我的模拟器上禁用了 AutoFillService(在相关设置部分中设置为 none)。 这似乎在一开始提高了我的测试成功率,但在几次运行后它们一直在崩溃。 不过,现在日志不再显示此泄漏。

[编辑 2]

显然,这个问题可能与 MockK 有关,因为我能够检索更多日志:

2020-07-24 11:57:15.955 15767-15780/com.my.company.android.debug A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 15780 (HeapTaskDaemon), pid 15767 (e.android.debug)
2020-07-24 11:57:15.997 15962-15962/? E/crash_dump32: failed to detach from thread 15773: No such process
2020-07-24 11:57:15.997 15962-15962/? E/crash_dump32: failed to detach from thread 15778: No such process
2020-07-24 11:57:15.997 15962-15962/? E/crash_dump32: failed to detach from thread 15779: No such process
2020-07-24 11:57:15.997 15962-15962/? E/crash_dump32: failed to detach from thread 15780: No such process

// 20 more times of exact same line //

2020-07-24 11:57:16.007 15962-15962/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2020-07-24 11:57:16.007 15962-15962/? A/DEBUG: Build fingerprint: 'google/sdk_gphone_x86/generic_x86:10/QSR1.190920.001/5891938:user/release-keys'
2020-07-24 11:57:16.007 15962-15962/? A/DEBUG: Revision: '0'
2020-07-24 11:57:16.007 15962-15962/? A/DEBUG: ABI: 'x86'
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG: Timestamp: 2020-07-24 09:57:16+0000
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG: pid: 15767, tid: 15780, name: HeapTaskDaemon  >>> com.my.company.android.debug <<<
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG: uid: 10136
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG: Cause: null pointer dereference
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG:     eax 00000000  ebx ef8a6c34  ecx 00000000  edx f310b604
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG:     edi f3200380  esi 00000000
2020-07-24 11:57:16.008 15962-15962/? A/DEBUG:     ebp e659d9a8  esp e659d940  eip ef7d89f4
2020-07-24 11:57:16.027 2044-2135/? E/InputDispatcher: channel '342ebda com.my.company.android.debug/com.my.compan.android.ui.error.LoginActivity (server)' ~ Channel is unrecoverably broken and will be disposed!

经过进一步调查,在 Android 测试 Github 存储库中有一个存在 1 年的问题(但问题现已关闭): https/ android-test/android-test/android-test/github.com

Mockk 的相关问题已在此处打开: https://github.com/mockk/mockk/issues/466

[编辑 3]

我正在探索 go 的替代方案,回到Mockito ,它具有更多的历史和更积极的发展。 花了一些时间,但我没有遇到重大问题将我的 UI 测试迁移到 Mockito。

结果:嗯,起初崩溃完全消失了。 我可以毫不费力地进行 10、20、30 次测试。 至少在手机上。

然而,在 Android 电视上(仍然有模拟器),崩溃很快再次出现。 然后在移动设备上也是如此,但来自InputDispatcher的可怕消息的频率要低得多。

While setting up the migration to Mockito, I have noticed that Mockk shares the same restrictions & dependencies with Mockito when mocking on Android Test Instrumentation. 我面临同样的问题和同样的困难。

所以这让我相信他们都不是罪魁祸首,但它很可能是 Android Instrumentation API。

我还注意到手动重启模拟器大大改善了这种情况。

这是在我的堆栈跟踪中:

  W  Unexpected CPU variant for X86 using defaults: x86
         ActivityThread  W  Package uses different ABI(s) than its instrumentation:

切换到 64 位模拟器解决了这个问题。

我的仪器测试套件也遇到了这个问题,并且怀疑 MockK (至少部分)有问题。

这远非真正的解决方案,但我注意到使用 Android Test Orchestrator 运行我的测试大大降低了由于测试进程崩溃(由上述段错误引起)导致的随机失败的机会。 (如果您使用 Firebase 测试实验室仿真器运行测试,这可能特别有用。)使用 Orchestrator 的另一个好处是,它在挖掘日志(在 Firebase 测试实验室)以找到根本错误方面做得非常好。在 Orchestrator 进程中确实失败。

我不确定这对每个人都适用,但如果确实如此,它可能表明 MockK(如果它确实是这个问题的根源)没有完全清理并且正在泄漏到其他测试中。

我有完全相同的情况,我的测试在模拟器上随机崩溃, Process crashed错误说检查 Logcat。 Logcat 上存在SIGSEGV错误,但并非总是如此。

在我的情况下,它是com.linkedin.dexmaker:dexmaker-mockito-inline导致随机崩溃。 我不得不将它添加到在我根本不需要的仪器测试中模拟 Kotlin 数据 class 。 所以删除这个依赖解决了我的问题。

我建议调查一下您的测试在什么时候开始崩溃,这样会更容易深入了解它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM