Bu dokümanda, Espresso API'si.
Espresso API, test yazarlarını kullanıcının ne ile karşılaşabileceği konusunda düşünmeye teşvik eder
etkileşimde bulunurken - kullanıcı arayüzü öğelerini bulma ve etkileşimde bulunma
görüntüleyebilirsiniz. Aynı zamanda bu çerçeve, etkinliklere doğrudan erişimi de engelliyor
çok açık olduğundan, bu nesneleri muhafaza etmek ve çalıştırmak için
testlerinde görülen dalgalanmaların önemli bir kaynağıdır. Böylece,
Espresso API'de getView()
ve getCurrentActivity()
gibi yöntemler görmüyor.
Kendi alt sınıflarınızı uygulayarak görünümler üzerinde güvenli bir şekilde çalışmaya devam edebilirsiniz.
ViewAction
ve ViewAssertion
.
API bileşenleri
Espresso'nun ana bileşenleri şunlardır:
- Espresso – Görüntülemelerle etkileşimlere giriş noktası (
onView()
veonData()
) tıklayın. Ayrıca, şunlar gibi herhangi bir görünüme bağlı olmayan API'leri de ortaya çıkarır:pressBack()
olarak. - ViewMatchers:
Matcher<? super View>
arayüzü. Bunlardan birini veya daha fazlasınıonView()
yöntemini kullanın. - ViewActions: Aktarılabilecek
ViewAction
nesne koleksiyonuViewInteraction.perform()
yöntemi (örneğin,click()
). - ViewAssertions – Örnek için
ViewAssertion
nesneViewInteraction.check()
yöntemini geçti. Çoğu zaman onay kutusuyla eşleşir. Bu onay işlemi, şu anda seçili olan görünüm.
Örnek:
Kotlin
// withId(R.id.my_view) is a ViewMatcher // click() is a ViewAction // matches(isDisplayed()) is a ViewAssertion onView(withId(R.id.my_view)) .perform(click()) .check(matches(isDisplayed()))
Java
// withId(R.id.my_view) is a ViewMatcher // click() is a ViewAction // matches(isDisplayed()) is a ViewAssertion onView(withId(R.id.my_view)) .perform(click()) .check(matches(isDisplayed()));
Görünüm bulma
Vakaların büyük çoğunluğunda, onView()
yöntemi bir hamcrest eşleştirici alır
geçerli görünümde yalnızca bir (yalnızca bir) görünümle eşleşmesi beklenen
hiyerarşik olarak düzenlenmiştir. Eşleştiriciler güçlüdür ve bu aracı kullanarak
Mockito veya JUnit ile yapabilirsiniz. Hamcrest eşleştiricilere aşina değilseniz
bu makaleye hızlıca göz atarak
sunu.
Genellikle istenen görünüm benzersiz bir R.id
değerine sahiptir ve basit bir withId
eşleyicisi
görünüm aramasını daraltın. Ancak, karara varmak istediğinize veya
, test geliştirme zamanında R.id
öğesini belirleyemiyor. Örneğin, belirli bir
R.id
öğesi bulunamaz veya R.id
benzersiz değildir. Bu durum, kanalınızın
enstrümantasyon testlerinin yazılması kırılgan ve karmaşıktır çünkü normal yöntem
görünüm erişimi (findViewById()
ile) çalışmaz. Dolayısıyla,
Aktivite veya Parça'nın görünüme sahip gizli üyelerine veya
bilinen R.id
içeren bir kapsayıcı bulun ve
bir görünüm oluşturabilirsiniz.
Espresso, görünümü daraltmanıza olanak tanıyarak bu sorunu sorunsuz bir şekilde
mevcut ViewMatcher
nesneleri veya kendi özel nesnelerinizi kullanabilirsiniz.
R.id
kullanarak bir görünümü bulmak, onView()
çağrısı yapmak kadar basittir:
Kotlin
onView(withId(R.id.my_view))
Java
onView(withId(R.id.my_view));
Bazen R.id
değerleri birden fazla görünüm arasında paylaşılır. Böyle bir durumda,
belirli bir R.id
girişimi size bir istisna sağlar. Örneğin,
AmbiguousViewMatcherException
. İstisna mesajı, alan adının
arayabileceğiniz ve daha kolay bulabileceğiniz mevcut görünüm hiyerarşisinin
benzersiz olmayan R.id
ile eşleşen görünümler:
java.lang.RuntimeException: androidx.test.espresso.AmbiguousViewMatcherException This matcher matches multiple views in the hierarchy: (withId: is <123456789>) ... +----->SomeView{id=123456789, res-name=plus_one_standard_ann_button, visibility=VISIBLE, width=523, height=48, has-focus=false, has-focusable=true, window-focus=true, is-focused=false, is-focusable=false, enabled=true, selected=false, is-layout-requested=false, text=, root-is-layout-requested=false, x=0.0, y=625.0, child-count=1} ****MATCHES**** | +------>OtherView{id=123456789, res-name=plus_one_standard_ann_button, visibility=VISIBLE, width=523, height=48, has-focus=false, has-focusable=true, window-focus=true, is-focused=false, is-focusable=true, enabled=true, selected=false, is-layout-requested=false, text=Hello!, root-is-layout-requested=false, x=0.0, y=0.0, child-count=1} ****MATCHES****
Görünümlerin çeşitli özelliklerini incelediğinizde, İş Listesi’ndeki
özellikleri olabilir. Yukarıdaki örnekte, görünümlerden biri
"Hello!"
Aramanızı daraltmak için
eşleştirenler:
Kotlin
onView(allOf(withId(R.id.my_view), withText("Hello!")))
Java
onView(allOf(withId(R.id.my_view), withText("Hello!")));
Eşleyicilerin hiçbirini tersine çevirmemeyi de seçebilirsiniz:
Kotlin
onView(allOf(withId(R.id.my_view), not(withText("Unwanted"))))
Java
onView(allOf(withId(R.id.my_view), not(withText("Unwanted"))));
Bkz. ViewMatchers
Espresso tarafından sağlanan görünüm eşleştiriciler için geçerlidir.
Dikkat edilmesi gereken noktalar
- Sağlıklı bir uygulamada, kullanıcının etkileşim kurabileceği tüm görünümler
ya açıklayıcı metin ya da bir içerik açıklaması içermelidir. Görüntüleyin
Uygulamaları daha fazla kullanıcı için daha erişilebilir
bolca fırsat sunuyor. Aramanın kapsamını
withText()
veyawithContentDescription()
bunu erişilebilirlik hatası olarak değerlendirebilirsiniz. - Aradığınız görünümü bulan en az açıklayıcı olan eşleştiriciyi kullanın
. Aşırı ayrıntı belirtmeyin. Aksi takdirde, çerçeve daha fazla iş yapmaya zorlar.
bu gereklidir. Örneğin, bir görünüm metniyle benzersiz bir şekilde tanımlanabiliyorsa
görünümün
TextView
öğesinden de atanabileceğini belirtmesine gerek yoktur. Çoğu kişi için görüntülemeninR.id
yeterli olacaktır. - Hedef görünüm bir
AdapterView
(ör.ListView
) içindeyseGridView
veyaSpinner
-onView()
yöntemi çalışmayabilir. Bu durumlarda bunun yerineonData()
kullanmalısınız.
Bir görünümde işlem gerçekleştirme
Hedef görünüm için uygun bir eşleştirici bulduğunuzda,
ViewAction
örneklerini gerçekleştir, gerçekleştir.
Örneğin, görünümü tıklamak için:
Kotlin
onView(...).perform(click())
Java
onView(...).perform(click());
Tek bir performans çağrısı ile birden fazla işlem yürütebilirsiniz:
Kotlin
onView(...).perform(typeText("Hello"), click())
Java
onView(...).perform(typeText("Hello"), click());
Üzerinde çalıştığınız görünüm bir ScrollView
(dikey veya
(yatay) yoksa, görünümün gerçek zamanlı olmasını gerektiren önceki işlemleri
scrollTo()
ile gösterilen (click()
ve typeText()
gibi). Bu
diğer işleme geçmeden önce görünümün görüntülenmesini sağlar:
Kotlin
onView(...).perform(scrollTo(), click())
Java
onView(...).perform(scrollTo(), click());
Bkz. ViewActions
Espresso tarafından sağlanan görüntüleme işlemleri içindir.
Görünüm onaylarını kontrol etme
Onaylar, geçerli olarak seçili görünüme check()
ile uygulanabilir
yöntemidir. En çok kullanılan onay matches()
onayıdır. Bir
Şu anda seçili görünümün durumunu doğrulamak için ViewMatcher
nesnesini kullanın.
Örneğin, bir görünümde "Hello!"
metninin bulunduğundan emin olmak için:
Kotlin
onView(...).check(matches(withText("Hello!")))
Java
onView(...).check(matches(withText("Hello!")));
"Hello!"
öğesinin görünümün içeriği olduğunu iddia etmek istiyorsanız aşağıdaki işlemler kötü uygulama olarak değerlendirilir:
Kotlin
// Don't use assertions like withText inside onView. onView(allOf(withId(...), withText("Hello!"))).check(matches(isDisplayed()))
Java
// Don't use assertions like withText inside onView. onView(allOf(withId(...), withText("Hello!"))).check(matches(isDisplayed()));
Diğer yandan, "Hello!"
metnini içeren bir görünümün
Görünür (örneğin, görüntüleme sayısı görünürlük işareti) değiştikten sonra
sorun yoktur.
Onaylama basit testini göster
Bu örnekte, SimpleActivity
bir Button
ve bir TextView
içeriyor.
düğmesi tıklandığında TextView
öğesinin içeriği "Hello Espresso!"
olarak değişir.
Bunu Espresso ile şu şekilde test edebilirsiniz:
Düğmeyi tıklayın.
İlk adım, düğmeyi bulmanıza yardımcı olacak bir özelliği aramaktır. İlgili içeriği oluşturmak için kullanılan
SimpleActivity
öğesindeki gibi, beklendiği gibi benzersiz bir R.id
değerine sahip.
Kotlin
onView(withId(R.id.button_simple))
Java
onView(withId(R.id.button_simple));
Şimdi tıklamayı gerçekleştirmek için:
Kotlin
onView(withId(R.id.button_simple)).perform(click())
Java
onView(withId(R.id.button_simple)).perform(click());
TextView metnini doğrulama
Doğrulama metnini içeren TextView
için de benzersiz bir R.id
vardır:
Kotlin
onView(withId(R.id.text_simple))
Java
onView(withId(R.id.text_simple));
Şimdi içerik metnini doğrulamak için:
Kotlin
onView(withId(R.id.text_simple)).check(matches(withText("Hello Espresso!")))
Java
onView(withId(R.id.text_simple)).check(matches(withText("Hello Espresso!")));
Bağdaştırıcı görünümlerinde verilerin yüklenmesini kontrol etme
AdapterView
, verilerini
Adaptör. AdapterView
için en yaygın örnek ListView
. Farklı
LinearLayout
gibi statik widget'ların aksine,
Geçerli görünüm hiyerarşisine AdapterView
alt öğe yüklenebilir. Basit bir
onView()
araması, şu anda yüklü olmayan görünümleri bulmaz.
Espresso bunu,onData()
önce söz konusu adaptör öğesini yükleyip üründen önce
üzerinde çalışan kişi veya kuruluşlar.
Uyarı:
AdapterView
, onData()
ile ilgili sorunlar yaşayabilir
Devralma sözleşmelerinin ihlal edilmesi durumunda, özellikle de
getItem()
API. Böyle durumlarda yapılacak en iyi şey
uygulama kodunuzu yeniden düzenleyin. Bunu yapamıyorsanız,
eşleşen özel AdapterViewProtocol
. Daha fazla bilgi için
varsayılan değeri inceleyin
AdapterViewProtocols
sınıfı Espresso tarafından sağlanmıştır.
Adaptör görünümü basit testi
Bu basit testte, onData()
özelliğinin nasıl kullanılacağı gösterilmektedir. SimpleActivity
, bir
Kahveli içecek türlerini temsil eden birkaç öğe içeren Spinner
. Bir
öğe seçildiğinde, "One %s a day!"
olarak değişen bir TextView
bulunur. Burada
%s
, seçilen öğeyi temsil eder.
Bu testin amacı, Spinner
uygulamasını açmak, belirli bir öğeyi seçmek ve
TextView
öğesinin öğeyi içerdiğini doğrulayın. Spinner
sınıfının yeri nedeniyle
AdapterView
üzerinde, şu işlem için onView()
yerine onData()
kullanılması önerilir:
öğe eşleşiyor.
Öğe seçimini aç
Kotlin
onView(withId(R.id.spinner_simple)).perform(click())
Java
onView(withId(R.id.spinner_simple)).perform(click());
Öğe seçme
Öğe seçimi için Spinner
, içeriğiyle bir ListView
oluşturur.
Bu görünüm çok uzun olabilir ve öğe, görünüme katkıda bulunmayabilir
hiyerarşik olarak düzenlenmiştir. onData()
kullanarak, istediğimiz öğeyi görünüme girmeye zorlarız
hiyerarşik olarak düzenlenmiştir. Spinner
içindeki öğeler dize olduğundan bir öğeyi eşleştirmek istiyoruz
Dize "Americano"
değerine eşit:
Kotlin
onData(allOf(`is`(instanceOf(String::class.java)), `is`("Americano"))).perform(click())
Java
onData(allOf(is(instanceOf(String.class)), is("Americano"))).perform(click());
Metnin doğru olduğundan emin olun
Kotlin
onView(withId(R.id.spinnertext_simple)) .check(matches(withText(containsString("Americano"))))
Java
onView(withId(R.id.spinnertext_simple)) .check(matches(withText(containsString("Americano"))));
Hata ayıklama
Espresso, bir test başarısız olduğunda yararlı hata ayıklama bilgileri sağlar:
Günlük kaydı
Espresso, tüm görüntüleme işlemlerini logcat'e kaydeder. Örnek:
ViewInteraction: Performing 'single click' action on view with text: Espresso
Hiyerarşiyi görüntüle
Espresso, onView()
durumunda istisna mesajındaki görünüm hiyerarşisini yazdırır
başarısız olur.
onView()
, hedef görünümü bulamazsaNoMatchingViewException
atılır. Analiz etmek için istisna dizesindeki görünüm hiyerarşisini eşleştiricinin hiçbir görüntülemeyle eşleşmemesinin nedeni.onView()
belirtilen eşleştiriciyle eşleşen birden fazla görünüm bulursaAmbiguousViewMatcherException
atıldı. Görünüm hiyerarşisi yazdırılır ve Eşleşen görünümlerMATCHES
etiketiyle işaretlenir:
java.lang.RuntimeException: androidx.test.espresso.AmbiguousViewMatcherException This matcher matches multiple views in the hierarchy: (withId: is <123456789>) ... +----->SomeView{id=123456789, res-name=plus_one_standard_ann_button, visibility=VISIBLE, width=523, height=48, has-focus=false, has-focusable=true, window-focus=true, is-focused=false, is-focusable=false, enabled=true, selected=false, is-layout-requested=false, text=, root-is-layout-requested=false, x=0.0, y=625.0, child-count=1} ****MATCHES**** | +------>OtherView{id=123456789, res-name=plus_one_standard_ann_button, visibility=VISIBLE, width=523, height=48, has-focus=false, has-focusable=true, window-focus=true, is-focused=false, is-focusable=true, enabled=true, selected=false, is-layout-requested=false, text=Hello!, root-is-layout-requested=false, x=0.0, y=0.0, child-count=1} ****MATCHES****
Karmaşık bir görünüm hiyerarşisi veya widget'ların beklenmedik davranışlarıyla başa çıkarken Android Studio'da Hiyerarşi Görüntüleyici bir açıklamadır.
Bağdaştırıcı görünümü uyarıları
Espresso, kullanıcıları AdapterView
widget'larının varlığı hakkında uyarır. onView()
işlemi bir NoMatchingViewException
ve AdapterView
widget'ları oluşturuyor
olması nedeniyle, en yaygın çözüm onData()
kullanmaktır.
İstisna mesajı, bağdaştırıcı görünümlerinin listesini içeren bir uyarı içerir.
Hedef görünümü yüklemek amacıyla onData()
yöntemini çağırmak için bu bilgileri kullanabilirsiniz.
Ek kaynaklar
Android testlerinde Espresso'yu kullanma hakkında daha fazla bilgi için şu sayfaya bakın: inceleyebilirsiniz.
Örnekler
- CustomMatcherSample (Özel Eşleme Örneği):
Espresso'nun, bir
EditText
nesnesinin ipucu özelliğiyle eşleşecek şekilde nasıl genişletileceğini gösterir. - RecyclerViewSample:
Espresso için
RecyclerView
işlem. - (diğer...)