Soru Espresso - Görünümden birinin görüntülenip görüntülenmediğini kontrol etme


Benim testimde, bir eylemden sonra, görünebilen iki olası görüş vardır ve her ikisi de doğrudur. Görünümlerden birinin görüntülenip görüntülenmediğini nasıl kontrol edebilirim. Tek bir görünüm için kontrol edebilirim (). Ancak bunun yerine başka bir görünüm görünürse bu başarısız olur. Bu iki görüntüden herhangi birinin görüntülenmesi durumunda testi geçmek istiyorum.

onMyButton.perform(click());

onMyPageOne.check(matches(isDisplayed())); //view 1
or
onMyPageTwo.check(matches(isDisplayed())); //view 2

Sonra, MyButton'a tıklayın, görünümün (1 veya 2) herhangi birinin görünmesi beklenir, ancak her ikisi de olmaz. Hangisinin görüntüleneceği düzeltilmez. Herhangi birinin görüntülenip görüntülenmediğini nasıl kontrol edebilirim?


33
2018-03-25 08:16


Menşei


Bağlantıya göre code.google.com/p/android-test-kit/wiki/..., "Yukarıdaki yaklaşım hala hiyerarşinin bir parçasıysa, yukarıdaki yaklaşım çalışır". "Görünümün görüntülenmediğini ileri sürmek" konusundaki metni arayın. - The Original Android


Cevaplar:


Espresso'nun bu gibi istisnalarını yakalamak mümkün:

Bir görünümün hiyerarşide olup olmadığını sınamak isterseniz:

try {
    onView(withText("Button")).perform(click());
    // View is in hierarchy

} catch (NoMatchingViewException e) {
    // View is not in hierarchy
}

Bu istisna, eğer görünüm ise atılacak değil hiyerarşide.

Bazen görünüm hiyerarşide olabilir, ancak görüntülenip görüntülenmediğini test etmemiz gerekir, bu nedenle şu gibi iddialar için başka bir istisna vardır:

try {
    onView(withText("Button")).check(matches(isDisplayed()));
    // View is displayed
} catch (AssertionFailedError e) {
    // View not displayed
}

37
2017-11-05 17:39



ama bir zaman aşımı için beklemek zorunda ve zaman aşımları ile uğraşmak yerine sadece "bu şey burada, evet ya da hayır" kontrol etmek daha güzel olurdu. Buradaki tek neden, bulut cihazı testi için cihaz dakikalarını azaltmam gerekmesi. Bir istisna vurmak için 30 saniye beklemek yeterli değildir ve zaman aşımlarını bağlamsal olarak yönetmek yanlış - Saik Caskey
İstisnalar beklemek genellikle bir kod kokusu, bilinmeyen girdileri ayrıştırma gibi bazı istisnalar hariç - ama bu tartışılabilir bile. - RyPope
Bu cevabı beğeniyorum, esas olarak soru, eğer elemanın görünür olup olmadığını kullanıcıya bildirmek için ViewAssertion yerine bir boole değeri (true veya false) döndüren herhangi bir API varsa. Bu yararlıdır, dolayısıyla otomatik fonksiyonel testler buna göre kodlanabilir. - MG Developer


Burada, örtmeye çalıştığınız iki durum var. Birincisi, manzaranın kontrol edilip edilmediğini kontrol etmektir. "Ekranda kullanıcıya gösterilir" hangi durumda kullanırsın isDisplayed()

onView(matcher).check(matches(isDisplayed()));

ya da olumsuzlama

onView(matcher).check(matches(not(isDisplayed())));

Diğer durum, eğer görüntünün görünüp görünmeyeceğini kontrol etmektesiniz, ancak ekranda gösterilmiyorsa (ör., Kaydırma görünümünde bir öğe). Bunun için kullanabilirsiniz withEffectiveVisibility(Visibility)

onView(matcher).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));

19
2017-11-22 18:30



Teşekkürler @RyPope, görünürlük testi çalıştı. - user1510006


Kullanabilirsiniz Matchers.anyOf İki görünümden birinin görüntülenip görüntülenmediğini kontrol etmek için:

onView(
   anyOf(withId(R.id.view_1), withId(R.id.view_2)) 
).check(matches(isDisplayed()));

15
2018-06-10 22:09



1 VEYA 2 görünümünün görüntülenip görüntülenmediğini kontrol etmek için viewMatcher'da anyOf kullanabilirsiniz. - Luiz Augusto
Bu kod, 2 görüntüden 1'inin tam olarak görüntülendiğinden emin olmak için çalışmaz. Yaptığından emin misin? - Dipesh Rathod


Görünüm olup olmadığını kontrol etmenizi sağlayan yardımcı program sınıfı visible, gone veya invisible:

public class ExtraAssertions {
    public static ViewAssertion isVisible() {
        return new ViewAssertion() {
            public void check(View view, NoMatchingViewException noView) {
                assertThat(view, new VisibilityMatcher(View.VISIBLE));
            }
        };
    }

    public static ViewAssertion isGone() {
        return new ViewAssertion() {
            public void check(View view, NoMatchingViewException noView) {
                assertThat(view, new VisibilityMatcher(View.GONE));
            }
        };
    }

    public static ViewAssertion isInvisible() {
        return new ViewAssertion() {
            public void check(View view, NoMatchingViewException noView) {
                assertThat(view, new VisibilityMatcher(View.INVISIBLE));
            }
        };
    }

    private static class VisibilityMatcher extends BaseMatcher<View> {

        private int visibility;

        public VisibilityMatcher(int visibility) {
            this.visibility = visibility;
        }

        @Override public void describeTo(Description description) {
            String visibilityName;
            if (visibility == View.GONE) visibilityName = "GONE";
            else if (visibility == View.VISIBLE) visibilityName = "VISIBLE";
            else visibilityName = "INVISIBLE";
            description.appendText("View visibility must has equals " + visibilityName);
        }

        @Override public boolean matches(Object o) {

            if (o == null) {
                if (visibility == View.GONE || visibility == View.INVISIBLE) return true;
                else if (visibility == View.VISIBLE) return false;
            }

            if (!(o instanceof View))
                throw new IllegalArgumentException("Object must be instance of View. Object is instance of " + o);
            return ((View) o).getVisibility() == visibility;
        }
    }
}

Ve kullanım şöyle görünebilir:

onView(withId(R.id.text_message)).check(isVisible());

5
2018-02-23 14:33





Espresso'yu biraz araştırdım ve bunu buldum. Espresso Örnekleri.

  1. Arama metni "Bir görünümün görüntülenmediğini ileri sürmek". “Yukarıdaki yaklaşım hala hiyerarşinin bir parçasıysa, yukarıdaki yaklaşım işe yarar” diyor. Bu yüzden kodunuzun çalışması gerektiğini düşünüyorum ama kullanmanız gerekiyor ViewAssertions Ayrıca. Kodunuzu kullanarak, belki bunu yapın:

    if (ViewAssertions.doesNotExist()) == null) {
       return;
    }
    onMyPageOne.check(matches(isDisplayed()));
    
  2. Başka bir teknik, UI varlığını kontrol etmektir. "Görünümün mevcut olmadığını ileri sürme" metnini arayın. Kodunuzu kullanarak en iyi önerim:

    onMyPageOne.check (doesNotExist ());

Not: Bu çağrılar doesNotExist yöntem.

Onların örnek kodları: onView(withId(R.id.bottom_left)).check(doesNotExist());


5
2018-03-25 17:13



Kullanılacak olan bu. Yapmıyordum (isDisplayed ()) :( - Juan Mendez


Sorun şu ki hepsi assertoin() ve check() yöntemler geri dön Assertion başarısız olursa test akışını durdurur.


2
2018-03-30 14:48



Tam olarak sorun bu! Bunu yapmanın bir yolu olup olmadığını bilmiyorum. herhangi bir Espresso uzmanı? - user846316
Bu bir yorum olmalı, sanırım - Willi Mentzel


Bir Düğme veya bir Düğme gibi alt sınıflarını kontrol etmenin basit bir yolu yöntem kullanmaktır getVisibility itibaren Görünüm sınıf. Görünürlük özniteliğinin GUI dünyasında açık bir şekilde tanımlanmadığına dikkat etmeliyim. Bir görünüm görünür olarak kabul edilebilir, ancak başka bir görünümle örtüşebilir, bir örnek için gizlenir.

Başka bir yol ama daha doğru (denemedim) Görünümün dikdörtgen sınırlarını kontrol etmektir. O kadar basit değil.

Bu yeterince açık mı? kod göndermediğiniz için size belirli örnekler veremezsiniz.


1
2018-03-25 10:17



Sorunu daha net hale getirmek için düzenledim. - user846316
Kod güncellemeniz için teşekkürler. Espresso'nın bir test kütüphanesi olduğunu bilmiyordum. Her neyse başka bir cevap yazdım. En azından Java ve Android'i biliyorum. - The Original Android


final AtomicBoolean view1Displayed = new AtomicBoolean(true);
Espresso.onView(ViewMatchers.withId(viewId1)).inRoot(RootMatchers.withDecorView(Matchers.is(intentsTestRule.getActivity().getWindow().getDecorView()))).withFailureHandler(new FailureHandler() {
        @Override
        public void handle(Throwable error, Matcher<View> viewMatcher) {
            view1Displayed.set(false);
        }
    }).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

if (view1Displayed.get()) {
        try {
            Espresso.onView(ViewMatchers.withId(viewId2)).inRoot(RootMatchers.withDecorView(Matchers.is(intentsTestRule.getActivity().getWindow().getDecorView()))).check(ViewAssertions.matches(Matchers.not(ViewMatchers.isDisplayed())));
        } catch (NoMatchingViewException ignore) {
        }
    } else {
        Espresso.onView(ViewMatchers.withId(viewId2)).inRoot(RootMatchers.withDecorView(Matchers.is(intentsTestRule.getActivity().getWindow().getDecorView()))).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
    }

0
2018-01-25 10:25