Espresso는 2명의 사용자를 위해 특정 항목으로 스크롤하거나 작업할 수 있는 메커니즘을 제공합니다. 목록 유형: 어댑터 뷰와 recycler 뷰입니다.
목록, 특히 RecyclerView
또는
AdapterView
객체가 있는 경우 사용자가 관심 있는 뷰가
소수의 하위 요소만 표시되고
재활용됩니다. 이 경우에는 scrollTo()
메서드를 사용할 수 없습니다.
기존 뷰가 필요하기 때문입니다
어댑터 뷰 목록 항목과 상호작용
onView()
메서드를 사용하는 대신 onData()
로 검색을 시작합니다.
일치시키려는 뷰를 지원하는 데이터에 대한 매처를 제공합니다.
Espresso가 Adapter
객체에서 행을 찾는 모든 작업을 실행합니다.
항목이 표시 영역에 표시되도록 합니다.
맞춤 뷰 매처를 사용하여 데이터 일치
아래 활동에는 SimpleAdapter
에서 지원하는 ListView
가 포함되어 있습니다.
- Map<String, Object>
객체의 각 행에 대한 데이터를 보유하는 객체입니다.
각 지도에는 다음과 같은 문자열이 포함된 "STR"
키, 이렇게 두 개의 항목이 있습니다.
"item: x"
, 키를 나타내는 Integer
가 포함된 "LEN"
키
지정할 수 있습니다. 예를 들면 다음과 같습니다.
{"STR" : "item: 0", "LEN": 7}
'item: 50'이 있는 행을 클릭하기 위한 코드는 다음과 같습니다.
Kotlin
onData(allOf(`is`(instanceOf(Map::class.java)), hasEntry(equalTo("STR"), `is`("item: 50")))).perform(click())
자바
onData(allOf(is(instanceOf(Map.class)), hasEntry(equalTo("STR"), is("item: 50")))) .perform(click());
Espresso는 필요에 따라 자동으로 목록을 스크롤합니다.
onData()
내부의 Matcher<Object>
를 분해해 보겠습니다. 이
is(instanceOf(Map.class))
메서드는 검색 범위를
AdapterView
: Map
객체로 지원됩니다.
여기서는 쿼리의 이 측면은 목록 뷰의 모든 행과 일치하지만 원하는 항목을 찾기 위해 다음을 사용하여 검색 범위를 더 좁힙니다.
Kotlin
hasEntry(equalTo("STR"), `is`("item: 50"))
자바
hasEntry(equalTo("STR"), is("item: 50"))
이 Matcher<String, Object>
은
키 "STR"
및 값 "item: 50"
이를 조회하는 코드는
다른 위치에서 다시 사용하고 싶다면 커스텀
이를 위한 withItemContent
매처:
Kotlin
return object : BoundedMatcher<Object, Map>(Map::class.java) { override fun matchesSafely(map: Map): Boolean { return hasEntry(equalTo("STR"), itemTextMatcher).matches(map) } override fun describeTo(description: Description) { description.appendText("with item content: ") itemTextMatcher.describeTo(description) } }
자바
return new BoundedMatcher<Object, Map>(Map.class) { @Override public boolean matchesSafely(Map map) { return hasEntry(equalTo("STR"), itemTextMatcher).matches(map); } @Override public void describeTo(Description description) { description.appendText("with item content: "); itemTextMatcher.describeTo(description); } };
유형의 객체만 일치시키기 위해 BoundedMatcher
를 기본으로 사용합니다.
Map
matchesSafely()
메서드를 재정의하여 발견된 매처를 삽입합니다.
로 전달할 수 있는 Matcher<String>
과 대조합니다.
인수입니다. 이렇게 하면 withItemContent(equalTo("foo"))
를 호출할 수 있습니다. 코드용
간결성을 위해 equalTo()
를 이미 호출하는 다른 매처를 만들고
다음과 같이 String
객체를 허용합니다.
Kotlin
fun withItemContent(expectedText: String): Matcher<Object> { checkNotNull(expectedText) return withItemContent(equalTo(expectedText)) }
자바
public static Matcher<Object> withItemContent(String expectedText) { checkNotNull(expectedText); return withItemContent(equalTo(expectedText)); }
이제 항목을 클릭하는 코드는 간단합니다.
Kotlin
onData(withItemContent("item: 50")).perform(click())
자바
onData(withItemContent("item: 50")).perform(click());
이 테스트의 전체 코드는 testClickOnItem50()
메서드를 살펴보세요.
범위
AdapterViewTest
클래스 및
이 맞춤 LongListMatchers
를 참조하시기 바랍니다.
특정 하위 뷰 일치
위의 샘플은 ListView
의 전체 행 중간에서 클릭을 발생시킵니다.
하지만 행의 특정 하위 요소에 관해 작업하려면 어떻게 해야 하나요? 예를 들어
LongListActivity
행의 두 번째 열을 클릭하려고 합니다.
첫 번째 열에 콘텐츠의 String.length를 표시합니다.
onChildView()
사양을
DataInteraction
:
Kotlin
onData(withItemContent("item: 60")) .onChildView(withId(R.id.item_size)) .perform(click())
자바
onData(withItemContent("item: 60")) .onChildView(withId(R.id.item_size)) .perform(click());
Recycler 뷰 목록 항목과 상호작용
RecyclerView
객체는 AdapterView
객체와 다르게 작동하므로
onData()
은(는) 상호작용하는 데 사용할 수 없습니다.
Espresso를 사용하여 RecyclerView와 상호작용하려면
espresso-contrib
패키지 - 다음 항목이 포함됩니다.
RecyclerViewActions
위치로 스크롤하거나 항목에 대한 작업을 실행하는 데 사용할 수 있는 는 다음과 같습니다.
scrollTo()
- 일치하는 뷰가 있는 경우 해당 뷰로 스크롤합니다.scrollToHolder()
- 일치하는 뷰 홀더가 있는 경우 해당 뷰 홀더로 스크롤합니다.scrollToPosition()
- 특정 위치로 스크롤합니다.actionOnHolderItem()
- 일치하는 뷰 홀더에서 ViewAction을 실행합니다.actionOnItem()
- 일치하는 뷰에서 ViewAction을 실행합니다.actionOnItemAtPosition()
- 특정 위치의 뷰에서 ViewAction을 실행합니다.
다음 스니펫에는 RecyclerView샘플 샘플:
Kotlin
@Test(expected = PerformException::class) fun itemWithText_doesNotExist() { // Attempt to scroll to an item that contains the special text. onView(ViewMatchers.withId(R.id.recyclerView)) .perform( // scrollTo will fail the test if no item matches. RecyclerViewActions.scrollTo( hasDescendant(withText("not in the list")) ) ) }
Java
@Test(expected = PerformException.class) public void itemWithText_doesNotExist() { // Attempt to scroll to an item that contains the special text. onView(ViewMatchers.withId(R.id.recyclerView)) // scrollTo will fail the test if no item matches. .perform(RecyclerViewActions.scrollTo( hasDescendant(withText("not in the list")) )); }
Kotlin
@Test fun scrollToItemBelowFold_checkItsText() { // First, scroll to the position that needs to be matched and click on it. onView(ViewMatchers.withId(R.id.recyclerView)) .perform( RecyclerViewActions.actionOnItemAtPosition( ITEM_BELOW_THE_FOLD, click() ) ) // Match the text in an item below the fold and check that it's displayed. val itemElementText = "${activityRule.activity.resources .getString(R.string.item_element_text)} ${ITEM_BELOW_THE_FOLD.toString()}" onView(withText(itemElementText)).check(matches(isDisplayed())) }
Java
@Test public void scrollToItemBelowFold_checkItsText() { // First, scroll to the position that needs to be matched and click on it. onView(ViewMatchers.withId(R.id.recyclerView)) .perform(RecyclerViewActions.actionOnItemAtPosition(ITEM_BELOW_THE_FOLD, click())); // Match the text in an item below the fold and check that it's displayed. String itemElementText = activityRule.getActivity().getResources() .getString(R.string.item_element_text) + String.valueOf(ITEM_BELOW_THE_FOLD); onView(withText(itemElementText)).check(matches(isDisplayed())); }
Kotlin
@Test fun itemInMiddleOfList_hasSpecialText() { // First, scroll to the view holder using the isInTheMiddle() matcher. onView(ViewMatchers.withId(R.id.recyclerView)) .perform(RecyclerViewActions.scrollToHolder(isInTheMiddle())) // Check that the item has the special text. val middleElementText = activityRule.activity.resources .getString(R.string.middle) onView(withText(middleElementText)).check(matches(isDisplayed())) }
Java
@Test public void itemInMiddleOfList_hasSpecialText() { // First, scroll to the view holder using the isInTheMiddle() matcher. onView(ViewMatchers.withId(R.id.recyclerView)) .perform(RecyclerViewActions.scrollToHolder(isInTheMiddle())); // Check that the item has the special text. String middleElementText = activityRule.getActivity().getResources() .getString(R.string.middle); onView(withText(middleElementText)).check(matches(isDisplayed())); }
추가 리소스
Android 테스트에서 Espresso 목록을 사용하는 방법에 관한 자세한 내용은 확인할 수 있습니다
샘플
- DataAdapterSample:
목록 및
AdapterView
에 관한 Espresso의onData()
진입점을 보여줍니다. 객체입니다.