2012-08-02 26 views
6

我试图测试两个不同的Activity类,其中一个Activity碰巧称为另一个。这里是我的代码,然后我会解释这个问题:getActivity()方法无限期地阻止单元测试

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用户令牌不为null,它立即开始RootActivity。如果它为空,则保持在IntroActivity。问题是如果它是非空的,第一个测试(IntroActivityTest)通过,然后挂在的getActivity()方法调用中,并且测试只是冻结...没有例外,它只是挂在那条线上。如果用户标记为空,它将完全正确地运行这两个测试。

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

回答

7

按照ActivityInstrumentationTestCase2 API

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

每个ActivityInstrumentationTestCase2实现都完全隔离,并具有其自己的生命周期,而不依赖于其他ActivityInstrumentationTestCase2实现。可测试活动必须始终通过工具基础结构创建,而不是来自被测试应用程序本身。在你的情况下,RootActivityTest不会从应用程序启动IntroActivity启动的RootActivity,也不会启动对RootActivity的持续运行测试。如果有RootActivity来自任何地方(而不是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。

+0

很好的回答!在我的情况下,我需要设置我的监视器_before_我调用了'getActivity()',因为我的新'Activity'从'onCreate()'开始。 – 2012-08-02 23:31:19

0

当以前的测试没有关闭活动时,我遇到了同样的问题,并且新的测试开始时与意图相同。但操作系统Android看到活动已经开始,并没有什么,所以InstrumentationTestCase开始等待已经tsarted的活动