Android UIAutomator Testing: Count of all elements present in the list view

user3452860 picture user3452860 · Mar 23, 2014 · Viewed 8.7k times · Source

While doing mobile UI Automation testing using Android UIAutomator, I need to find out all the elements present in the list view.

By using 'getChildCount()' method as shown below, I am getting the count of currently visible elements only, but more elements are present in the list view but are invisible.

Here is the sample code:

    //Created UI Object for list view
UiObject listview_elements = new UiObject(new UiSelector().className("android.widget.ListView"));


//Printing the numbmer of child ements present in the List View by using getchildCount() method
System.out.println("List view elements : "+listview_elements.getChildCount());*

Could any one kindly help to get the count of all list view elements including invisible elements (i.e currently not displayed on the screen).

Note: Kindly note that here I am not implementing android UI, rather I am just testing the third party android app's UI using Android's UIAutomator.

Answer

Markymark picture Markymark · Feb 10, 2016

A bit late but here are some suggestions.

Remember that you can use UI Automator Viewer to identify resource ids and such. AndroidSDKPath\tools\uiautomatorviewer

A couple considerations that change how we approach this.

  • Are items in the list clickable?
  • Are items in the list the same size?
  • Do the items contain distinct text fields?

Assuming the items in the list are clickable you can use a selector like this:

UiSelector selector = new UiSelector().clickable(true);

If the items do contain distinct text fields then you can perhaps use a Java Set to keep track of strings that represent each item.

If the items in the list are the same size then you can use a loop and scroll up by the same amount each time. Otherwise you can look at the next item in the list, get its bounds, get the top coordinate, and then scroll upward until you reach the top of the list (this might be the bottom of a toolbar). You can check if you hit the top by looking at the bounds.

When writing a loop the idea would be to only increment the index if you reach the end of the list since when you scroll up the top most item will become position 0.

Your loop would look something like this:

//UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());;
UiObject list = device.findObject(new UiSelector().resourceId(PACKAGE + ":id/" + resourceId));

int index = 0;
int count = 0;

while (index < list.getChildCount()) {
    UiObject listItem = list.getChild(selector.index(index));

    Set<String> examinedItems = new LinkedHashSet<>();

    //if first item is a bit out of view (under toolbar) then skip it
    if (listItem.getBounds().top < TOOLBAR_BOTTOM_Y) {
        index++;
        continue;
        //this will only ever happen once = reached end of list
    }

    //get unique details from each item
    //for example, you might get a text field for that list item list this
    //UiObject textField = listItem.getChild(new UiSelector().resourceId(PACKAGE + ":id/" + childResourceId));
    String itemDetails = ...;

    //this would be relevent if the list was perfectly scrolled to the top and we don't know we are at the end of the list
    if (examinedItems.contains(itemDetails)) {
        index++;
        continue;
    }

    //do any actual testing on the item here..
    count++;

    //if index > 0 we have reached the end of the list
    if (index == 0) {
        //you'll need to inherit from InstrumentationTestCase so you can pass an instance to this method
        TouchUtils.drag(this, CENTER_X, CENTER_X, START_SCROLL_Y, START_SCROLL_Y - ITEM_HEIGHT, 150);
    }

    examinedItems.add(itemDetails);
}

//maybe return count here