浓缩咖啡不等到活动被销毁,然后再为下一个测试创建新的活动 [英] Espresso not waiting till Activity is destroyed, before creating a new one for the next test

查看:95
本文介绍了浓缩咖啡不等到活动被销毁,然后再为下一个测试创建新的活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the official documentation here: https://google.github.io/android-testing-support-library/docs/rules/index.html, it says:

"此规则提供对单个活动的功能测试. 被测活动将在每个测试都带有注释之前启动 @Test和任何以@Before注释的方法之前. 这将是 测试完成后终止,并用注释所有方法 @完成后.可以在以下期间访问被测活动 您通过调用ActivityTestRule#getActivity()进行测试."

"This rule provides functional testing of a single activity. The activity under test will be launched before each test annotated with @Test and before any method annotated with @Before. It will be terminated after the test is completed and all methods annotated with @After are finished. The Activity under Test can be accessed during your test by calling ActivityTestRule#getActivity()."

从技术上讲,活动已终止. 但是似乎无法保证何时发生.例如.它不一定会在为下一个测试再次创建之前发生.

Technically yes, the Activity is being terminated. But there doesn't seem to be any guarantee as to when this will happen. E.g. it won't necessarily happen before it's created again for the next test.

在我的某些测试中,我需要依靠每次测试后之前开始的OnDestroy或OnDetach片段.我的听众需要清除并重新创建.

In some of my tests, I need to rely on the fragments OnDestroy or OnDetach being called after each test, before the next test starts. I have listeners that need to be cleared and recreated.

如果在当前测试的OnResume之后调用先前测试的onDestroy,则将清除回调,并且视图不会更新,并且测试失败.

If onDestroy from the previous test is called after OnResume in the current test, then the callback is cleared and the view doesn't get updated and the test fails.

如果根本没有调用来自先前测试的onDestroy,则来自当前测试的回调将引用错误的实例.再次,视图将不会更新,并且测试将失败.

If onDestroy from the previous test is not called at all, then the callback from the current test will be referring to the wrong instance. Again the view will not get updated and the test will fail.

  1. 是在设计时针对这种情况进行了讨论,还是一种错误?到目前为止,我在文档中找不到此行为.
  2. 处理此问题的最佳实践是什么?我怀疑其他人也遇到了这个问题.
  1. Is this behaviour discussed in the situation by design or is it a bug? I'm so far unable to find this in the documentation.
  2. What is best practice to handle this? I suspect other people have faced this problem.

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

Edit: I've now solved part 2. See workarounds section below. However if someone can answer part one by citing an official resource then I'd be happy to accept that answer. That's what I'm really asking here. The second part was just a bonus if someone had some ideas.

如果您希望看到此行为,则只需几分钟.使用如下活动创建一个新项目:

If you would like to see this behaviour it will only take a few moments. Create a new project with an Activity like this:

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方法上放置断点,并在调试模式下运行测试套件.

Put breakpoints on the OnResume and OnDestroy methods and run the test suite in debug mode.

多次执行此操作,请注意,Activity生命周期方法的调用顺序不一致.例如.它可能连续调用两次OnResume,然后调用一次OnDestroy,然后再次调用OnResume,两次,然后两次OnDestroy,或者您可以想到的任何其他组合.当然,它总是以至少一个OnResume开始.有时即使在最后它甚至都没有调用OnDestroy,但这很好.不好的是,由于这种不可预测的顺序,我的测试很不稳定.

Do this a few times and notice that the order the Activity life cycle methods are called is not consistent. E.g. it might call OnResume twice in a row, and then call OnDestroy once, and then OnResume twice again, and then OnDestroy three times, or any other combination you can think of. Of course it always starts with at least one OnResume. Sometimes it doesn't even call OnDestroy if it's at the very end, but that's fine. What's not fine is that my tests are flaky because of this unpredicatable order.

我知道这可能是有意的,可能有一种简单的处理方法,我只是很不幸运地找到了它.如果您知道这是什么,请在此处发布答案.事后看来,我不在乎我的问题有多愚蠢,我已经在这个问题上花了很多时间.几乎总是简单的事情,所以我准备为答案感到尴尬.

I'm aware that this might be intentional and there could be a simple way to deal with it, I'm just not lucky enough to have found it. Please if you know what it is, post the answer here. I don't care how dumb my question might be in hindsight, I've spent a LOT of time on this problem. It's almost always something simple so I'm prepared to be embarrassed by the answer.

在onActivateForResult上使用onPause优于OnDestroy,但在平板电脑模式下不会在后台片段中再次调用onResume.我正在探索使这项工作可行的方法,但目前还没有解决方案.

Using onPause over OnDestroy has the side effect of being called when I startActivityForResult, but without calling onResume again in the background fragment while in tablet mode. I'm exploring ways to make this work but no solution as yet.

编辑:onPause遇到了同样的问题-这就是为什么我首先使用onDetach的部分原因.最终,在片段被破坏之前,我有时不想分离监听器.

onPause ended up with the same problem - which is partly why I was using onDetach in the first place. Ultimately, there are times when I don't want to detach the listeners until the fragment is destroyed.

这使我想到了下一个可行的想法! 直到现在,我仍在为调用的Activity创建一个回调,因为它要的是 ,如果该特定的回调不存在.原来,这是一个坏主意.我这样做是为了将回调的数量限制为所需的确切数量.动机是合理的,但是实现需要清除所有这些回调.解决方案是在从片段调用时重新创建每个回调.如果它为空,请不要创建它,总是创建它并替换之前的任何内容.现在完全不需要清除它们(AFAIK).

This leads me to my next idea which worked! Hooray! Up until now I was creating a callback for the calling Activity, for the thing it was asking for, only if that specific callback didn't exist. It turns out this was a bad idea. I did that so I could limit the number of callbacks to the exact number required. The motivation was sound but the implementation required all this callback clearing. The solution is to recreate every callback when ever it's called from the fragment. Don't create it if it's null, always create it and replace whatever was there before. Now there's no need to clear them at all (AFAIK).

推荐答案

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

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

I use fork work around it: https://github.com/shazam/fork

这篇关于浓缩咖啡不等到活动被销毁,然后再为下一个测试创建新的活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆