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 RefactorMigrate 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.