首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取Android Instrumentation测试的当前活动

获取Android Instrumentation测试的当前活动
EN

Stack Overflow用户
提问于 2014-04-22 10:32:32
回答 3查看 7.4K关注 0票数 7

我的安卓应用程序上的MainActivity会检查用户是否已登录(它存储在SharedPreferences中),如果没有登录,则将用户带到LoginActivity。我正在尝试使用以下代码来测试这一点

代码语言:javascript
复制
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

private static final int TIME_OUT = 5000; /* miliseconds */

private MainActivity mMainActivity;
private Instrumentation mInstrumentation;
private SharedPreferences mLoginPrefs;

public MainActivityTest() {
    super(MainActivity.class);
}

protected void setUp() throws Exception {
    super.setUp();

    setActivityInitialTouchMode(false);

    mMainActivity = getActivity();
    mInstrumentation = getInstrumentation();
    mLoginPrefs = mInstrumentation.getTargetContext().getSharedPreferences(LoginActivity.PREFS_NAME, Context.MODE_PRIVATE);

    SharedPreferences.Editor editor = mLoginPrefs.edit();
            // User is not logged in, so it should be redirect to LoginActivity
    editor.putBoolean("logged_in", false);
    editor.commit();
}

//...

public void testC_OpenLoginActivityIfUserIsNotLoggedIn() {
    ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false);
    Activity nextActivity = mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);

    assertNotNull(nextActivity);
    nextActivity.finish();

    SharedPreferences.Editor editor = mLoginPrefs.edit();
            // Login the user so we can continue the tests
    editor.putBoolean("logged_in", true);
    editor.commit();
}

但是这不起作用,LoginActivity打开了,但是waitForMonitorWithTimeout再也没有返回,所以我被LoginActivity卡住了(我需要回到MainActivity来做其他的测试)。

类似于此SO Question的代码适用于按钮单击,但此活动不是由任何单击加载的,所以我在想,可能没有时间让监视器工作。

我只需要一种方法来获取实际的活动,这样我就可以进行断言并使其完成以继续我的测试。

还有一件事:如果可能的话,我更喜欢不使用Robotium的方法。

EN

回答 3

Stack Overflow用户

发布于 2015-01-10 05:16:21

为了解决你的问题,首先看看你的测试中最重要的两种方法:

代码语言:javascript
复制
Instrumentation#addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean)
Instrumentation.ActivityMonitor#waitForActivity()

根据Android API参考:

addMonitor

添加一个新的Instrumentation.ActivityMonitor,每当启动活动时都将被检查。监视器被添加到任何现有监视器之后;只有当现有监视器本身都不能处理意图时,监视器才会被击中。

waitForActivity

阻塞,直到创建了一个与此监视器匹配的活动,并返回结果活动。

现在让我们把它说得更清楚一点。

addMonitor应该在预期的活动开始之前调用always ,永远不会太晚。

waitForActivity应该只在被启动的预期活动之后调用,永远不要太早,因为它会阻塞。

回到你的代码:

你把他们两个都叫到一起,中间没有任何魔法发生。所以对addMonitor来说要么太晚了,要么对waitForActivity来说太早了。

代码语言:javascript
复制
ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false);
Activity nextActivity = mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);

如果调用waitForActivity太早,它将阻塞并失败,直到超时(因为预期的活动尚未命中),并且您永远看不到预期的活动正在启动。

如果调用addMonitor为时已晚,则会在预期的activity启动后开始监控,此后不会再启动预期的activity,因此waitForActivity会因为监视器没有命中而阻塞。

因此,无论预期的活动是否启动,两种情况之间的差异都是。对于你的情况,我认为现在调用addMonitor已经太晚了。

解决方案非常简单:只需在LoginActivity启动之前将addMonitor移动到足够早的位置,或者将其移动到setUp方法,如下所示:

代码语言:javascript
复制
mInstrumentation = getInstrumentation();
ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false);

顺便说一句,对于你的情况,有没有超时都无关紧要。

在不再需要monitor时,不要忘记将其删除。例如:

代码语言:javascript
复制
@Override
protected void tearDown() throws Exception {
    mInstrumentation.removeMonitor(monitor);
    super.tearDown();
}
票数 11
EN

Stack Overflow用户

发布于 2018-10-27 23:09:37

代码语言:javascript
复制
public static Activity getCurrentActivity() {
    final Activity[] currentActivity = {null};
    getInstrumentation().runOnMainSync(new Runnable() {
        public void run() {
            Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance()
                    .getActivitiesInStage(RESUMED);
            if (resumedActivities.iterator().hasNext()) {
                currentActivity[0] = (Activity) resumedActivities.iterator().next();
            }
        }
    });
    return currentActivity[0];
}
票数 3
EN

Stack Overflow用户

发布于 2014-09-04 13:16:05

你走在了正确的道路上。您需要调用的方法是:

代码语言:javascript
复制
monitor.waitForActivityWithTimeout(TIME_OUT);

而不是

代码语言:javascript
复制
mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23209372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档