我使用ActivityInstrumentationTestCase2测试了一个使用ExoPlayer和正确资源清理的Activity。由于清理和最终检查对所有测试都是相同的,我认为tearDown()是实施它们的好地方。所有测试单独运行没有任何问题,但当我运行多个测试时,有时getActivity()没有返回。我的tearDown()执行了各种操作:
- 检查活动状态(调用各种assert())
- 检查播放器状态(调用各种assert())
- 手动清除播放器资源(调用close()和release())
- setActivity(null)(这引起了问题)
- super.tearDown()
我尝试了所有建议的解决方法,如重写getActivity()和使用instrumentation的其他方法创建和清理活动。这些方法都没有帮助。
大量调试表明,上述情况下前一个测试的活动的onDestory()可能与下一个测试的活动的onCreate()重叠。因此,日志按以下顺序显示生命周期事件:
test1.getActivity();
test1.tearDown() called;
test1.tearDown() over;
test2.getActivity()
test2.onCreate();
test1.onStop(); --> why is this late?
test1.onDestroy(); --> why is this late?
test2.tearDown() called;
test2.tearDown() over;
test3.getActiviy() --> this should call test3.onCreate, but did not and never returned.
即使测试用例在不同的ActivityInstrumentationTestCase2类/文件中实现,这种情况仍会发生。第一次重叠不会导致问题,因此2个测试始终是OK的,但以任何顺序运行3个测试会导致此重叠,从而导致第3个getActivity()调用永远不返回。
我尝试了所有方法,如使用instrumentation手动调用onPause() + onStop() + onDestroy(),在测试之间引入非常长的睡眠期间,强制清除instrumentationTestCase的activity,重新排序tearDown的检查,但没有帮助。最后,我意外地在我的检查之前删除了setActivity(null),并且生命周期事件得到了正确的排序:
test1.tearDown() called;
test1.onStop();
test1.onDestroy();
test1.tearDown() over;
test2.getActivity()
test2.onCreate();
...
所以在我的情况下真正起作用的是:不要调用ActivityTestCase.setActivity()。这会导致super.tearDown()不直接调用活动的生命周期事件,清理将稍后发生并引起问题。