Espresso Testing Framework - AdapterView

AdapterView é um tipo especial de visualização projetado especificamente para renderizar uma coleção de informações semelhantes, como lista de produtos e contatos do usuário obtidos de uma fonte de dados subjacente usando o Adapter . A fonte de dados pode ser uma lista simples para entradas de banco de dados complexas. Algumas das visualizações derivadas de AdapterView são ListView , GridView e Spinner .

AdapterView renderiza a interface com o usuário dinamicamente, dependendo da quantidade de dados disponíveis na origem de dados subjacente. Além disso, AdapterView renderiza apenas os dados mínimos necessários, que podem ser renderizados na área visível disponível da tela. AdapterView faz isso para economizar memória e fazer com que a interface do usuário pareça suave, mesmo se os dados subjacentes forem grandes.

Após a análise, a natureza da arquitetura AdapterView torna a opção onView e seus correspondentes de visualização irrelevantes porque a visualização específica a ser testada pode não ser renderizada em primeiro lugar. Felizmente, o espresso fornece um método, onData ( ), que aceita matchers hamcrest (relevantes para o tipo de dados dos dados subjacentes) para combinar os dados subjacentes e retorna o objeto do tipo DataInteraction correspondente à visualização dos dados combinados. Um exemplo de código é o seguinte,

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

Aqui, onData () corresponde à entrada “Apple”, se estiver disponível nos dados subjacentes (lista de matriz) e retorna o objeto DataInteraction para interagir com a visualização correspondida (TextView correspondente à entrada “Apple”).

Métodos

DataInteraction fornece os métodos abaixo para interagir com a visualização,

executar ()

Isso aceita ações de visualização e dispara as ações de visualização passadas.

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

Verifica()

Aceita asserções de visão e verifica as asserções de visão passadas.

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

inAdapterView ()

Isso aceita correspondências de visualização. Ele seleciona o AdapterView específico com base nos matchers de visualização passados ​​e retorna o objeto DataInteraction para interagir com o AdapterView correspondente

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

atPosition ()

Isso aceita um argumento do tipo inteiro e se refere à posição do item nos dados subjacentes. Ele seleciona a visualização correspondente ao valor posicional passado dos dados e retorna o objeto DataInteraction para interagir com a visualização correspondente. Será útil, se soubermos a ordem correta dos dados subjacentes.

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

onChildView ()

Isso aceita correspondências de visualização e corresponde à visualização dentro da visualização secundária específica. Por exemplo, podemos interagir com itens específicos como o botão Comprar em uma lista de produtos baseada em AdapterView .

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

Escreva um aplicativo de amostra

Siga as etapas mostradas abaixo para escrever um aplicativo simples baseado em AdapterView e escrever um caso de teste usando o método onData () .

  • Inicie o Android Studio.

  • Crie um novo projeto conforme discutido anteriormente e nomeie-o, MyFruitApp .

  • Migre o aplicativo para a estrutura AndroidX usando RefactorMigrar para o menu de opções AndroidX .

  • Remova o design padrão da atividade principal e adicione ListView . O conteúdo do activity_main.xml é o seguinte,

<?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>
  • Adicione um novo recurso de layout, item.xml para especificar o modelo de item da exibição de lista. O conteúdo do item.xml é o seguinte,

<?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"
/>
  • Agora, crie um adaptador com array de frutas como dados subjacentes e configure-o para a exibição de lista. Isso precisa ser feito em onCreate () de MainActivity conforme especificado abaixo,

@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);
}
  • Agora, compile o código e execute o aplicativo. A captura de tela do aplicativo My Fruit é a seguinte,

  • Agora, abra o arquivo ExampleInstrumentedTest.java e adicione ActivityTestRule conforme especificado abaixo,

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

Além disso, certifique-se de que a configuração do teste seja feita em 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'
}
  • Adicione um novo caso de teste para testar a exibição de lista conforme abaixo,

@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());
}
  • Por fim, execute o caso de teste usando o menu de contexto do Android Studio e verifique se todos os casos de teste estão funcionando.