2016-02-03 19 views
11

przepływu pracy powinny być następujące:Testowanie pasek postępu na Androida z espresso

  1. Działalność rozpoczyna
  2. Pasek postępu jest widoczny
  3. żądania pożary sieciowe (resource biegu jałowym jest już zarejestrowany więc espresso umie czekać dla tego).
  4. Pasek postępu jest ukryty
  5. Wyświetlany jest tekst z sieci.

Do tego momentu, napisałem twierdzeń do stepów 1, 3, 5 i działa idealnie:

onView(withText("foo 1")) 
    .check(matches(isDisplayed())); 

Problem jest, nie mam pojęcia, jak do niech espresso wiedzieć, aby zweryfikować widoczność paska postępu przed wniosek został złożony i po złożeniu wniosku.

rozważyć metodę onCreate() jest następujący:

super.onCreate(...); 
setContentView(...); 

showProgressBar(true); 
apiClient.getStuff(new Callback() { 
    public void onSuccess() { 
     showProgressBar(false); 
    } 
}); 

Próbowałem następujących, ale to nie działa:

// Activity is launched at this point. 
activityRule.launchActivity(new Intent()); 

// Up to this point, the request has been fired and response was 
// returned, so the progress bar is now GONE. 
onView(withId(R.id.progress_bar)) 
    .check(matches(isDisplayed())); 

onView(withId(R.id.progress_bar)) 
    .check(matches(not(isDisplayed()))); 

Powodem jest to dzieje się tak dlatego, ponieważ klient jest zarejestrowany jako zasób bezczynny, espresso poczeka, aż znowu będzie gotowe idle, zanim uruchomię pierwszą wersję , więc potrzebuję sposobu, aby powiadomić espresso o uruchomieniu tego PRZED będzie bezczynny.

EDIT: to nie działa albo:

idlingResource.registerIdleTransitionCallback(new IdlingResource.ResourceCallback() { 
     @Override 
     public void onTransitionToIdle() { 
      onView(withId(R.id.progress_bar)) 
        .check(matches(isDisplayed())); 
     } 
    }); 
+0

dobrze będzie musiał sprawdzić Twoją aktywność. Jeśli chcesz pozostać przy uruchomionych testach integracyjnych, będziesz musiał pozorować/zablokować swoje wywołania api. –

+0

Aplikacja APi jest zgaszona i zarejestrowana jako zasób bezczynny. Nie o to pytam. –

Odpowiedz

4

Wygląda to tak naprawdę nie może być możliwe. Chociaż jest to starsza publikacja grupowa, w Android Test Kit Discussion istnieje dość zdecydowana odpowiedź, w której stwierdza się, że wątki interfejsu użytkownika nie spoczywają podczas animacji pasków postępu, a więc struktura Espresso nie może zostać uruchomiona.

Marcus Klepp zaleca przejście obok tego here za pomocą typów kompilacji. Wtyczka Gradle pozwoli ci zdefiniować różne build types. Możesz ustawić inny układ w swoim typie kompilacji androidTest, który zastąpi dany obiekt View czymś generycznym. Jeśli wszystko, co robisz, potwierdza, że ​​widget isDisplayed() w jednym zestawie warunków i not(isDisplayed()) w innym zestawie warunków, możesz z pewnością zaimplementować to za pomocą różnych plików układu. Nie żeby to nie było trochę windy.

Wreszcie, nie może być inny post tutaj, które niesie pewne dodatkowe informacje tutaj: "java.lang.RuntimeException: Could not launch intent" for UI with indeterminate ProgressBar

11

Espresso ma problemy z animacją. Możesz ustawić losowanie paska postępu na coś statycznego tylko dla testu i działa zgodnie z oczekiwaniami.

Drawable notAnimatedDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.whatever); 
((ProgressBar) getActivity().findViewById(R.id.progress_bar)).setIndeterminateDrawable(notAnimatedDrawable); 

onView(withId(R.id.progress_bar)).check(matches(isDisplayed())); 
+0

Dobry pies-gwóźdź :-) –

+0

Możesz wyłączyć animacje w Ustawieniach -> Opcje programisty -> Skala animacji Windows/Skala animacji przejścia/Skala animacji czasu – heloisasim

+0

@heloisasim niestety nie pomaga –

2

Jak widzę Espresso jest ściśle sprzężony z pomijanie dynamicznych działań UI w ogóle, to dlaczego nie można przetestować ProgressBar użyciu Espresso. Można jednak łatwo osiągnąć ten cel z innego narzędzia Android Google: UiAutomator następująco:

saveButton().click(); // perform action opening ProgressBar with UiAutomator, not Espresso 
    assertTrue(progressBar().exists()); 

Stosując te statyczne utils:

public static UiObject progressBar() { 
    return uiObjectWithText(R.string.my_progress); 
} 

public static UiObject saveButton() { 
    return uiObjectWithId(R.id.my_save_button); 
} 

public static UiObject uiObjectWithId(@IdRes int id) { 
    String resourceId = getTargetContext().getResources().getResourceName(id); 
    UiSelector selector = new UiSelector().resourceId(resourceId); 
    return UiDevice.getInstance(getInstrumentation()).findObject(selector); 
} 

public static UiObject uiObjectWithText(@StringRes int stringRes) { 
    UiSelector selector = new UiSelector().text(getTargetContext().getString(stringRes)); 
    return UiDevice.getInstance(getInstrumentation()).findObject(selector); 
} 

Upewnij się build.gradle obejmuje:

androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' 
+0

Dziękuję, to było jedyne rozwiązanie to się udało :-) –