Android: Writing test cases for Fragments
Here's a rough guide using ActivityInstrumentationTestCase2
:
Step 1. Create a blank Activity to hold your fragment(s)
private static class FragmentUtilActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout view = new LinearLayout(this);
view.setId(1);
setContentView(view);
}
}
Step 2: Inside your test, instantiate your fragment and add it to the blank activity
public class MyFragmentTest extends ActivityInstrumentationTestCase2<FragmentUtilActivity> {
private MyFragment fragment;
@Before
public void setup() {
fragment = new MyFragment();
getActivity().getFragmentManager().beginTransaction().add(1, fragment, null).commit();
}
}
Step 3 Test your instantiated fragment
@Test
public void aTest() {
fragment.getView().findViewById(...);
}
If you're using robolectric, this is pretty straightforward using the FragmentUtilTest class:
@Test
public void aTest() {
// instantiate your fragment
MyFragment fragment = new MyFragment();
// Add it to a blank activity
FragmentTestUtil.startVisibleFragment(fragment);
// ... call getView().findViewById() on your fragment
}
Here is my working solution:
Create an instrumentation unit test class for this in androidTest directory, i.e.:
public class FragmentTest extends ActivityInstrumentationTestCase2<MainActivity> { private MainActivity testingActivity; private TestFragment testFragment; //... }
call this constructor inside this new class:
public FragmentTest() { super(MainActivity.class); }
override the setUp() method (be sure to have R.id.fragmentContainer in your Activity class) where you will call at the end waitForIdleSync():
@Override protected void setUp() throws Exception { super.setUp(); // Starts the activity under test using // the default Intent with: // action = {@link Intent#ACTION_MAIN} // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK} // All other fields are null or empty. testingActivity = getActivity(); testFragment = new TestFragment(); testingActivity.getFragmentManager().beginTransaction().add(R.id.fragmentContainer,testFragment,null).commit(); /** * Synchronously wait for the application to be idle. Can not be called * from the main application thread -- use {@link #start} to execute * instrumentation in its own thread. * * Without waitForIdleSync(); our test would have nulls in fragment references. */ getInstrumentation().waitForIdleSync(); }
Write a test method, for example somethng like:
public void testGameFragmentsTextViews() { String empty = ""; TextView textView = (TextView)testFragment.getView().findViewById(R.id.myTextView); assertTrue("Empty stuff",(textView.getText().equals(empty))); }
Run the test.