我刚刚开始使用 MockK 来模拟基于MVP的应用程序中的所有Repository/Services逻辑,以进行UI测试。
我有一些UI测试运行登录 Activity ,在该 Activity 中Espresso输入登录名和密码,并使用MockK可以伪造登录失败或失败的各种情况。
所有服务和存储库都是标准的Kotlin对象,因此我正在使用mockkobjectevery/coEvery覆盖和处理登录请求和任务。
在我的物理设备上,测试完全没有问题,但是一旦我尝试在运行带有推荐图像的Android P +模拟器上运行它们,它们就会在随机时间不断崩溃。而且在极少数情况下,它们可以存活足够长的时间来工作。
查看日志,我得到了各种SIGSEGV:






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

寻找解决方案,这似乎可能是由于内存泄漏引起的?
无论如何,我都确保以@Before方法启动要测试的 Activity ,其中所有模拟都会发生,而我正在清除此类模拟并在@After方法中进行验证。
显然,我相信测试确实可以正常工作,但是Espresso或发生的所有 mock 都一定有问题...
[编辑1]
进一步查看以前的日志,这可能是内存泄漏的原因:

我在模拟器上禁用了AutoFillService(在“相关设置”部分中设置为“无”)。从一开始,这似乎可以提高我的测试成功率,但是经过几次运行,它们仍然崩溃。
现在,日志不再显示此泄漏了。
[编辑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 Test Github存储库上存在一个存在1年的问题,该问题也显示了同样的问题(但问题现已关闭):https://github.com/android/android-test/issues/352
Mockk的一个相关问题已在此处打开:https://github.com/mockk/mockk/issues/466
[编辑3]
我正在探索返回Mockito的替代方法,它具有更多的历史记录和更积极的开发。花了一些时间,但是将UI测试迁移到Mockito时没有大问题。
结果:好,起初崩溃完全消失了。我可以不加急地进行10、20、30次测试。至少在移动设备上。
但是,在Android TV(仍带有模拟器)上,崩溃很快又出现了。然后也可以在移动设备上使用,但使用InputDispatcher发出的可怕消息的方式则更少。
在设置迁移到Mockito的过程中,我注意到当在Android Test Instrumentation上进行模拟时,Mockk与Mockito共享相同的限制和依赖性。我面临同样的问题,同样的困难。
因此,我相信他们都不是罪魁祸首,但是很可能是Android Instrumentation API。
我还注意到,手动重新启动仿真器可以大大改善这种情况。

最佳答案

这是在我的堆栈跟踪中:

  W  Unexpected CPU variant for X86 using defaults: x86
         ActivityThread  W  Package uses different ABI(s) than its instrumentation:
切换到64位仿真器可以解决此问题。

10-08 18:25