Espresso如何测试Activity是否已经完成?

33

我想要确认一下,当执行某些操作后,我目前正在测试的Activity已经结束。不幸的是,到目前为止,我只能通过在测试结束时添加一些延迟来进行确认。有更好的方法吗?

import android.content.Context;
import android.os.Build;
import android.support.test.rule.ActivityTestRule;
import android.test.suitebuilder.annotation.LargeTest;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import static org.junit.Assert.assertTrue;

@SuppressWarnings("unchecked")
@RunWith(JUnit4.class)
@LargeTest
public class MyActivityTest {

    Context context;

    @Rule
    public ActivityTestRule<MyActivity> activityRule
            = new ActivityTestRule(MyActivity.class, true, false);

    @Before
    public void setup() {
        super.setup();
        // ...
    }

    @Test
    public void finishAfterSomethingIsPerformed() throws Exception {

        activityRule.launchActivity(MyActivity.createIntent(context));

        doSomeTesting();

        activityRule.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                fireEventThatResultsInTheActivityToFinishItself();
            }
        });

        Thread.sleep(2000); // this is needed :(

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            assertTrue(activityRule.getActivity().isDestroyed());
        }

    }

}
8个回答

61

对于我的情况,我可以测试isFinishing()

assertTrue(activityTestRule.getActivity().isFinishing());

而不是:

    Thread.sleep(2000); // this is needed :(

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        assertTrue(activityRule.getActivity().isDestroyed());
    }

isFinishing() 的另一个优点是,您不需要进行版本检查。


当然,使用isFinishing()很好,但您没有解决问题的主要问题,即如何解决睡眠问题。 - Nicolás Carrasco-Stevenson
1
在我看来,OP 是在寻求更好的断言方式,以避免使用 Thread.sleep - keineantwort
2
我注意到在测试代码后可以避免使用Thread.sleep()。但是你忘了提到这一点,所以我编辑了你的回答,使这一点更加明确。 - Nicolás Carrasco-Stevenson

8
也许有点晚,但这也是可能的:
assertThat(activityRule.getActivityResult(), hasResultCode(Activity.RESULT_CANCELED));

6

ActivityTestRule 已经过时了,现在我的回答基于 ActivityScenario,它是 ActivityTestRule 的新替代品。

要测试当前 activity 是否结束(已销毁)或不会。您可以简单地编写以下代码-

方法1: ActivityScenario.launch(YourActivityName::class.java).use { activityScenario -> // 您的测试代码}

  assertTrue(activityScenario.state == Lifecycle.State.DESTROYED)
}
  • activityScenario.state表示正在测试的Activity的当前状态
  • Lifecycle.State.DESTROYED表示Activity已经被销毁

方法二:

ActivityScenario<MyActivity> scenario = ActivityScenario.launch(MyActivity.class);
   // Let's say MyActivity has a button that finishes itself.
   onView(withId(R.id.finish_button)).perform(click());
   assertThat(scenario.getResult().getResultCode()).isEqualTo(Activity.RESULT_OK);

方式2可行,但您需要通过以下方式正确启动活动:ActivityScenario.launchActivityForResult(MyActivity.class); - Noya

2
如果您的活动中没有设置结果,您可以直接使用以下代码:
assertTrue(activityRule.scenario.result.resultCode == Activity.RESULT_CANCELED)

1

不确定这是否是一个好的做法,但对我有效:

assertTrue(mTestRule.getActivity() == null);

1

0

您可以使用下面的StartActivityForResult示例,在链接中有更多描述。

如何从FirstActivity启动Activity:

Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, 1);

这是如何完成你的SecondActivity并返回到第一个活动(不发送结果)的方法:

Intent returnIntent = new Intent();
setResult(Activity.RESULT_CANCELED, returnIntent);
finish();

如何在 SecondActivity 完成后引发事件(在 FirstActivity 中编写):

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

   if (requestCode == 1) {

   }
}//onActivityResult

更多相关信息可以在这里找到:http://developer.android.com/training/basics/intents/result.html,以及这里 如何在Android上管理`startActivityForResult`?,其中还介绍了如何发送你想要从SecondActivity获取的数据。


感谢您的回复。我想我表达得不够清楚。我的问题是我没有第二个活动或第一个活动。我只有一个活动。所以,我只能在启动一个虚拟的第一个活动后才能从那里启动我想要测试的活动,然后才能使用您的解决方案。 - JoachimR
所以你有可运行的代码,并且想在它完成后执行一些操作? - kilian eller
我想确保在调用fireEventThatResultsInTheActivityToFinishItself()之后,我的活动会被关闭。 - JoachimR

0
val latch = CountDownLatch(1)
activityScenarioRule.scenario.onActivity {
        it.lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onDestroy(owner: LifecycleOwner) = latch.countDown()
        })
    }
latch.await(8, TimeUnit.SECONDS).let { Assert.assertTrue(it) }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接