我正在为一个简单的Android应用程序(这是一个学校项目)编写测试,但在测试活动ContactListActivity时遇到了麻烦,该活动扩展了Android的ListActivity.
我想测试什么
单击ContactListActivity的ListView中的第一项,然后检查ContactDetailActivity是否已启动.
问题
列表数据来自SQLite数据库.为了进行测试,我将测试数据加载到ListView中,因此该测试将无法处理实时数据.加载测试数据工作正常.在运行测试的同时观看仿真器,我可以看到活动正在启动,并且测试数据出现在列表中.但是,尝试访问第一个(也是唯一一个)列表项失败.
测试方法
@UiThreadTest
public final void testLoadContactDetail() {
ListView list = activity.getListView();
assertNotNull(list);
ContactsListAdapter adapter = new ContactsListAdapter(
getInstrumentation().getContext(),
createData() // Creates an ArrayList of test data
);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
// list.getAdapter().getCount() is expectedly 1
// list.getChildCount() is unexpectedly 0
assertNotNull(list.getChildAt(0)); // Assertion fails
// (...)
}
可以看出,我正在使用@UIThreadTest注释测试以能够操作视图元素.使用测试数据创建一个新的ListAdapter并将其设置为列表.然后,adapter.notifyDataSetChanged()确保列表知道新数据.
题
如何将测试数据从ActivityInstrumentationTestCase2内加载到ListView中,以便不仅将数据显示在屏幕上,而且实际上是“在那儿”,这意味着可以使用list.getChildAt(0)提取列表项并单击它?
整个测试用例
public class ContactListActivityFunctionalTest extends
ActivityInstrumentationTestCase2 {
private ContactListActivity activity;
public ContactListActivityFunctionalTest() {
super(ContactListActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(false);
activity = getActivity();
}
protected void tearDown() throws Exception {
super.tearDown();
}
@UiThreadTest
public final void testLoadContactDetail() {
ListView list = activity.getListView();
assertNotNull(list);
ContactsListAdapter adapter = new ContactsListAdapter(
getInstrumentation().getContext(),
createData()
);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
assertNotNull(list.getChildAt(0));
// Anything beyond this point is never executed,
// because the above assertion fails, and I have no idea
// if this test code is correct at all.
ActivityMonitor monitor = getInstrumentation().addMonitor(
ContactDetailActivity.class.getName(), null, false
);
TouchUtils.clickView(this, list.getChildAt(0));
ContactDetailActivity contactDetailActivity =
(ContactDetailActivity)monitor.waitForActivityWithTimeout(2000);
assertNotNull(contactDetailActivity);
assertTrue(getInstrumentation().checkMonitorHit(monitor, 1));
contactDetailActivity.finish();
}
private List createData() {
ContactInterface contact = new Contact();
contact.setId(1L);
contact.setName("Unit Test").setPhone("0123456789").setPosition(3);
List contacts = new ArrayList();
contacts.add(contact);
return contacts;
}
}