Zasoby nieaktywnego espresso

Nieaktywny zasób reprezentuje operację asynchroniczną, której wyniki mają wpływ kolejnych operacji w teście interfejsu. Rejestrując nieaktywne zasoby za pomocą Espresso, możesz uzyskać bardziej niezawodną weryfikację tych operacji asynchronicznych, gdy testowania aplikacji.

Określ, kiedy potrzebne są nieaktywne zasoby

Kawa espresso oferuje elegancki zestaw synchronizacji danych. Ten odnosi się jednak wyłącznie do operacji wiadomości w MessageQueue, takie jak podklasa View, który rysuje swoją zawartość na ekranie.

Ponieważ Espresso nie wie o żadnych innych operacjach asynchronicznych, w tym jeśli działa w wątku w tle, Espresso nie może gwarancjami w takich sytuacjach. Aby zapoznać się z długo trwających operacji, musisz zarejestrować każdą z nich jako bezczynny zasób.

Jeśli przy testowaniu wyników aplikacji nie używasz bezczynnych zasobów asynchronicznej, może być konieczne użycie jednej z stosowanie „złych rozwiązań tymczasowych, aby poprawić wyniki” niezawodność:

  • Dodaję połączenia do: Thread.sleep(). Gdy sztuczne opóźnienia w testach, bo wydłużenie czasu testowania i może jej się zakończyć. Testy mogą nadal zakończyć się niepowodzeniem na wolniejszych urządzeniach. Poza tym opóźnienia te nie skalują się odpowiednio, ponieważ aplikacja może będą musieli przeprowadzać bardziej czasochłonne asynchroniczne prace w kolejnej wersji.
  • Implementowanie kodów ponownych prób, które używają pętli do wielokrotnego sprawdzania, czy aplikacja wykonuje działania asynchroniczne, dopóki nie nastąpi przekroczenie limitu czasu. Nawet jeśli określić maksymalną liczbę ponownych prób w testach, każde ponowne wykonanie zużywa zasobów systemowych, a zwłaszcza procesora.
  • Używanie instancji CountDownLatch,która zezwól jednemu lub kilku wątkom na oczekiwanie na określoną liczbę operacji wykonanych w innym wątku. Te obiekty wymagają określenia limit czasu; W przeciwnym razie aplikacja może zostać zablokowana na stałe. Zatrzaski które niepotrzebnie komplikują kod i utrudniają jego obsługę.

Espresso pozwala wyeliminować te mniej niezawodne rozwiązania z testów i zamiast tego zarejestrować asynchroniczną pracę aplikacji jako bezczynne zasoby.

Częste zastosowania

Podczas wykonywania w testach operacji podobnych do poniższych rozważ użycie bezczynnego zasobu:

  • Wczytywanie danych z internetu lub lokalnego źródła danych.
  • nawiązywanie połączeń z bazami danych i wywołaniami zwrotnymi;
  • Zarządzanie usługami za pomocą usługi systemowej lub instancji IntentService
  • Wykonywanie złożonej logiki biznesowej, np. przekształceń mapy bitowej.

Rejestracja nieaktywnych zasobów jest szczególnie ważna, gdy te operacje zaktualizować interfejs, który zostanie zweryfikowany przez testy.

Przykładowe implementacje bezczynnych zasobów

Na liście poniżej znajdziesz kilka przykładowych implementacji nieaktywnych zasobów które możesz zintegrować z aplikacją:

CountingIdlingResource
Masz licznik aktywnych zadań. Gdy licznik ma wartość zero, powiązany element zasób jest uznawany za bezczynny. Ta funkcja bardzo przypomina funkcję Semaphore W większości przypadków jest to wystarcza do zarządzania asynchroniczną pracą aplikacji podczas jej testowania.
UriIdlingResource
Podobne do CountingIdlingResource, ale dla określonego okresu przed zasób jest uznawany za bezczynny. Ten dodatkowy okres oczekiwania trwa kolejno żądań sieciowych, gdzie aplikacja z wątku może utworzyć nowy natychmiast po otrzymaniu odpowiedzi na poprzednie zgłoszenie.
IdlingThreadPoolExecutor
Niestandardowa implementacja ThreadPoolExecutor który śledzi łączną liczbę uruchomionych zadań w utworzonym wątku. basenów. Te zajęcia korzystają z funkcji CountingIdlingResource do aby utrzymać licznik aktywnych zadań.
IdlingScheduledThreadPoolExecutor
Niestandardowa implementacja ScheduledThreadPoolExecutor Zapewnia to samo funkcji i możliwości, IdlingThreadPoolExecutor na zajęciach, ale może też śledzić zadania zaplanowane na przyszłość lub które mają być okresowo wykonywane.
.

Utwórz własny bezczynny zasób

Ponieważ w testach aplikacji używasz bezczynnych zasobów, konieczne może być podanie niestandardowe zarządzanie zasobami lub logowanie. W takich przypadkach podane w poprzedniej sekcji mogą nie wystarczyć. W takim przypadku możesz rozszerz jedną z tych implementacji bezczynnych zasobów lub utwórz własną.

Jeśli wdrażasz własną funkcję bezczynności zasobów, zachowaj następujące najlepsze zwłaszcza pierwszej:

Wywołuj przejścia w stan bezczynności poza sprawdzaniem bezczynności.
Gdy aplikacja stanie się nieaktywna, zadzwoń do onTransitionToIdle(). poza wszelkimi implementacjami isIdleNow() Dzięki temu Espresso nie robi sekundy, niepotrzebnie sprawdza, czy bezczynny zasób jest bezczynny.

Poniższy fragment kodu ilustruje tę rekomendację:

Kotlin

fun isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

fun backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}

Java

public void isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

public void backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}
Zarejestruj nieaktywne zasoby, zanim będą potrzebne.

Korzyści z synchronizacji związane z brakiem zasobów mają zastosowanie tylko po pierwszym wywołaniu tego zasobu przez Espresso isIdleNow().

Poniższa lista zawiera kilka przykładów tej właściwości:

  • Jeśli zarejestrujesz bezczynny zasób w metodzie opatrzonej adnotacją @Before, bezczynny zasób zacznie obowiązywać w pierwszym wierszu każdego testu.
  • Jeśli zarejestrujesz bezczynny zasób w teście, bezczynny zasób zostanie zastosowany podczas następnego działania opartego na Espresso. To zachowanie nadal zachodzi nawet wtedy, gdy następne działanie znajduje się w tym samym teście co stwierdzenie, że rejestruje bezczynny zasób.
Wyrejestruj nieaktywne zasoby, gdy przestaniesz ich używać.

Aby oszczędzać zasoby systemowe, jak najszybciej wyrejestruj nieaktywne zasoby bo nie są już potrzebne. Jeśli na przykład zarejestrujesz bezczynny zasób w metodzie z adnotacjami @Before, najlepiej wyrejestrować ten zasób w odpowiedniej metody oznaczonej adnotacją @After.

Użyj nieaktywnego rejestru, aby zarejestrować i wyrejestrować nieaktywne zasoby.

Korzystając z tego kontenera dla nieaktywnych zasobów aplikacji, możesz zarejestrować wyrejestrowuj bezczynne zasoby wielokrotnie w razie potrzeby i nadal obserwuj spójne zachowanie użytkownika.

Utrzymuj prosty stan aplikacji w obrębie bezczynnych zasobów.

Na przykład zaimplementowane i rejestrowane bezczynne zasoby nie powinny zawierają odwołania do obiektów View.

Rejestrowanie bezczynnych zasobów

Espresso udostępnia klasę kontenera, w której można umieścić brak aktywności aplikacji i zasobami Google Cloud. Te zajęcia, zwane IdlingRegistry to samodzielnym artefaktem, który minimalizuje obciążenie aplikacji. Klasa pozwala też na wykonanie tych czynności w celu poprawy łatwość utrzymania:

  • Utwórz odwołanie do zasobu IdlingRegistry zamiast bezczynnych zasobów w testach aplikacji.
  • Zachowaj różnice w zbieraniu nieaktywnych zasobów, których używasz do każdego wariantu kompilacji.
  • Zdefiniuj bezczynne zasoby w usługach aplikacji, a nie w interfejsie które odwołują się do tych usług.
.

Zintegruj z aplikacją bezczynne zasoby

Chociaż bezczynne zasoby można dodać do aplikacji na kilka różnych sposobów: i zadba o otoczenie aplikacji, a jednocześnie pozwala możesz określić konkretną operację reprezentowaną przez dany bezczynny zasób.

Zdecydowanie zalecamy przy dodawaniu nieaktywnych zasobów do aplikacji logikę bezczynności zasobów w samej aplikacji i wykonywanie wyłącznie rejestracji podczas wyrejestrowania.

Chociaż występuje nietypowa sytuacja, w której użytkownicy korzystają z interfejsu tylko do testów, kodu produkcyjnego, stosując się do tej metody, możesz opakować bezczynne zasoby wokół który już masz, z zachowaniem rozmiaru pliku APK i liczby metod.

Alternatywne sposoby

Jeśli nie chcesz korzystać z logiki bezczynności zasobów w środowisku produkcyjnym aplikacji jest kilka innych skutecznych strategii integracji:

  • Możesz tworzyć warianty kompilacji, takie jak wersja Gradle’a produkt smaki i używaj bezczynnych zasobów tylko w kompilacji do debugowania aplikacji.
  • Użyj platformy wstrzykiwania zależności, takiej jak Dagger, aby wstrzyknąć bezczynność aplikacji graf zależności zasobów. Jeśli używasz Daggera 2, samo wstrzykiwanie powinno pochodzić z podkomponentu.
  • Zaimplementuj bezczynny zasób w testach aplikacji i udostępnij część implementacji aplikacji, którą trzeba zsynchronizować w testów.

    Uwaga: chociaż ta decyzja dotycząca projektu wydaje się tworzy niezależne odniesienie do bezczynnych zasobów, ale także można stosować w nie tylko najprostszych aplikacjach.

Dodatkowe materiały

Więcej informacji o używaniu Espresso w testach na Androidzie znajdziesz w poniższe zasoby.

Próbki