Espresso, belirli bir öğeye iki kişi için kaydırma yapmak veya öğe üzerinde işlem yapmak için kullanılabilecek mekanizmalar sunar. bağdaştırıcı görünümleri ve geri dönüşüm gerçekleştirenler görünümleri.
Listelerle, özellikle de bir RecyclerView
veya
AdapterView
nesnesi, ilgilendiğiniz görünüm açık bile olmayabilir
gösterildiği için ekranda az sayıda çocuk gösterildiği
geri dönüştürülür. Bu durumda scrollTo()
yöntemi kullanılamaz
çünkü bunun için mevcut bir görünüm gerekiyor.
Bağdaştırıcı görünümü liste öğeleriyle etkileşimde bulunma
onView()
yöntemini kullanmak yerine, aramanızı onData()
ve
eşlemek istediğiniz görünümü destekleyen verilerle ilgili bir eşleştirici sağlayın.
Espresso, Adapter
nesnesindeki satırı bulma işini tamamlar ve
Böylece, öğeyi görüntü alanında görünür hale getirebilirsiniz.
Özel görünüm eşleştirici kullanarak verileri eşleştirin
Aşağıdaki etkinlik, SimpleAdapter
ile desteklenen bir ListView
içeriyor
Map<String, Object>
nesnesindeki her satır için verileri barındıran bir öğedir.
Her haritada iki giriş vardır: gibi bir Dize içeren anahtar "STR"
"item: x"
ve Integer
değerini içeren "LEN"
anahtarı
daha iyi olur. Örnek:
{"STR" : "item: 0", "LEN": 7}
"item: 50" değerini içeren satırdaki bir tıklamanın kodu şöyle görünür:
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'nun gerektiğinde listede otomatik olarak ilerlediğini unutmayın.
onData()
içindeki Matcher<Object>
öğesini ayıralım. İlgili içeriği oluşturmak için kullanılan
is(instanceOf(Map.class))
yöntemi, aramayı
AdapterView
, Map
nesnesiyle destekleniyor.
Örneğimizde sorgunun bu yönü, liste görünümünün her satırıyla eşleşir, ancak bir öğeyi tıklamak istediğimiz için aramayı şu şekilde daha da daraltırız:
Bu Matcher<String, Object>
, şu giriş içeren tüm haritalarla eşleşir:
"STR"
anahtarı ve "item: 50"
değeri. Çünkü bunu arayacak kod
ve bunu başka konumlarda kullanmak istiyorsak özel bir
Bunun için withItemContent
eşleştirici:
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);
}
};
Yalnızca şu türdeki nesneleri eşleştirmek istediğiniz için, BoundedMatcher
tabanını temel olarak kullanırsınız:
Map
. matchesSafely()
yöntemi geçersiz kılındı, bulunan eşleştirici konur
olarak iletebileceğiniz bir Matcher<String>
ile eşleştirerek,
bağımsız değişkeninin önüne geçer. Böylece withItemContent(equalTo("foo"))
numarasını arayabilirsiniz. Kod için
varsa, halihazırda equalTo()
ve
String
nesnesini kabul eder:
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));
}
Öğeyi tıklama kodu artık basittir:
onData(withItemContent("item: 50")).perform(click())
onData(withItemContent("item: 50")).perform(click());
Bu testin tam kodu için testClickOnItem50()
yöntemine göz atın.
şunun içinde yer alır:
AdapterViewTest
sınıf ve
bu özel LongListMatchers
matcher'ı kullanabilirsiniz.
Belirli bir alt görünümle eşleştir
Yukarıdaki örnek, bir ListView
satırının tamamının ortasına bir tıklama gönderir.
Peki satırın belirli bir alt öğesi üzerinde çalışmak istersek ne olur? Örneğin,
LongListActivity
satırının ikinci sütununu tıklamak istiyor,
değeri görüntülenir:
Uygulamanıza bir onChildView()
spesifikasyonu eklemeniz yeterlidir.
DataInteraction
:
onData(withItemContent("item: 60"))
.onChildView(withId(R.id.item_size))
.perform(click())
onData(withItemContent("item: 60"))
.onChildView(withId(R.id.item_size))
.perform(click());
Geri dönüşüm listesi öğeleriyle etkileşim kurun
RecyclerView
nesneleri, AdapterView
nesnelerden farklı şekilde çalışır.
onData()
, bu kişilerle etkileşimde bulunmak için kullanılamaz.
Espresso kullanarak RecyclerViews ile etkileşimde bulunmak için
Şu koleksiyonun bulunduğu espresso-contrib
paketi:
RecyclerViewActions
Konumlara kaydırmak veya öğeler üzerinde işlem gerçekleştirmek için kullanılabilen özellikler:
scrollTo()
- Varsa eşleşen görünüme kaydırır.scrollToHolder()
: Varsa eşleşen Görüntüleme Sahibine kaydırır.scrollToPosition()
: Belirli bir konuma gider.actionOnHolderItem()
- Eşleşen bir görüntüleme tutucuda bir görüntüleme işlemi gerçekleştirir.actionOnItem()
- Eşleşen bir görünümde görüntüleme işlemi gerçekleştirir.actionOnItemAtPosition()
- Belirli bir konumdaki bir görünümde ViewAction gerçekleştirir.
Aşağıdaki snippet'lerde RecyclerViewSample örnek:
@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"))
)
)
}
@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"))
));
}
@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()))
}
@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()));
}
@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()))
}
@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()));
}
Ek kaynaklar
Android testlerinde Espresso listelerini kullanma hakkında daha fazla bilgi için şu sayfaya bakın: inceleyebilirsiniz.
Örnekler
- DataAdapterSample:
Espresso'nun listeler ve
AdapterView
içinonData()
giriş noktasını gösterir nesneler'i tıklayın.