Espresso ile ilgili temel bilgiler

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() ve onData()) 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 koleksiyonu ViewInteraction.perform() yöntemi (örneğin, click()).
  • ViewAssertions – Örnek için ViewAssertion nesne ViewInteraction.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() veya withContentDescription() 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ülemenin R.id yeterli olacaktır.
  • Hedef görünüm bir AdapterView (ör. ListView) içindeyse GridView veya Spinner - onView() yöntemi çalışmayabilir. Bu durumlarda bunun yerine onData() 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ü bulamazsa NoMatchingViewException 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 bulursa AmbiguousViewMatcherException atıldı. Görünüm hiyerarşisi yazdırılır ve Eşleşen görünümler MATCHES 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