Android 如何在活动片段上运行测试

Android 如何在活动片段上运行测试,android,junit,android-fragments,Android,Junit,Android Fragments,我刚刚开始使用junit,我遇到的第一个问题是,我应该如何测试片段 正在测试的活动有1个片段,这是主布局 @Override protected void setUp() throws Exception { super.setUp(); Intent intent = new Intent(getInstrumentation().getTargetContext(), ActivityWelcome.class); startActivity(

我刚刚开始使用junit,我遇到的第一个问题是,我应该如何测试片段

正在测试的活动有1个片段,这是主布局

@Override
protected void setUp() throws Exception {
    super.setUp();
    Intent intent = new Intent(getInstrumentation().getTargetContext(),
            ActivityWelcome.class);
    startActivity(intent, null, null);

    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
    mFragmentWelcome = (FragmentWelcome) fragmentManager.findFragmentByTag(FragmentWelcome.TAG);
    if (mFragmentWelcome == null) {

        mFragmentWelcome= FragmentWelcome.newInstance();
        fragmentManager
                .beginTransaction()
                .replace(android.R.id.content, mFragmentWelcome, FragmentWelcome.TAG)
                .commit();
    }
}
然后我继续测试布局:

@SmallTest
public void testLayout() {

    ImageButton buttonImage = (ImageButton) getActivity().findViewById(my.package.R.id.button_invites);
    assertNotNull(buttonImage);
    assertEquals("ImageButton Invite has an invalid drawable"
            , getActivity().getResources().getDrawable(my.package.R.drawable.light_social_invite)
            , buttonImage);
}
错误:

java.lang.NullPointerException
    at my.package.test.ActivityWelcomeUnitTest.testLayout(ActivityWelcomeUnitTest.java:55)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
    at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
    at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
    at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
    at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:545)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551)
它在以下情况下失败:

ImageButton buttonImage = (ImageButton) mFragmentWelcome.getView().findViewById(my.package.R.id.button_invites);

我不知道为什么片段是空的,我显然执行了错误的操作,有人能告诉我吗?

实际上,您必须等待UI线程用片段组成主视图

我也有同样的错误,所以我查看了Robotium的来源,看看他们是如何处理的。答案是他们使用了一些等待所需时间的方法

对于fragment,您可以在执行断言之前使用类似的内容:

protected Fragment waitForFragment(String tag, int timeout) {
        long endTime = SystemClock.uptimeMillis() + timeout;
        while (SystemClock.uptimeMillis() <= endTime) {

            Fragment fragment = getActivity().getSupportFragmentManager().findFragmentByTag(tag);
            if (fragment != null) {
                return fragment;
            }
        }
        return null;
    }



编辑:此响应假设您的junit扩展了
ActivityInstrumentationTestCase2

对于
ActivityUnitTestCase
测试,我必须在
waitForFragment
方法中添加以下行:

// haven't really checked if this is necessary
getInstrumentation().waitForIdleSync();
// without this, waitForFragment() failed to find the fragment
getActivity().getFragmentManager().executePendingTransactions();

你可以使用com.robotium.solo.solo从
'com.jayway.android.robotium:robotium solo:5.2.1'

    mInstrumentation = InstrumentationRegistry.getInstrumentation();
    mSolo = new Solo(mInstrumentation);
    mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    .....
    mSolo.waitForFragmentById();

谢谢你的回复。很有意义,但是它没有解析空指针。我似乎无法访问
getView()
您的junit是否扩展了
ActivityInstrumentationTestCase2
?不知道它是否有帮助,但在我的
setup()
上,在所有调用
getActivity()
之前,我会调用
setActivityInitialTouchMode(false)
。我也没有在
startActivity
上打电话。。。最后,尝试增加超时值。谢谢。我使用的是
ActivityUnitTestCase
,它可能不处理片段。是的,但我的错误是我的
ActivityWelcome
默认加载片段,因此它已经存在。这意味着在
setUp()
(我搞混了)中不需要为片段创建(newInstance)代码块。我实际上并不想加载一个“单独的”片段来测试这个特定的实例。完全是我对
ActivityInstrumentationTestCase2
工作原理的误解。谢谢你抽出时间。终于到了!谢谢你澄清这一点@tbruyelle的回答对我不起作用。我已检查是否确实不需要调用
waitForIdleSync()
。是否使用getSUPPORTFragmentManager().ExecutePending执行
MFFragment.getView()
不为空。。。使用ActivityUnitTestCase工作,因为我通过调用getSupportFragmentManager()添加了片段。希望这对某人有所帮助。澄清:事实上,我从未获得要在ActivityCreated上调用的片段,但我确实从findFragmentByTag()方法中获得了不为null的片段。您是如何运行单元测试的。在androidstudio中,我在
Intent-Intent=new-Intent(getInstrumentation().getTargetContext(),ActivityWelcome.class)处获得空指针验证我的testClass正在扩展ActivityUnitTestCase
// haven't really checked if this is necessary
getInstrumentation().waitForIdleSync();
// without this, waitForFragment() failed to find the fragment
getActivity().getFragmentManager().executePendingTransactions();
    mInstrumentation = InstrumentationRegistry.getInstrumentation();
    mSolo = new Solo(mInstrumentation);
    mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    .....
    mSolo.waitForFragmentById();