Tworzenie testów jednostek lokalnych

Test lokalny odbywa się bezpośrednio na Twojej stacji roboczej, a nie na Androidzie urządzenia lub emulatora. Wykorzystuje do tego lokalną maszynę wirtualną Java (JVM), do testów, a nie na urządzeniach z Androidem. Testy lokalne pozwalają ocenić do działania logiki aplikacji. Jednak brak możliwości interakcji Platforma Androida ogranicza liczbę dostępnych testów.

Test jednostek sprawdza zachowanie niewielkiej części kodu, jednostki test. Dzieje się to przez wykonanie tego kodu i sprawdzenie wyniku.

Testy jednostkowe są zwykle proste, ale ich konfiguracja może stanowić problem, jeśli jednostka w trakcie testowania nie jest zaprojektowany z myślą o możliwości testowania:

  • Kod, który chcesz zweryfikować, musi być dostępny z poziomu testu. Dla: nie możesz więc bezpośrednio przetestować metody prywatnej. Zamiast tego przetestujesz klasę za pomocą publicznych interfejsów API.
  • Aby można było przeprowadzić testy jednostkowe w izolacji, zależności jednostki w trakcie testów muszą zostać zastąpione komponentami, które kontrolujesz, takimi jak podróbki lub inne podwojenie testowe. Problem ten dotyczy szczególnie sytuacji, gdy kod zależy od platformy Android.

Więcej o typowych strategiach testowania jednostkowego w Androidzie dowiesz się z artykułu Co test.

Lokalizacja testów lokalnych

Domyślnie pliki źródłowe dla lokalnych testów jednostkowych są umieszczane w folderze module-name/src/test/ Ten katalog już istnieje, gdy tworzysz nowy za pomocą Android Studio.

Dodaję zależności testowe

Musisz też skonfigurować w projekcie zależności testowe, aby używać parametru dostępnych w środowisku testowym JUnit.

Aby to zrobić, otwórz plik build.gradle modułu aplikacji i podaj następujące dane jako zależności. Użyj funkcji testImplementation, aby wskazać, dotyczą one lokalnego zbioru źródeł testu, a nie aplikacji:

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"
}

Tworzenie zajęć testowych z jednostki lokalnej

Tworzysz klasę testu jednostki lokalnej jako klasę testową JUnit 4.

Aby to zrobić, utwórz klasę zawierającą co najmniej 1 metodę testowania, zwykle w metodzie module-name/src/test/ Metoda testowania zaczyna się od adnotacji @Test i który zawiera kod ćwiczenia i weryfikowanie jednego aspektu komponentu, które chcesz przetestować.

Poniższy przykład pokazuje, jak wdrożyć klasę testu jednostkowego lokalnego. metoda testowaemailValidator_correctEmailSimple_returnsTrue()próbuje zweryfikować isValidEmail(),która jest metodą w aplikacji. Funkcja testowa zwróci true (prawda), jeśli isValidEmail() również zwraca wartość „true” (prawda).

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"));
  }
}

Należy tworzyć czytelne testy, które pozwolą ocenić, czy komponenty w tabeli zwróci oczekiwane wyniki. Zalecamy użycie biblioteki asercji, takiej jak jako junit.Assert, Hamcrest lub Fakt. Powyższy fragment kodu pokazuje, jak za pomocą junit.Assert

Biblioteka Androida

Gdy uruchamiasz testy jednostkowe lokalnych, wtyczka Androida do obsługi Gradle zawiera biblioteka, która zawiera wszystkie interfejsy API platformy Android, od prawej do używanej w projekcie. W bibliotece znajdują się wszystkie publiczne metody tych interfejsów API, ale kod wewnątrz metod został usunięty. Jeśli tak, metody, które zostaną użyte, test zgłosi wyjątek.

Umożliwia to tworzenie testów lokalnych w przypadku odwołań do klas w Androidzie. takiej jak Context. Co ważniejsze, pozwala to wykorzystać z zajęciami dotyczącymi Androida.

Pozorowanie zależności Androida

Typowym problemem jest stwierdzenie, że klasa używa zasobu ciągu znaków. Dostępne opcje pobierz zasoby ciągów znaków, wywołując metodę getString() w Context zajęcia. W teście lokalnym nie można jednak używać właściwości Context ani żadnej z jej metod, ponieważ należą do platformy Androida. W idealnej sytuacji połączenie z numerem getString() to i wyjechali z klasy, ale nie zawsze jest to praktyczne. Rozwiązaniem jest utwórz makietę Context, która zawsze zwraca tę samą wartość, gdy argument Wywoływana jest metoda getString().

Z biblioteką aplikacji na Androida i platformami do tworzenia żartów, takich jak Mockito lub MockK, możesz zaprogramować próbek klas Androida podczas testów jednostkowych.

Aby dodać przykładowy obiekt do testu jednostkowego lokalnego za pomocą Mockito, postępuj zgodnie z tym model programowania:

  1. Dodaj zależność biblioteki Mockito do pliku build.gradle jako opisane w artykule Konfigurowanie środowiska testowego.
  2. Na początku definicji klasy testu jednostkowego dodaj @RunWith(MockitoJUnitRunner.class) adnotacja. Adnotacja informuje Mockito – uruchom testy do sprawdzenia, czy korzystasz z platformy prawidłowo upraszcza inicjowanie przykładowych obiektów.
  3. Aby utworzyć przykładowy obiekt zależności Androida, dodaj adnotację @Mock przed deklaracją pola.
  4. Aby skrócić zachowanie zależności, możesz określić warunek i zwracana wartość, gdy warunek jest spełniony za pomocą funkcji when() i thenReturn() .

Z przykładu poniżej dowiesz się, jak utworzyć test jednostkowy z przykładem Obiekt Context w Kotlin utworzony za pomocą narzędzia Mockito-Kotlin.

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)
  }
}

Więcej informacji o korzystaniu z platformy Mockito znajdziesz w Mockito API odniesienie i klasa SharedPreferencesHelperTest w funkcji przykładowy kod. Zapoznaj się też z ćwiczeniami z programowania Android Testing (w języku angielskim).

Błąd: „Metoda ... nie sfałszowana”

Biblioteka aplikacji na Androida zgłasza wyjątek, jeśli spróbujesz uzyskać dostęp do którejkolwiek z jej z komunikatem Error: "Method ... not mocked.

Jeśli zgłoszone wyjątki stanowią problem dla Twoich testów, możesz zmienić w taki sposób, aby metody zwracały wartość null lub zero, w zależności od zwracany typ. Aby to zrobić, dodaj w projekcie tę konfigurację plik build.gradle najwyższego poziomu w Groovy:

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