【问题标题】:getActivity() method blocking indefinitely while unit testinggetActivity() 方法在单元测试时无限期阻塞
【发布时间】:2012-08-02 20:29:19
【问题描述】:

我正在尝试测试两个不同的 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。问题是,如果它不为空,则第一个测试 (IntroActivityTest) 通过,然后它挂在 RootActivityTest 中的 getActivity() 方法调用上,并且测试只是冻结...没有异常,它只是挂起在那条线上。如果用户令牌为空,它会完全正常运行这两个测试。

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

【问题讨论】:

    标签: android unit-testing junit android-testing


    【解决方案1】:

    根据ActivityInstrumentationTestCase2 API

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

    每个 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。

    【讨论】:

    • 很好的答案!在我的情况下,我需要设置我的监视器之前我打电话给getActivity(),因为我的新Activity 是从onCreate() 开始的。
    【解决方案2】:

    当以前的测试没有关闭活动时,我遇到了同样的问题,而新的测试开始时也有同样的意图。但是 OS Android 看到 Activity 已经开始并且什么也没做,所以 InstrumentationTestCase 开始等待已经被 tsarted 的 Activity

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多