android - getActivity() 方法在单元测试时无限期阻塞

标签 android unit-testing junit android-testing

我正在尝试测试两个不同的 Activity 类,其中一个 Activity 恰好调用另一个。这是我的代码,然后我将解释问题:

介绍 Activity 测试

public class IntroActivityTest extends ActivityInstrumentationTestCase2<IntroActivity> {

    IntroActivity activity;

    public IntroActivityTest() {

        super( IntroActivity.class );
    }

    @Override
    protected void setUp() throws Exception {

        super.setUp();
        activity = getActivity();
    }

    public void testIntroBypass() {

        if ( new SharedPreferencesHelper( getInstrumentation().getTargetContext() ).retrieveUserToken() == null ) {
            assertTrue( !activity.isFinishing() );
        }
        else {
            assertTrue( activity.isFinishing() );
        }
    }
}

根 Activity 测试:

public class RootActivityTest extends ActivityInstrumentationTestCase2<RootActivity> {

    RootActivity activity;

    public RootActivityTest() {

        super( RootActivity.class );
    }

    @Override
    protected void setUp() throws Exception {

        super.setUp();
        activity = getActivity();
    }

    public void testInitialTab() {

        assertTrue( activity.getSupportActionBar().getSelectedTab().getText().toString().equalsIgnoreCase( "Library" ) );
    }
}

IntroActivityTest 中,如果来自 SharedPreferences 的用户 token 不为空,它会立即启动 RootActivity。如果它为 null,它将停留在 IntroActivity 上。问题是,如果它是非空的,第一个测试 (IntroActivityTest) 通过,然后它卡在 RootActivityTest< 中的 getActivity() 方法调用上 并且测试只是卡住......没有异常(exception),它只是卡在那条线上。如果用户 token 为 null,它会完全正常地运行这两个测试。

这可能是什么原因造成的?根据观察,RootActivityTest 似乎正在尝试使用从 IntroActivity 启动的 RootActivity,但它不应该启动自己的实例吗RootActivity?

最佳答案

根据ActivityInstrumentationTestCase2 API :

This class provides functional testing of a single activity. The activity under test will be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity()) and you will then be able to manipulate your Activity directly.

每个 ActivityInstrumentationTestCase2 实现都是完全隔离的,并且有自己的生命周期,不依赖于其他 ActivityInstrumentationTestCase2 实现。可测试的 Activity 必须始终通过检测基础设施创建,而不是从被测应用程序本身创建。在您的情况下,RootActivityTest 不会从应用程序和针对 RootActivity 的持续运行测试中获取由 IntroActivity 启动的 RootActivity。如果有一个 RootActivity 不知从何而来(不是由 InstrumentationTestRunner 产生)并被带到前面,当运行 RootActivityTest 时,InstrumentationTestRunner 会在尝试创建可测试的 RootActivity 时感到困惑,并简单地停止并等待这个陌生人被杀死。

要测试您想要的,即 如果来自 SharedPreferences 的用户 token 不为空,它会立即启动 RootActivity。如果为空,则保留在 IntroActivity 上,您可以在 IntroActivityTest 中编写所有内容并使用 Instrumentation.ActivityMonitor从 IntroActivity 开始检测 RootActivity。查看here对于代码示例。请注意,您需要在 IntroActivityTest 中完成测试后完成 RootActivity,以便在 RootActivityTest 中调用 getActivity() 时 RootActivity 可以正常启动。

使用 RootActivityTest 来测试与 RootActivity 相关的一切,在 RootActivity 启动并被带到前面后,例如,TextView 呈现良好,按钮点击做正确的事情等等。在 RootActivityTest 中,您不需要关心在哪里以及如何RootActivity 已启动,只需调用 getActivity() 并向仪器询问可测试的 RootActivity。

关于android - getActivity() 方法在单元测试时无限期阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11785239/

相关文章:

unit-testing - 在 TDD 中,我如何确保测试本身不会过时(并错误地报告 SUCCESS)?

android - 从 AsyncTask 设置 TextView 的文本时未找到资源 ID

android - 同时在 editText 中提示和文本

android - 如何订购这样的元素?

android - 在 Activity 和 Service 之间共享首选项

java - 为什么这个 EasyMock 测试失败?

unit-testing - TestNG 可以看到我的 Spock (JUnit) 测试结果吗?

java - 集群 ehcache 的 Junit 测试策略

gradle compileJava 错误 : package org. junit 不存在

java - 为什么运行 mvn clean install 命令(在 Spring Boot 项目上)如果我注释掉这些方法来跳过测试,我也会遇到单元测试失败?