一些背景:
当我运行测试时,我的记忆发生了很大的变化。 我看到了关闭活动/片段场景的建议。 我尝试将其应用于我的所有测试。 对于某些测试来说,这可以正常工作,而对于其他测试来说,这会使事情陷入糟糕的状态。 一次运行一个测试是可行的。运行类中的所有测试,第一个测试有效,其他测试无法启动 ui。 如果我不关闭场景,他们就没事。 我一直在拔头发。 今天我制作了一个电子表格,列出了每个班级以及我认为可能导致问题的各种事情。
一些共享状态? 这似乎是显而易见的(也许在某种程度上这是答案)。 电子表格揭示了一些有趣的事情。 撰写屏幕没有问题。 只有一个撰写屏幕的实例存在问题,然后我意识到,当该屏幕撰写时,该测试正在测试溢出菜单,即布局。
我有一个屏幕的问题非常简单。 它的 viewModel 只有一个设置类、一个协程调度程序和保存的状态句柄(注意布局本身相当复杂,viewModel 及其逻辑很简单)。
我真的认为问题是被注入到具有共享状态的 viewModel 中的。 我已经用假的替换了设置。 那没有帮助。 我玩过我注入的调度程序(后来意识到在没有问题的测试中完全相同)。 在假设置上,我添加了一些东西来在测试之间清除它们。
一些有问题的屏幕只是请求转换为合成。 这样做的危险是删除一些存在问题的简单案例。
所以我知道这种情况发生在布局中而不是组合中。 一些非常简单的布局就暴露了这个问题。 大多数布局都有问题,少数则没有。 有些问题非常简单,有些则相当复杂。 我没有看到任何基于布局的视图显示该问题的模式。
我的一些假设是不正确的。 测试速度变慢,但罪魁祸首不是内存蠕变,而是 Robolectic 和 Compose 的问题。
https://github.com/robolectric/robolectric/issues/9043
最后,创建一个junit规则来重置AndroidUIDispatcher的Choreographer解决了这个问题。
这是 junit 规则的要点: https://gist.github.com/johngray1965/24d7a3f1e5ae5f0fc1adc24444fe12ac
注意:规则在撰写规则之前运行非常重要(否则撰写规则可能会失败)。