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

Jas*_*son 6 junit android unit-testing 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() );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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" ) );
    }
}
Run Code Online (Sandbox Code Playgroud)

IntroActivityTest,如果用户令牌来自SharedPreferences非空,则立即启动RootActivity.如果它为null,则保持打开状态IntroActivity.问题是,如果它是非null,则第一个test(IntroActivityTest)通过,然后它挂起getActivity()方法调用RootActivityTest并且测试只是冻结...没有例外,它只是挂在那一行上.如果用户令牌为null,则它会完全运行两个测试.

可能是什么导致了这个?从观察来看,它似乎RootActivityTest是试图使用从RootActivity它开始的IntroActivity,但不应该是它自己的实例RootActivity

yor*_*rkw 7

根据ActivityInstrumentationTestCase2 API:

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

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

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

使用RootActivityTest测试与RootActivity相关的所有内容,在它被启动并带到前面之后,例如,TextView渲染得很好,按钮点击做正确的事等等.在RootActivityTest中,您不需要关心RootActivity的启动位置和方式,只需调用getActivity()并向instrumentation请求可测试的RootActivity.