Espresso测试ListView项目单击childView的动作(扩展FrameLayout)

问题描述 投票:0回答:1

我有一个活动,在这个活动中,我有多个子视图:

public class CategoriesActivity extends AppCompatActivity {

    private StaggeredGridLayoutManager categoryGridLayoutManager;
    private DrawerLayout mDrawerLayout;
    private RecyclerView recyclerView;
    private NavigationView navigationView;
    private List<Category> categoryList;
    private Toolbar toolbar;
    private MaterialSearchView searchView;
    ...
 }

我有一个工具栏,在这个工具栏上有一个菜单按钮和一个搜索按钮。

主屏幕如下所示:

[初始画面](https://imgur.com/bk0GXyOm.png

单击搜索按钮时,搜索视图将在现有列表视图的顶部打开,如下所示:

[搜索屏幕](https://imgur.com/XefVGFwm.png

我有兴趣测试搜索的功能,更准确地说,用Espresso测试点击搜索视图的每一行的动作(例如,点击'Hello',然后点击'Bonjour'等) 。

到目前为止我所拥有的是以下内容(获得建议的数量):

@RunWith(AndroidJUnit4.class)
public class CategoryActivityInstrumentedTests {
    @Rule
    public ActivityTestRule<CategoriesActivity> activityActivityTestRule = new ActivityTestRule<CategoriesActivity>(CategoriesActivity.class);

    @Before
    public void init(){
        //activityActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction();
        Utils.level = 2;
    }

    @Test
    public void TestSuggestions(){
        onView(withId(R.id.action_search)).perform(click());
        onView(withId(R.id.search_view)).perform(new MyCustomViewAction());
    }

    public class MyCustomViewAction implements ViewAction {
        int size = 0;
        @Override
        public Matcher<View> getConstraints(){
            return isAssignableFrom(MaterialSearchView.class);
        }


        @Override
        public String getDescription(){
            return "whatever, size = " + size;
        }

        @Override
        public void perform(UiController uiController, View view){
            MaterialSearchView yourCustomView = (MaterialSearchView) view;
            size = yourCustomView.getSuggestionsCount();
            System.out.println(size);
            yourCustomView.mSuggestionsListView.performItemClick(yourCustomView.mSuggestionsListView.getAdapter().getView(1, null, null), 1, yourCustomView.mSuggestionsListView.getAdapter().getItemId(1));
                    //getItemAtPosition(0) toString(); // .performClick();
            Log.e(Constants.TAG_CategoriesActivity, " size = " + size);

        }

    }
}

问题是我无法在此活动中获取此列表(搜索视图包含建议列表),因此,我无法对此视图的元素执行单击操作。

当我在MyCustomViewAction中执行单击时,它可以正常工作但我在主活动中得到一个空指针异常,因为viewGroup未初始化。

这是我的搜索视图的代码:

public class MaterialSearchView extends FrameLayout implements Filter.FilterListener {

    //Views
    private View mSearchLayout;
    private View mTintView;
    public ListView mSuggestionsListView;
    private EditText mSearchSrcTextView;
    private ImageButton mBackBtn;
    private ImageButton mVoiceBtn;
    private ImageButton mEmptyBtn;
    private RelativeLayout mSearchTopBar;
    ...
}

有任何想法吗 ?谢谢!


编辑

我在我的测试方法TestSuggestions()中尝试了以下调用:

onData(allOf(withText("Bonjour"))) // Find the row in the list .inAdapterView(withId(R.id.search_view)) // Find the list in the view hierarchy .perform(click());

我得到以下异常:

`I/TestRunner: android.support.test.espresso.PerformException: Error performing 'load adapter data' on view 'with id: com...:id/search_view'.`
java android android-espresso android-testing
1个回答
0
投票

我终于找到了解决方案(至少有2个解决方案):

第一解决方案

    @Test
    public void TestSuggestions1(){
        for (int i=0 ; i<4081; i++) {

            onView(withId(R.id.action_search)).perform(click());    // opens the search
            Espresso.pressBack();   // performs the go back action to dismiss the keyboard
            onData(anything())      // selects the actual item at the desired position (which opens another activity)
                    .atPosition(i)
                    .perform(click());
            Espresso.pressBack();   // performs the go back action from the newer activity
            Log.e("TestSuggestions", " i = " + i);
        }
    }

我一直到4081,因为这是我的建议数量。

二解决方案:

    @Test
    public void TestSuggestions2() {
        for (i = 0; i < 4081; i++) {
            onView(withId(R.id.action_search)).perform(click());    // opens the search
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Espresso.pressBack();   // performs the go back action from the newer activity
            onView(withId(R.id.search_view)).perform(new MyCustomViewAction()); // selects the actual item at the desired position (which opens another activity)
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Espresso.pressBack();
        }
    }

使用以下MyCustomViewAction:

    public class MyCustomViewAction implements ViewAction {
        int size = 0;

        @Override
        public Matcher<View> getConstraints(){
            return isAssignableFrom(MaterialSearchView.class);
        }

        @Override
        public String getDescription(){
            return "whatever, size = " + size;
        }

        @Override
        public void perform(UiController uiController, View view){
            MaterialSearchView yourCustomView = (MaterialSearchView) view;
            size = yourCustomView.getSuggestionsCount();
            yourCustomView.mSuggestionsListView.performItemClick(yourCustomView.mSuggestionsListView.getAdapter().getView(i, null, null), i, yourCustomView.mSuggestionsListView.getAdapter().getItemId(i));
            Log.e(Constants.TAG_CategoriesActivity, " size = " + size);
        }
    }

其中i是我的TestClass中的一个全局变量,从0开始。

© www.soinside.com 2019 - 2024. All rights reserved.