我刚刚开始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);
我不确定为什么片段为空,我显然执行此操作不正确,有人可以赐教我吗?
答案 0 :(得分:9)
实际上你必须等待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的超时,似乎运行良好。
因此,在您的代码中,您应该替换
mFragmentWelcome = (FragmentWelcome) fragmentManager.findFragmentByTag(FragmentWelcome.TAG);
通过
mFragmentWelcome = (FragmentWelcome) waitForFragment(FragmentWelcome.TAG, 5000);
编辑:此回复假设您的junit延长ActivityInstrumentationTestCase2<T>
答案 1 :(得分:4)
对于ActivityUnitTestCase
测试,我必须将以下行添加到waitForFragment
方法中:
// haven't really checked if this is necessary
getInstrumentation().waitForIdleSync();
// without this, waitForFragment() failed to find the fragment
getActivity().getFragmentManager().executePendingTransactions();
答案 2 :(得分:1)
你可以使用'com.jayway.android.robotium:robotium-solo:5.2.1'
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mSolo = new Solo(mInstrumentation);
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
.....
mSolo.waitForFragmentById();