如何在活动片段上运行testing

我刚刚开始了,我碰到的第一个问题是,我应该如何testing片段?

被testing的活动有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(); } } 

然后我继续testing版面:

 @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); 

我不知道为什么这个片段是空的,我显然是不正确地执行这个操作,有人请赐教吗?

Solutions Collecting From Web of "如何在活动片段上运行testing"

其实你必须等待UI线程与片段组成主视图。

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

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

 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; } 

我用了5000ms的超时时间,看起来效果不错。

所以在你的代码中你应该replace

 mFragmentWelcome = (FragmentWelcome) fragmentManager.findFragmentByTag(FragmentWelcome.TAG); 

通过

 mFragmentWelcome = (FragmentWelcome) waitForFragment(FragmentWelcome.TAG, 5000); 

编辑:这个回应假设你的junit扩展了ActivityInstrumentationTestCase2<T>

对于ActivityUnitTestCasetesting,我不得不waitForFragment添加到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();