单元测试时无限期地阻塞getActivity()方法

时间:2012-08-02 20:29:20

标签: android unit-testing junit android-testing

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

IntroActivityTest

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() );
        }
    }
}

RootActivityTest:

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的用户令牌为非空,则会立即启动RootActivity。如果它为空,则它保持在IntroActivity。问题是,如果它是非null,则第一个测试(IntroActivityTest)通过,然后它挂起getActivity()中的RootActivityTest方法调用,测试就冻结了......没有例外,它只是挂在那条线上。如果用户令牌为null,则它会完全运行两个测试。

可能导致这种情况的原因是什么?从观察来看,似乎RootActivityTest正在尝试使用从RootActivity开始的IntroActivity,但它不应该启动自己的RootActivity实例吗?

2 个答案:

答案 0 :(得分:7)

根据ActivityInstrumentationTestCase2 API

  

此类提供单个活动的功能测试。将使用系统基础结构(通过调用InstrumentationTestCase.launchActivity())创建测试中的活动,然后您将能够直接操作您的活动。

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

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

使用RootActivityTest测试与RootActivity相关的所有内容,在它被启动并带到前面之后,例如,TextView渲染得很好,按钮点击做正确的事等等。在RootActivityTest中,你不需要关心在哪里以及如何RootActivity已启动,只需调用getActivity()并询问有关可测试RootActivity的工具。

答案 1 :(得分:0)

当前一次测试没有关闭活动时我遇到了同样的问题,并且新测试开始时与意图相同。但操作系统Android看到该活动已经启动并且没有任何内容,因此InstrumentationTestCase开始等待已经被攻击的活动