Struktura testowania espresso - AdapterView
AdapterView to specjalny rodzaj widoku, zaprojektowany specjalnie do renderowania kolekcji podobnych informacji, takich jak lista produktów i kontakty użytkownika pobrane z bazowego źródła danych za pomocą Adaptera . Źródłem danych może być prosta lista złożonych wpisów bazy danych. Niektóre widoki pochodzące z AdapterView to ListView , GridView i Spinner .
AdapterView dynamicznie renderuje interfejs użytkownika w zależności od ilości danych dostępnych w bazowym źródle danych. Ponadto AdapterView renderuje tylko minimum niezbędnych danych, które można renderować w dostępnym widocznym obszarze ekranu. AdapterView robi to, aby oszczędzać pamięć i sprawić, by interfejs użytkownika wyglądał płynnie, nawet jeśli podstawowe dane są duże.
Po analizie natura architektury AdapterView sprawia, że opcja onView i jej elementy dopasowujące widok są nieistotne, ponieważ konkretny widok do testowania może w ogóle nie być renderowany. Na szczęście espresso udostępnia metodę onData ( ), która akceptuje dopasowania hamcrest (odpowiednie dla typu danych bazowych) w celu dopasowania danych bazowych i zwraca obiekt typu DataInteraction odpowiadający widokowi dopasowanych danych. Przykładowy kod jest następujący:
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())
Tutaj onData () dopasowuje wpis „Apple”, jeśli jest dostępny w danych źródłowych (lista tablic) i zwraca obiekt DataInteraction do interakcji z dopasowanym widokiem (TextView odpowiadający wpisowi „Apple”).
Metody
DataInteraction udostępnia poniższe metody interakcji z widokiem,
wykonać()
Akceptuje działania widoku i uruchamia przekazane akcje widoku.
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())
czek()
To akceptuje potwierdzenia widoku i sprawdza przekazane potwierdzenia w widoku.
onData(allOf(is(instanceOf(String.class)), startsWith("Apple")))
.check(matches(withText("Apple")))
inAdapterView ()
To akceptuje dopasowania widoku. Wybiera konkretny AdapterView na podstawie przekazanych w widoku dopasowującym i zwraca obiekt DataInteraction do interakcji z dopasowanym AdapterView
onData(allOf())
.inAdapterView(withId(R.id.adapter_view))
.atPosition(5)
.perform(click())
atPosition ()
Akceptuje argument typu integer i odsyła pozycję elementu w danych bazowych. Wybiera widok odpowiadający przekazanej wartości pozycyjnej danych i zwraca obiekt DataInteraction do interakcji z dopasowanym widokiem. Przyda się, jeśli znamy prawidłową kolejność danych bazowych.
onData(allOf())
.inAdapterView(withId(R.id.adapter_view))
.atPosition(5)
.perform(click())
onChildView ()
Akceptuje dopasowania widoku i dopasowuje widok wewnątrz określonego widoku podrzędnego. Na przykład możemy wchodzić w interakcje z określonymi elementami, takimi jak przycisk Kup w AdapterView opartym na liście produktów .
onData(allOf(is(instanceOf(String.class)), startsWith("Apple")))
.onChildView(withId(R.id.buy_button))
.perform(click())
Napisz przykładową aplikację
Wykonaj poniższe kroki, aby napisać prostą aplikację opartą na AdapterView i napisać przypadek testowy przy użyciu metody onData () .
Uruchom studio Android.
Utwórz nowy projekt zgodnie z wcześniejszym opisem i nazwij go MyFruitApp .
Przenieś aplikację do frameworka AndroidX za pomocą menu opcji Refactor → Migrate to AndroidX .
Usuń domyślny projekt w głównym działaniu i Dodaj ListView . Zawartość pliku activity_main.xml jest następująca:
<?xml version = "1.0" encoding = "utf-8"?>
<RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity">
<ListView
android:id = "@+id/listView"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content" />
</RelativeLayout>
Dodaj nowy zasób układu, item.xml, aby określić szablon elementu widoku listy. Zawartość pliku item.xml jest następująca:
<?xml version = "1.0" encoding = "utf-8"?>
<TextView xmlns:android = "http://schemas.android.com/apk/res/android"
android:id = "@+id/name"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:padding = "8dp"
/>
Teraz utwórz adapter z tablicą owoców jako danymi bazowymi i ustaw dla niego widok listy. To musi być zrobione w onCreate () z główną działalność , jak określono poniżej,
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find fruit list view
final ListView listView = (ListView) findViewById(R.id.listView);
// Initialize fruit data
String[] fruits = new String[]{
"Apple",
"Banana",
"Cherry",
"Dates",
"Elderberry",
"Fig",
"Grapes",
"Grapefruit",
"Guava",
"Jack fruit",
"Lemon",
"Mango",
"Orange",
"Papaya",
"Pears",
"Peaches",
"Pineapple",
"Plums",
"Raspberry",
"Strawberry",
"Watermelon"
};
// Create array list of fruits
final ArrayList<String> fruitList = new ArrayList<String>();
for (int i = 0; i < fruits.length; ++i) {
fruitList.add(fruits[i]);
}
// Create Array adapter
final ArrayAdapter adapter = new ArrayAdapter(this, R.layout.item, fruitList);
// Set adapter in list view
listView.setAdapter(adapter);
}
Teraz skompiluj kod i uruchom aplikację. Zrzut ekranu aplikacji My Fruit przedstawia się następująco:
Teraz otwórz plik ExampleInstrumentedTest.java i dodaj ActivityTestRule, jak określono poniżej,
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule<MainActivity>(MainActivity.class);
Upewnij się również, że konfiguracja testowa jest wykonana w pliku app / build.gradle -
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test:rules:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
Dodaj nowy przypadek testowy, aby przetestować widok listy, jak poniżej,
@Test
public void listView_isCorrect() {
// check list view is visible
onView(withId(R.id.listView)).check(matches(isDisplayed()));
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click());
onData(allOf(is(instanceOf(String.class)), startsWith("Apple")))
.check(matches(withText("Apple")));
// click a child item
onData(allOf())
.inAdapterView(withId(R.id.listView))
.atPosition(10)
.perform(click());
}
Na koniec uruchom przypadek testowy za pomocą menu kontekstowego Android Studio i sprawdź, czy wszystkie przypadki testowe się powiodły.