Espresso Testing Framework - AdapterView

AdapterView è un tipo speciale di visualizzazione progettato specificamente per eseguire il rendering di una raccolta di informazioni simili come l'elenco dei prodotti e i contatti utente recuperati da un'origine dati sottostante utilizzando Adapter . L'origine dati può essere un semplice elenco di voci di database complesse. Alcune delle viste derivate da AdapterView sono ListView , GridView e Spinner .

AdapterView esegue il rendering dell'interfaccia utente in modo dinamico a seconda della quantità di dati disponibili nell'origine dati sottostante. Inoltre, AdapterView esegue il rendering solo dei dati minimi necessari, che possono essere visualizzati nell'area visibile disponibile dello schermo. AdapterView esegue questa operazione per risparmiare memoria e per rendere l'interfaccia utente liscia anche se i dati sottostanti sono di grandi dimensioni.

Dopo l'analisi, la natura dell'architettura di AdapterView rende irrilevante l' opzione onView e i relativi matcher di visualizzazione, poiché la vista particolare da testare potrebbe non essere affatto riprodotta in primo luogo. Fortunatamente, espresso fornisce un metodo, onData ( ), che accetta matcher hamcrest (rilevanti per il tipo di dati dei dati sottostanti) per abbinare i dati sottostanti e restituisce un oggetto di tipo DataInteraction corrispondente alla vista o ai dati abbinati. Un codice di esempio è il seguente,

onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())

In questo caso, onData () corrisponde alla voce "Apple", se è disponibile nei dati sottostanti (elenco di array) e restituisce l' oggetto DataInteraction per interagire con la vista corrispondente (TextView corrispondente alla voce "Apple").

Metodi

DataInteraction fornisce i seguenti metodi per interagire con la vista,

eseguire()

Accetta le azioni di visualizzazione e attiva le azioni di visualizzazione passate.

onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())

dai un'occhiata()

Accetta le asserzioni di visualizzazione e controlla le asserzioni di visualizzazione passate.

onData(allOf(is(instanceOf(String.class)), startsWith("Apple")))
   .check(matches(withText("Apple")))

inAdapterView ()

Accetta i matcher di visualizzazione. Seleziona il particolare AdapterView in base ai matcher di visualizzazione passati e restituisce l' oggetto DataInteraction per interagire con AdapterView corrispondente

onData(allOf())
   .inAdapterView(withId(R.id.adapter_view))
   .atPosition(5)
   .perform(click())

atPosition ()

Accetta un argomento di tipo integer e fa riferimento alla posizione dell'elemento nei dati sottostanti. Seleziona la vista corrispondente al valore posizionale passato dei dati e restituisce l' oggetto DataInteraction per interagire con la vista corrispondente. Sarà utile, se conosciamo l'ordine corretto dei dati sottostanti.

onData(allOf())
   .inAdapterView(withId(R.id.adapter_view))
   .atPosition(5)
   .perform(click())

onChildView ()

Accetta i matcher di visualizzazione e corrisponde alla visualizzazione all'interno della visualizzazione figlio specifica. Ad esempio, possiamo interagire con elementi specifici come il pulsante Acquista in un AdapterView basato su un elenco di prodotti .

onData(allOf(is(instanceOf(String.class)), startsWith("Apple")))
   .onChildView(withId(R.id.buy_button))
   .perform(click())

Scrivi un'applicazione di esempio

Seguire i passaggi mostrati di seguito per scrivere una semplice applicazione basata su AdapterView e scrivere un test case utilizzando il metodo onData () .

  • Avvia Android Studio.

  • Crea un nuovo progetto come discusso in precedenza e chiamalo , MyFruitApp .

  • Migrare l'applicazione al framework AndroidX utilizzando RefactorMigrate to AndroidX option menu.

  • Rimuovi il design predefinito nell'attività principale e aggiungi ListView . Il contenuto di activity_main.xml è il seguente,

<?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>
  • Aggiungi nuova risorsa di layout, item.xml per specificare il modello di elemento della visualizzazione elenco. Il contenuto di item.xml è il seguente,

<?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"
/>
  • Ora, crea un adattatore con un array di frutta come dati sottostanti e impostalo sulla visualizzazione elenco. Questo deve essere fatto in onCreate () di MainActivity come specificato di seguito,

@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);
}
  • Ora, compila il codice ed esegui l'applicazione. Lo screenshot dell'app My Fruit è il seguente,

  • Ora, apri il file ExampleInstrumentedTest.java e aggiungi ActivityTestRule come specificato di seguito,

@Rule
public ActivityTestRule<MainActivity> mActivityRule =
   new ActivityTestRule<MainActivity>(MainActivity.class);

Inoltre, assicurati che la configurazione del test sia eseguita in 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'
}
  • Aggiungi un nuovo scenario di test per testare la visualizzazione elenco come di seguito,

@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());
}
  • Infine, esegui il test case utilizzando il menu contestuale di Android Studio e controlla se tutti i test case hanno successo.