Android Espresso Test gets stuck at perform(click(

2019-05-10 21:12发布

问题:

I am using Espresso for some automated test cases. The scenario is:

I have an activity which holds two fragments say FrgA and FrgB.

FrgA consists of a list with some items which takes the user to the FrgB on click of them.

Once FrgB is displayed, I check for existence of an gridview on FrgB. The code I use for this is:

@Test
public void testProductsDisplayed(){
    onData(anything()).atPosition(1).perform(click());
    onView(withId(R.id.gridview)).check(matches(isDisplayed()));
}

The problem I have been facing is, the list item from FrgA gets clicked successfully and it also takes me to the FrgB which has the GridView. But my test won't proceed to the line 2 of the test case and gets stucked on the first line (click()). After some time it gets timed out. Strange thing is, if I remove the gridview and place some TextView and search for it's existence, the test passes without any error.

The only thing I can think of is some timing issue while it is loading the gridview contents in FrgB. The code for FrgB is as follows:

public class FrgB extends BaseFragment implements OnItemClickListener {
private View mView;
private List<Product> mProducts;
private ImagesAdapter mAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Log.d("Kart", "In onActivityCreated");

    GridView gvProducts = findTypedViewById(mView, R.id.gvProducts);
    mAdapter = new ImagesAdapter(getActivity(), R.layout.image_grid_item, new ArrayList<Product>());

    if(getArguments() != null && getArguments().containsKey(Constants.CATEGORY_ID)){
        String catId = getArguments().getString(Constants.CATEGORY_ID);
        Log.d("Kart", "In onActivityCreated - activity is: "+getActivity());
        if(getActivity() == null){
            Log.e("Kart", "Activity does not exist");
        }else{
            mProducts = ((ScrLanding)getActivity()).getProductsForCategory(catId);
            mAdapter.addAll(mProducts);
        }

        gvProducts.setAdapter(mAdapter);
        gvProducts.setOnItemClickListener(this);

    } else{
        returnToLastScreen();
    }
}
/**
 * Method to remove current fragment from fragment manager
 */
private void returnToLastScreen() {
    UiHelper.showToast(getString(R.string.msg_no_products), Toast.LENGTH_SHORT);
    removeFragment(this);       
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    mView = inflater.inflate(R.layout.frg_product_listing, container, false);
    return mView;
}


@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
    switch (parent.getId()) {
    case R.id.gvProducts:
        FrgProductDetails fragment = new FrgProductDetails();
        Bundle bundle = new Bundle();
        bundle.putSerializable(Constants.PRODUCT_INFO, mProducts.get(position));
        ((ScrLanding)getActivity()).setSelectedProductBitmap(mAdapter.getThumbsMap().get(position));
        fragment.setArguments(bundle);
        addFragment(fragment, R.id.fragment_container);
        break;

    default:
        break;
    }
}

}

Where am I going wrong?

回答1:

I had the same issue while I was working with a ListView.

Interestingly, I noticed that the test would resume if I manually tried to scroll the screen. Adding this line solved the issue and resumed the test.

 onView(withId(R.id.myListView)).perform(swipeUp());


回答2:

Workaround 1:

Add a JUnit timeout on the test that is causing the hang. This will allow the test to fail and continue to the next test. The stack trace of the timeout message should indicate where it is getting stuck.

Info on how to add timeouts: Mark as failed running too long JUnit tests

Workaround 2:

Try to run Espresso tests on newer versions of Android OS, like Android 5.1 (API 22) or above. Some older versions, like Android 4.1, can have problems running Espresso tests that are mixed with other tests, especially on ARM emulator.

Example problems can be test hangs or the app crashing during a test suite. For example, you could also get this error on older Android OS:

Test failed to run to completion. Reason: 'Instrumentation run failed due to 'Process crashed.''. Check device logcat for details

More info here and here and here.

Newer Android versions will run Instrumentation tests more reliably.