Lokale Einheitentests erstellen

Ein lokaler Test wird direkt auf Ihrer eigenen Workstation und nicht auf einem Android-Gerät ausgeführt Gerät oder Emulator nutzen. Es verwendet also Ihre lokale Java Virtual Machine (JVM), als mit einem Android-Gerät. Mit lokalen Tests können Sie die Logik Ihrer App zu optimieren. Es ist jedoch nicht möglich, mit den Das Android-Framework schränkt die Testtypen ein, die Sie ausführen können.

Mit einem Einheitentest wird das Verhalten eines kleinen Codeabschnitts, der Einheit unter testen. Dazu wird der Code ausgeführt und das Ergebnis überprüft.

Einheitentests sind in der Regel einfach, aber ihre Einrichtung kann problematisch sein, wenn die Einheitentests ist nicht auf Testbarkeit ausgelegt:

  • Der Code, den Sie überprüfen möchten, muss über einen Test zugänglich sein. Für Sie eine private Methode nicht direkt testen können. Stattdessen testen Sie den Kurs mit seinen öffentlichen APIs.
  • Um Einheitentests isolieren auszuführen, müssen die Abhängigkeiten der Einheit müssen durch von Ihnen kontrollierte Komponenten wie Fakes oder andere Test-Doubles. Dies ist besonders problematisch, wenn Ihr Code Android-Framework entwickelt.

Informationen zu gängigen Strategien für Einheitentests unter Android finden Sie unter Was Sie testen.

Speicherort für lokale Tests

Standardmäßig werden die Quelldateien für lokale Einheitentests an folgendem Ort platziert: module-name/src/test/ Dieses Verzeichnis ist bereits vorhanden, wenn Sie ein neues erstellen mithilfe von Android Studio.

Testabhängigkeiten hinzufügen

Außerdem müssen Sie die Testabhängigkeiten für Ihr Projekt konfigurieren, um die Methode Standard-APIs, die vom JUnit-Test-Framework bereitgestellt werden

Öffnen Sie dazu die Datei build.gradle Ihrer App-Moduls und geben Sie Folgendes an: Bibliotheken als Abhängigkeiten. Mit der Funktion testImplementation geben Sie die sie auf den lokalen Testquellensatz und nicht auf die Anwendung anwenden:

dependencies {
  // Required -- JUnit 4 framework
  testImplementation "junit:junit:$jUnitVersion"
  // Optional -- Robolectric environment
  testImplementation "androidx.test:core:$androidXTestVersion"
  // Optional -- Mockito framework
  testImplementation "org.mockito:mockito-core:$mockitoVersion"
  // Optional -- mockito-kotlin
  testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
  // Optional -- Mockk framework
  testImplementation "io.mockk:mockk:$mockkVersion"
}

Testklasse für lokale Einheiten erstellen

Sie schreiben die Testklasse für lokale Einheiten als JUnit 4-Testklasse.

Dazu erstellen Sie eine Klasse, die eine oder mehrere Testmethoden enthält, normalerweise in module-name/src/test/ Eine Testmethode beginnt mit der Anmerkung @Test und enthält den Code zur Übung und Überprüfung eines einzelnen Aspekts der Komponente, der die Sie testen möchten.

Das folgende Beispiel zeigt, wie eine lokale Einheitentestklasse implementiert wird. Die Testmethode emailValidator_correctEmailSimple_returnsTrue()versucht isValidEmail(),eine Methode in der App. Die Testfunktion gibt „true“, wennisValidEmail() auch „true“ zurückgibt.

Kotlin

import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class EmailValidatorTest {
  @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() {
    assertTrue(EmailValidator.isValidEmail("name@email.com"))
  }

}

Java

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

class EmailValidatorTest {
  @Test
  public void emailValidator_CorrectEmailSimple_ReturnsTrue() {
    assertTrue(EmailValidator.isValidEmail("name@email.com"));
  }
}

Sie sollten lesbare Tests erstellen, die bewerten, App die erwarteten Ergebnisse zurückgeben. Wir empfehlen die Verwendung einer Assertion-Bibliothek wie als junit.Assert, Hamcrest oder Truth: Das Snippet oben ist ein Beispiel für junit.Assert

Mockable Android-Bibliothek

Wenn Sie lokale Einheitentests ausführen, enthält das Android-Gradle-Plug-in ein Bibliothek, die alle APIs des Android-Frameworks enthält, die in Ihrem Projekt verwendet wird. Die Bibliothek enthält alle öffentlichen Methoden und -Klassen dieser APIs, aber der Code innerhalb der Methoden wurde entfernt. Falls vorhanden der Methoden aufgerufen wird, löst der Test eine Ausnahme aus.

Dadurch können lokale Tests erstellt werden, wenn auf Klassen in der Android-App verwiesen wird. Framework wie Context. Noch wichtiger ist, dass Sie eine Simulation verwenden können, -Framework mit Android-Klassen.

Android-Abhängigkeiten simulieren

Ein typisches Problem besteht darin, festzustellen, ob eine Klasse eine Zeichenfolgenressource verwendet. Sie können Stringressourcen durch Aufrufen der Methode getString() im Context abrufen . In einem lokalen Test können Context oder eine ihrer Methoden jedoch nicht verwendet werden, gehören zum Android-Framework. Im Idealfall wäre der Aufruf von getString() aus dem Kurs gezogen, aber das ist nicht immer praktikabel. Die Lösung besteht darin, einen Mock oder einen Stub von Context erstellen, der immer denselben Wert zurückgibt, Die Methode getString() wird aufgerufen.

Mit der Mockable Android-Bibliothek und Mocking-Frameworks wie Mit Mockito oder MockK können Sie den von Modellen der Android-Klassen in Ihren Einheitentests.

So fügen Sie Ihrem lokalen Einheitentest mit Mockito ein simuliertes Objekt hinzu: Programmiermodell:

  1. Fügen Sie die Abhängigkeit der Mockito-Bibliothek in Ihre build.gradle-Datei ein: wie unter Testumgebung einrichten beschrieben.
  2. Fügen Sie am Anfang der Definition der Einheitentestklasse den Parameter @RunWith(MockitoJUnitRunner.class)-Anmerkung. Diese Anmerkung informiert die Mockito-Test-Runner, um zu überprüfen, ob Sie das Framework korrekt nutzen vereinfacht die Initialisierung Ihrer simulierten Objekte.
  3. Fügen Sie die Annotation @Mock hinzu, um ein simuliertes Objekt für eine Android-Abhängigkeit zu erstellen. vor der Felddeklaration hinzu.
  4. Um das Verhalten der Abhängigkeit zu durchsuchen, können Sie eine Bedingung angeben und Rückgabewert, wenn die Bedingung mithilfe von when() und thenReturn() erfüllt ist .

Im folgenden Beispiel sehen Sie, wie Sie einen Unittest erstellen, der eine Simulation verwendet. Das Objekt Context in Kotlin, das mit Mockito-Kotlin erstellt wurde.

import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock

private const val FAKE_STRING = "HELLO WORLD"

@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {

  @Mock
  private lateinit var mockContext: Context

  @Test
  fun readStringFromContext_LocalizedString() {
    // Given a mocked Context injected into the object under test...
    val mockContext = mock<Context> {
        on { getString(R.string.name_label) } doReturn FAKE_STRING
    }

    val myObjectUnderTest = ClassUnderTest(mockContext)

    // ...when the string is returned from the object under test...
    val result: String = myObjectUnderTest.getName()

    // ...then the result should be the expected one.
    assertEquals(result, FAKE_STRING)
  }
}

Weitere Informationen zur Verwendung des Mockito-Frameworks finden Sie in der Mockito API. Referenz und der SharedPreferencesHelperTest-Klasse in der Beispielcode. Probieren Sie auch das Codelab für Android-Tests aus.

Fehler: "Method ... not mocked"

Die Mockable Android-Bibliothek löst eine Ausnahme aus, wenn Sie versuchen, auf ihre Methoden mit der Error: "Method ... not mocked-Nachricht an.

Wenn die ausgelösten Ausnahmen für Ihre Tests problematisch sind, können Sie die , sodass die Methoden stattdessen entweder null oder null zurückgeben, je nachdem, gibt. Fügen Sie dazu die folgende Konfiguration im Top-Level-build.gradle-Datei in Groovy:

android {
  ...
  testOptions {
    unitTests.returnDefaultValues = true
  }