Espresso不会等到活动被销毁,然后为下一次测试创建一个新活动

时间:2017-03-04 03:26:38

标签: android android-espresso

情况

在这里的官方文档中:https://google.github.io/android-testing-support-library/docs/rules/index.html,它说:

  

“此规则提供单个活动的功能测试   在每次测试注释之前,将启动被测活动   @Test以及在使用@Before注释的任何方法之前。 会的   测试完成后终止并且所有方法都注释了   @After完成。可以在访问期间访问测试中的活动   通过调用ActivityTestRule#getActivity()进行测试。“

技术上是的,活动正在终止。 但似乎没有任何保证何时会发生这种情况。例如。它不一定会在下次测试再次创建之前发生。

问题

在我的一些测试中,我需要依赖每次测试后调用的片段OnDestroy或OnDetach,下一次测试开始之前。我有需要清理和重新创建的听众。

如果在当前测试中在OnResume之后调用上一次测试中的onDestroy,则清除回调并且视图不会更新并且测试失败。

如果根本没有调用上一次测试中的onDestroy,那么当前测试的回调将引用错误的实例。同样,视图不会更新,测试也会失败。

问题

  1. 这种行为是在设计中讨论的还是一个错误?我到目前为止还没有在文档中找到这个。
  2. 处理此问题的最佳做法是什么?我怀疑其他人都遇到过这个问题。
  3. 编辑:我现在已经解决了第2部分。请参阅下面的解决方法部分。但是,如果有人可以通过引用官方资源来回答第一部分,那么我很乐意接受这个答案。这就是我在这里真正要求的。第二部分只是一个奖励,如果有人有一些想法。

    证据

    如果您希望看到此行为,则只需要一些时间。使用如下活动创建一个新项目:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
        }
    }
    

    和这样的测试类:

    @RunWith(AndroidJUnit4.class)
    @LargeTest
    public class EspressoLifecycleTest {
    
        @Rule
        public ActivityTestRule<MainActivity> mActivityRule =
            new ActivityTestRule<>(MainActivity.class);
    
        @Test
        public void test1() {
        }
    
        @Test
        public void test2() {
        }
    
        @Test
        public void test3() {
        }
    
        @Test
        public void test4() {
        }
    }
    

    在OnResume和OnDestroy方法上放置断点并以调试模式运行测试套件。

    执行此操作几次并注意调用Activity生命周期方法的顺序不一致。例如。它可能连续两次调用OnResume,然后再调用OnDestroy一次,再调用OnResume两次,然后再调用OnDestroy三次,或者你能想到的任何其他组合。当然,它始终以至少一个OnResume开头。有时它甚至不会调用OnDestroy,如果它在最后,但那很好。有什么不好的是因为这个不可预测的订单,我的测试很不稳定。

    我知道这可能是有意的,并且可能有一种简单的方法来处理它,我只是没有幸运地找到它。如果你知道它是什么,请在这里发布答案。事后我并不在乎我的问题是多么愚蠢,我花了很多时间来解决这个问题。它几乎总是很简单,所以我准备好让答案感到尴尬。

    变通方法

    在onSttroy上使用onPause会产生在startActivityForResult时调用的副作用,但在平板电脑模式下不会在背景片段中再次调用onResume。我正在探索实现这项工作的方法,但尚无解决方案。

    编辑: onPause最终遇到了同样的问题 - 这也是我首先使用onDetach的部分原因。最终,有些时候我不想在片段被破坏之前分离听众。

    这让我想到了下一个有用的想法! Hooray!到目前为止,我正在为调用Activity创建一个回调,因为它要求的是 ,如果那个特定的回调不存在。事实证明这是一个坏主意。我这样做了所以我可以将回调次数限制为所需的确切数量。动机是合理的,但实施需要所有这些回调清算。解决方案是在从片段调用时重新创建每个回调。如果它为null,则不要创建它,始终创建它并替换之前的任何内容。现在根本不需要清除它们(AFAIK)。

2 个答案:

答案 0 :(得分:3)

这是一个错误:http://b.android.com/201513

我使用fork工作:https://github.com/shazam/fork

答案 1 :(得分:0)

之前注意到这个问题和解决方案&#39;我可以想到的是覆盖ActivityTestRule中的方法: afterActivityFinished() beforeActivityLaunched()。基本上你想检查并等待在下次测试执行之前清除监听器。

IMO,这是ActivityTestRule的错误。