我正在尝试测试两个不同的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() );
        }
    }
}

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中的用户 token 为非null,它将立即启动RootActivity。如果为null,则保留在IntroActivity上。问题是,如果它不是非null,则第一个测试(IntroActivityTest)通过,然后卡在getActivity()中的RootActivityTest方法调用上,并且测试只是卡住...没有异常,它只是卡在该行上。如果用户 token 为空,则运行两个测试都将完全正常。

是什么原因造成的?通过观察,看来RootActivityTest试图使用从RootActivity开始的IntroActivity,但是它不应该在启动自己的RootActivity实例吗?

最佳答案

根据ActivityInstrumentationTestCase2 API:



每个ActivityInstrumentationTestCase2实现都是完全隔离的,并且具有自己的生命周期,该生命周期不依赖于其他ActivityInstrumentationTestCase2实现。必须始终通过检测基础结构而不是从被测应用程序本身来创建可测试 Activity 。在您的情况下,RootActivityTest将不会从IntroActivity中启动应用程序中的RootActivity,也不会继续针对RootActivity运行测试。如果有RootActivity从无处来(不是InstrumentationTestRunner提供的)并且位于最前面,则在运行RootActivityTest时,在尝试创建可测试的RootActivity时InstrumentationTestRunner会感到困惑,只需停止并等待这个陌生人被杀死即可。

要测试您想要的内容,即(如果SharedPreferences中的用户 token 不为空),它将立即启动RootActivity。如果为空,它将停留在IntroActivity的上,您可以在IntroActivityTest中编写所有内容,并使用Instrumentation.ActivityMonitor检测从IntroActivity启动的RootActivity。 checkout here以获得代码示例。请注意,在IntroActivityTest中完成测试后,您需要完成RootActivity,以便在RootActivityTest中调用getActivity()时可以正确启动RootActivity。

使用RootActivityTest可以测试与RootActivity相关的所有内容,例如,启动TextView效果良好,单击按钮进行正确的操作等。在RootActivityTest中,您无需担心RootActivity在何处以及如何启动,只需调用getActivity()并向工具要求可测试的RootActivity。

09-04 10:34