Espresso不会等到活动被破坏,然后在为下一次测试创建一个新活动之前

Mic*_*ovo 9 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. 这种行为是在设计中讨论的还是一个bug?到目前为止,我无法在文档中找到它.
  2. 处理这个问题的最佳做法是什么?我怀疑其他人都遇到过这个问题.

编辑:我现在已经解决了第2部分.请参阅下面的解决方法部分.但是,如果有人可以通过引用官方资源来回答第一部分,那么我很乐意接受这个答案.这就是我在这里真正要求的.第二部分只是一个奖励,如果有人有一些想法.


证据

如果你想看到这种行为,它只需要一些时间.使用如下所示的Activity创建一个新项目:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

和这样的测试类:

@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() {
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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


解决方法

在onSttroy上使用onPause具有在startActivityForResult时调用的副作用,但在平板电脑模式下不在后台片段中再次调用onResume.我正在探索如何使这项工作,但尚未解决.

编辑: onPause最终遇到了同样的问题 - 这也是我在第一时间使用onDetach的部分原因.最终,有时候我不想在片段被破坏之前分离监听器.

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

chi*_*uki 3

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

我使用 fork 解决它: https: //github.com/shazam/fork