Espresso twierdzi, że nie ma takiej potrzeby Thread.sleep();
, ale mój kod nie działa, dopóki go nie dołączę. Łączę się z adresem IP. Podczas łączenia jest wyświetlane okno dialogowe postępu. Muszę sleep
poczekać, aż okno dialogowe zostanie zamknięte. Oto mój fragment testowy, w którym go używam:
IP.enterIP(); // fills out an IP dialog (this is done with espresso)
//progress dialog is now shown
Thread.sleep(1500);
onView(withId(R.id.button).perform(click());
Próbowałem tego kodu z i bezThread.sleep();
ale mówi R.id.Button
, nie istnieje. Jedynym sposobem, żeby to zadziałało, jest sen.
Próbowałem też zastąpić Thread.sleep();
takimi rzeczami, jak getInstrumentation().waitForIdleSync();
i nadal nie mam szczęścia.
Czy to jedyny sposób, aby to zrobić? A może coś mi brakuje?
Z góry dziękuję.
android
testing
android-espresso
Chad Bingham
źródło
źródło
Odpowiedzi:
Moim zdaniem prawidłowe podejście będzie następujące:
A następnie wzór użycia będzie:
źródło
Dzięki AlexK za jego niesamowitą odpowiedź. Są przypadki, w których trzeba opóźnić kod. Niekoniecznie czeka na odpowiedź serwera, ale może czekać na zakończenie animacji. Osobiście mam problem z idolingResources w Espresso (myślę, że piszemy wiele linii kodu dla prostej rzeczy), więc zmieniłem sposób, w jaki AlexK robił, na następujący kod:
Możesz więc utworzyć
Delay
klasę i umieścić w niej tę metodę, aby mieć do niej łatwy dostęp. Możesz go użyć w swojej klasie testowej w ten sam sposób:onView(isRoot()).perform(waitFor(5000));
źródło
Thread.sleep()
Natknąłem się na ten wątek, szukając odpowiedzi na podobny problem, gdzie czekałem na odpowiedź serwera i zmianę widoczności elementów na podstawie odpowiedzi.
Chociaż powyższe rozwiązanie zdecydowanie pomogło, w końcu znalazłem ten doskonały przykład z chiuki i teraz używam tego podejścia jako mojego rozwiązania, gdy czekam na wykonanie akcji w okresach bezczynności aplikacji.
Dodałem ElapsedTimeIdlingResource () do mojej własnej klasy narzędzi, mogę teraz skutecznie używać tego jako odpowiedniej alternatywy dla Espresso, a teraz użycie jest ładne i czyste:
źródło
I/TestRunner: java.lang.NoClassDefFoundError: fr.x.app.y.testtools.ElapsedTimeIdlingResource
błąd. Dowolny pomysł. Używam Proguarda, ale z wyłączonym zaciemnianiem.-keep
instrukcję dla klas, które nie zostały znalezione, aby upewnić się, że ProGuard nie usuwa ich jako niepotrzebnych. Więcej informacji tutaj: developer.android.com/tools/help/proguard.html#keep-codeMyślę, że łatwiej jest dodać tę linię:
Czeka określoną liczbę milisekund (uptimeMillis) przed zwróceniem. Podobny do sleep (long), ale nie zgłasza InterruptedException; zdarzenia przerwania () są odroczone do następnej przerywanej operacji. Nie zwraca, dopóki nie upłynie co najmniej określona liczba milisekund.
źródło
Możesz po prostu użyć metod Barista:
BaristaSleepActions.sleep(2000);
BaristaSleepActions.sleep(2, SECONDS);
Barista to biblioteka, która opakowuje Espresso, aby uniknąć dodawania całego kodu wymaganego przez zaakceptowaną odpowiedź. A oto link! https://github.com/SchibstedSpain/Barista
źródło
Thread.sleep()
. Przepraszam! Było to w niektórych z pierwszych filmów, które Google zrobił o Espresso, ale nie pamiętam, który z nich ... to było kilka lat temu. Przepraszam! : ·) Och! Edytować! Link do wideo umieściłem w PR, które otworzyłem trzy lata temu. Sprawdź to! github.com/AdevintaSpain/Barista/pull/19Jest to podobne do tej odpowiedzi, ale używa limitu czasu zamiast prób i może być połączone z innymi ViewInteractions:
Stosowanie:
źródło
Jestem nowy w programowaniu i espresso, więc chociaż wiem, że dobrym i rozsądnym rozwiązaniem jest użycie biegu jałowego, nie jestem jeszcze wystarczająco inteligentny, aby to zrobić.
Dopóki nie zdobędę większej wiedzy, wciąż potrzebuję moich testów, aby jakoś je uruchomić, więc na razie używam tego brudnego rozwiązania, które podejmuje szereg prób znalezienia elementu, zatrzymuje się, jeśli go znajdzie, a jeśli nie, zasypia i uruchamia się ponownie, aż osiągnie maksymalną liczbę prób (jak dotąd największa liczba prób wynosiła około 150).
Używam tego we wszystkich metodach wyszukiwania elementów według identyfikatora, tekstu, elementu nadrzędnego itp .:
źródło
findById(int itemId)
metoda zwróci element (który może mieć wartość NULL) niezależnie od tego, czywaitForElementUntilDisplayed(element);
zwróci prawdę, czy fałsz ... więc to nie jest w porządkuIdlingResource
s nie są dla mnie wystarczające ze względu na 5-sekundową szczegółowość szybkości odpytywania (o wiele za duża jak na mój przypadek użycia). Zaakceptowana odpowiedź również dla mnie nie działa (wyjaśnienie, dlaczego jest już zawarte w długim kanale komentarzy dla tej odpowiedzi). Dzięki za to! Wziąłem twój pomysł i stworzyłem własne rozwiązanie i działa jak urok.Espresso zostało stworzone, aby uniknąć wywołań funkcji sleep () w testach. Twój test nie powinien otwierać okna dialogowego do wprowadzenia adresu IP, za który powinna odpowiadać testowana aktywność.
Z drugiej strony test interfejsu użytkownika powinien:
Test powinien wyglądać mniej więcej tak:
Espresso czeka, aż wszystko, co dzieje się zarówno w wątku interfejsu użytkownika, jak iw puli AsyncTask, zakończy się przed wykonaniem testów.
Pamiętaj, że testy nie powinny robić niczego, co wiąże się z odpowiedzialnością aplikacji. Powinien zachowywać się jak „dobrze poinformowany użytkownik”: użytkownik, który klika, sprawdza, czy coś jest pokazane na ekranie, ale tak naprawdę zna identyfikatory komponentów
źródło
Powinieneś użyć zasobu Espresso Idling Resource, jest to zalecane w tym CodeLab
Przykład wywołania asynchronicznego od prezentera
Zależności
W przypadku systemu Androidx
Oficjalne repozytorium: https://github.com/googlecodelabs/android-testing
Przykład IdlingResource: https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IdlingResourceSample
źródło
Chociaż myślę, że najlepiej jest do tego użyć zasobów Idling ( https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/ ), prawdopodobnie możesz użyć tego jako rozwiązania zastępczego:
a następnie nazwij go w swoim kodzie np .:
zamiast
Pozwala to również na dodawanie limitów czasu dla działań wyświetlania i potwierdzeń.
źródło
return new TimedViewInteraction(Espresso.onView(viewMatcher));
zreturn new TimedViewInteraction(Espresso.onView(viewMatcher).check(matches(isDisplayed())));
Moje narzędzie powtarza wykonywanie, które można uruchomić lub wywołać, dopóki nie przejdzie bez błędów lub nie zostanie wyrzucone po przekroczeniu limitu czasu. Doskonale sprawdza się w testach Espresso!
Załóżmy, że ostatnia interakcja z widokiem (kliknięcie przycisku) aktywuje niektóre wątki w tle (sieć, baza danych itp.). W rezultacie powinien pojawić się nowy ekran i chcemy to sprawdzić w następnym kroku, ale nie wiemy, kiedy nowy ekran będzie gotowy do testów.
Zalecanym podejściem jest wymuszenie na aplikacji wysyłania komunikatów o stanach wątków do testu. Czasami możemy użyć wbudowanych mechanizmów, takich jak OkHttp3IdlingResource. W innych przypadkach należy wstawić fragmenty kodu w różnych miejscach źródeł aplikacji (powinieneś znać logikę aplikacji!) Tylko do testowania wsparcia. Ponadto powinniśmy wyłączyć wszystkie Twoje animacje (chociaż jest to część interfejsu użytkownika).
Inne podejście czeka, np. SystemClock.sleep (10000). Ale nie wiemy, jak długo czekać, a nawet duże opóźnienia nie gwarantują sukcesu. Z drugiej strony twój test będzie trwał długo.
Moje podejście polega na dodaniu warunku czasu, aby wyświetlić interakcję. Np. Testujemy, że nowy ekran powinien pojawić się podczas 10000 mc (przekroczenie limitu czasu). Ale nie czekamy i sprawdzamy to tak szybko, jak chcemy (np. Co 100 ms) Oczywiście w ten sposób blokujemy wątek testowy, ale zwykle jest to właśnie to, czego potrzebujemy w takich przypadkach.
To jest źródło mojej klasy:
https://gist.github.com/alexshr/ca90212e49e74eb201fbc976255b47e0
źródło
To jest pomocnik, którego używam w Kotlin do testów na Androida. W moim przypadku używam longOperation do naśladowania odpowiedzi serwera, ale możesz dostosować to do swojego celu.
źródło
Dodam do tego mój sposób na zrobienie tego:
Nazywa się tak:
Do funkcji suspendUntilSuccess można dodać parametry, takie jak maksymalna liczba iteracji, długość iteracji itp.
Nadal wolę używać nieaktywnych zasobów, ale gdy testy działają z powodu np. Powolnych animacji na urządzeniu, używam tej funkcji i działa dobrze. Może oczywiście zawiesić się do 5 sekund, tak jak przed niepowodzeniem, więc może wydłużyć czas wykonywania testów, jeśli akcja, która zakończy się sukcesem, nigdy się nie powiedzie.
źródło