Espresso ile bir diyalog görüntülenip görüntülenmediğini kontrol edin


87

Yeni android test kiti (Espresso) ile bazı testler yazmaya çalışıyorum . Ancak bir iletişim kutusunun görüntülenip görüntülenmediğini nasıl kontrol edeceğime ve üzerinde bazı eylemler gerçekleştireceğime dair herhangi bir bilgi bulamıyorum (pozitif ve negatif düğmelerine tıklamak gibi). Bir iletişim kutusunun WebViewuygulama tarafından değil, a tarafından da görüntülenebileceğini unutmayın.

Herhangi bir yardım memnuniyetle karşılanacaktır. Sadece bir bağlantıya veya temel bilgiler için bir örnek koda ihtiyacım var:

  1. Bir iletişim kutusunun görünüp görünmediğini kontrol edin
  2. İletişim düğmelerine tıklama gerçekleştirin
  3. İletişim kutusunun iç görünümüyle etkileşim kurun (özel bir görünümse)
  4. İletişim kutusunun dışındaki tıklamaları önceden biçimlendirin ve görüntülenip görüntülenmediğini kontrol edin (örneğin setCancelable(false), iletişim kutusu oluşturucuda çağrıldıysa ve bunu kontrol etmek istiyoruz)

Fikrin için teşekkürler!


Aşağıdaki cevabımla ilgili herhangi bir geri bildirim var mı?
2014

Yanıtlar:


125
  1. İletişim kutusunun görünüp görünmediğini doğrulamak için, iletişim kutusunda bulunan bir metinle Görüntüle'nin gösterilip gösterilmediğini kontrol edebilirsiniz:

    onView(withText("dialogText")).check(matches(isDisplayed()));
    

    veya kimliğine sahip metne göre

    onView(withId(R.id.myDialogTextId)).check(matches(allOf(withText(myDialogText), isDisplayed()));
    
  2. Diyaloglar düğmesine tıklamak için bunu yapın (düğme1 - Tamam, düğme2 - İptal):

    onView(withId(android.R.id.button1)).perform(click());
    

    GÜNCELLEME

  3. Espresso çoklu pencere desteğine sahip olduğu için mümkün olduğunu düşünüyorum .
  4. Özel iletişim kutusu görünümünün dışına tıklamaktan emin değilsiniz, ancak görüntülenip görüntülenmediğini kontrol etmek için özel eşleştiricinizi oluşturmanız ve içini kontrol etmeniz gerekir.

3
Adım 1, bir ProgressDialog'da benim için işe yaramadı. Sadece iletişim kutusunun Başlığını ve Mesajını doğrulamaya çalışıyorum
Tim Boland

1
Espresso ve statik ithalatta ne var? Bu yöntemler hangi sınıflardan geliyor? Yığın taşması yanıtında neden statik içe aktarmalar kullanıyorsunuz?

2
@jvrodrigues her Espresso öğreticisi statik içe aktarmalar kullanır. Sadece alışmanızı öneririm (gerçi hayal kırıklığını anlasam da). Bu yardımcı olur: google.github.io/android-testing-support-library/docs
AutonomousApps

Adım 4 için iletişim kutusunun dışına tıklamak yerine "pressBack ();" bu iletişim kutusunu kapatır. donanım geri düğmesini kullanmaya eşdeğerdir.
Ethan

@denys projesi taşındı. Görünüşe göre bağlantı kesildi.
Neon Warge

67

Şu anda bunu kullanıyorum ve iyi çalışıyor gibi görünüyor.

onView(withText(R.string.my_title))
    .inRoot(isDialog()) // <---
    .check(matches(isDisplayed()));

28

Bunun gibi bir AlertDialog'unuz varsa:

görüntü açıklamasını buraya girin

Bileşenlerin görüntülenip görüntülenmediğini kontrol edebilirsiniz:

int titleId = mActivityTestRule.getActivity().getResources()
        .getIdentifier( "alertTitle", "id", "android" );

onView(withId(titleId))
        .inRoot(isDialog())
        .check(matches(withText(R.string.my_title)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.text1))
        .inRoot(isDialog())
        .check(matches(withText(R.string.my_message)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.button2))
        .inRoot(isDialog())
        .check(matches(withText(android.R.string.no)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.button3))
        .inRoot(isDialog())
        .check(matches(withText(android.R.string.yes)))
        .check(matches(isDisplayed()));

ve bir eylem gerçekleştirin:

onView(withId(android.R.id.button3)).perform(click());

2
Benim durumumdaki metnin kimliği android.R.id.messageve başlığın gizli kimliği vardı android.R.id.alertTitle.
Jason Robinson

2
AppCompat destek kitaplığından gelen AlertDialog (veya DialogFragment) kullanıyorsanız, şunu kullanın:int alertDialogTitleId = android.support.v7.appcompat.R.id.alertTitle;
Mr-IDE

Herhangi birinin parametre değerlerini bilmesi gerektiğinde, stackoverflow.com/a/15488321/1713366 . Adı veya tanım türünü bilmiyorsanız, var olmayan check()bir görünümü deneyin ve logcat üzerindeki düzen hiyerarşisine bakın. Bunlardan bir sürü göreceksiniz defType = name. Örneğin message=hello world, o zaman parametreniz şöyle görünmelidir"hello world", "message", "your package name"
Jcorretjer

3

Kabul edilen cevabın olmadığı 4. soruyu cevaplamak için, burada bir Toast görüntülenip görüntülenmediğini test etmek için Stack Overflow'da ( bağlantı ) bulduğum aşağıdaki kodu değiştirdim .

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @IdRes int id) {
    return onView(withId(id)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

idGeçirilen bir tanımlama numarası olan Viewşu anda iletişim kutusunda görüntülenen. Yöntemi şöyle de yazabilirsiniz:

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @NonNull String text) {
    return onView(withText(text)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

Ve şimdi Viewbelirli bir metin dizesi içeren bir metin arıyor .

Bunu şu şekilde kullanın:

getRootView(getActivity(), R.id.text_id).perform(click());

3

Ids R.id.button1 ve R.id.button2 butonları cihazlar arasında aynı olmayacak. Kimlikler, işletim sistemi sürümlerine göre değişebilir.

Bunu başarmanın doğru yolu UIAutomator kullanmaktır. UIAutomator bağımlılığını build.gradle dosyanıza ekleyin

// Set this dependency to build and run UI Automator tests
  androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'

ve kullan

// Initialize UiDevice instance
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

// Search for correct button in the dialog.
UiObject button = uiDevice.findObject(new UiSelector().text("ButtonText"));
if (button.exists() && button.isEnabled()) {
    button.click();
}

1
Aslında android.R.id.button1, android.R.id.button2ve android.R.id.button3"Pozitif" için, "tarafsız" ve "negatif", küresel sembollerdir olabilir kullanılabilir. Düğmeleri metinleri aracılığıyla seçmeyi seçerseniz - ki bu tamamen iyidir - UIAutomator'a ihtiyacınız yoktur, ancak Espresso'larla aynı şeyi yapabilirsiniz onView(withText("ButtonTest")).perform(click()).
Thomas Keller

Bu çözümü bir Robotium test çerçevesi ile kullandım ve Android işletim sistemi iletişim kutusu düğmelerini kolaylıkla seçebildim. Bana çok zaman kazandırdı. Teşekkürler jaydeepw!
Ray

@ThomasKeller Geçmişte button1, button2 kimlikleri kullandım, çeşitli cihazlarda çalıştırdığımda testlerim bozuldu. Gösterilen iletişim kutusu sistem kontrolüdür. Sizin kontrolünüz / kullanıcı arayüzünüz değil. Kullanıcı arayüzünüz dışındaki herhangi bir şey için UIAutomator önerilir.
JaydeepW

Bu kadar. Çok teşekkür ederim.
1lb3r

3

Birinin bu soruya benim yaptığım gibi tökezlemesi durumunda. Tüm yanıtlar yalnızca iletişim düğmeleri OLAN diyaloglar için çalışacaktır. Kullanıcı etkileşimi olmadan ilerleme diyalogları için bunu denemeyin ve kullanmayın. Espresso, uygulamanın boşta kalma durumuna girmesini beklemeye devam ediyor. İlerleme iletişim kutusu görünür olduğu sürece uygulama boşta değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.