Espresso Testing Framework - AdapterView
AdapterView ist eine spezielle Art von Ansicht, die speziell zum Rendern einer Sammlung ähnlicher Informationen wie Produktlisten und Benutzerkontakte entwickelt wurde, die mit Adapter aus einer zugrunde liegenden Datenquelle abgerufen wurden . Die Datenquelle kann eine einfache Liste zu komplexen Datenbankeinträgen sein. Einige der von AdapterView abgeleiteten Ansichten sind ListView , GridView und Spinner .
AdapterView rendert die Benutzeroberfläche dynamisch in Abhängigkeit von der in der zugrunde liegenden Datenquelle verfügbaren Datenmenge. Darüber hinaus rendert AdapterView nur die minimal erforderlichen Daten, die im verfügbaren sichtbaren Bereich des Bildschirms gerendert werden können. AdapterView tut dies, um Speicherplatz zu sparen und die Benutzeroberfläche auch dann reibungslos aussehen zu lassen, wenn die zugrunde liegenden Daten groß sind.
Bei der Analyse sind die onView- Option und ihre Ansichtsabgleiche aufgrund der Art der AdapterView- Architektur irrelevant, da die zu testende Ansicht möglicherweise überhaupt nicht gerendert wird. Glücklicherweise bietet Espresso eine Methode, onData ( ), die Hamcrest-Matcher (relevant für den Datentyp der zugrunde liegenden Daten) akzeptiert, um mit den zugrunde liegenden Daten übereinzustimmen, und ein Objekt vom Typ DataInteraction zurückgibt , das der Ansicht der übereinstimmenden Daten entspricht. Ein Beispielcode lautet wie folgt:
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())
Hier stimmt onData () mit dem Eintrag "Apple" überein , wenn er in den zugrunde liegenden Daten (Array-Liste) verfügbar ist, und gibt das DataInteraction- Objekt zurück, um mit der übereinstimmenden Ansicht zu interagieren (TextView entspricht dem Eintrag "Apple").
Methoden
DataInteraction bietet die folgenden Methoden zur Interaktion mit der Ansicht:
ausführen()
Dies akzeptiert Ansichtsaktionen und löst die übergebenen Ansichtsaktionen aus.
onData(allOf(is(instanceOf(String.class)), startsWith("Apple"))).perform(click())
prüfen()
Dies akzeptiert Ansichtszusicherungen und überprüft die übergebenen Ansichtszusicherungen.
onData(allOf(is(instanceOf(String.class)), startsWith("Apple")))
.check(matches(withText("Apple")))
inAdapterView ()
Dies akzeptiert View Matcher. Es wählt die bestimmte AdapterView basierend auf den übergebenen View-Matchern aus und gibt das DataInteraction- Objekt zurück, um mit der übereinstimmenden AdapterView zu interagieren
onData(allOf())
.inAdapterView(withId(R.id.adapter_view))
.atPosition(5)
.perform(click())
atPosition ()
Dies akzeptiert ein Argument vom Typ Integer und verweist auf die Position des Elements in den zugrunde liegenden Daten. Es wählt die Ansicht aus, die dem übergebenen Positionswert der Daten entspricht, und gibt das DataInteraction- Objekt zurück, um mit der übereinstimmenden Ansicht zu interagieren. Es ist nützlich, wenn wir die richtige Reihenfolge der zugrunde liegenden Daten kennen.
onData(allOf())
.inAdapterView(withId(R.id.adapter_view))
.atPosition(5)
.perform(click())
onChildView ()
Dies akzeptiert Ansichtsabgleiche und stimmt mit der Ansicht in der spezifischen untergeordneten Ansicht überein. Beispielsweise können wir mit bestimmten Elementen wie der Schaltfläche " Kaufen" in einer auf Produktlisten basierenden AdapterView interagieren .
onData(allOf(is(instanceOf(String.class)), startsWith("Apple")))
.onChildView(withId(R.id.buy_button))
.perform(click())
Schreiben Sie eine Beispielanwendung
Führen Sie die folgenden Schritte aus, um eine einfache Anwendung auf Basis von AdapterView zu schreiben und einen Testfall mit der Methode onData () zu schreiben .
Starten Sie Android Studio.
Erstellen Sie ein neues Projekt wie zuvor beschrieben und nennen Sie es MyFruitApp .
Migrieren Sie die Anwendung auf AndroidX Framework Umgestalten → Migrate zu AndroidX Optionsmenü.
Entfernen Sie das Standarddesign in der Hauptaktivität und fügen Sie ListView hinzu . Der Inhalt der Datei activity_main.xml lautet wie folgt:
<?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>
Fügen Sie die neue Layoutressource item.xml hinzu , um die Elementvorlage der Listenansicht anzugeben. Der Inhalt der item.xml lautet wie folgt:
<?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"
/>
Erstellen Sie nun einen Adapter mit einem Fruchtarray als zugrunde liegenden Daten und setzen Sie ihn auf die Listenansicht. Dies muss in onCreate () von MainActivity erfolgen, wie unten angegeben.
@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);
}
Kompilieren Sie nun den Code und führen Sie die Anwendung aus. Der Screenshot der My Fruit App sieht wie folgt aus:
Öffnen Sie nun die Datei ExampleInstrumentedTest.java und fügen Sie ActivityTestRule wie unten angegeben hinzu.
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule<MainActivity>(MainActivity.class);
Stellen Sie außerdem sicher, dass die Testkonfiguration in app / build.gradle - durchgeführt wird.
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'
}
Fügen Sie einen neuen Testfall hinzu, um die Listenansicht wie folgt zu testen:
@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());
}
Führen Sie den Testfall schließlich über das Kontextmenü von Android Studio aus und überprüfen Sie, ob alle Testfälle erfolgreich sind.