Yerel birim testleri oluşturma

Yerel test, bir Android cihaz veya emülatör yerine doğrudan kendi iş istasyonunuzda çalıştırılır. Dolayısıyla, testleri çalıştırmak için bir Android cihaz yerine yerel Java Sanal Makinenizi (JVM) kullanır. Yerel testler, uygulamanızın mantığını daha hızlı değerlendirmenizi sağlar. Ancak Android çerçevesiyle etkileşimde bulunamamak, çalıştırabileceğiniz test türlerinde sınırlamalara neden olur.

Birim testi, kodun küçük bir bölümünün (test edilen birimin) davranışını doğrular. Bunun için ilgili kodu çalıştırıp sonucu kontrol eder.

Birim testleri genellikle basittir ancak test edilen birim, test edilebilirlik göz önünde bulundurularak tasarlanmadığında kurulum sorunları olabilir:

  • Doğrulamak istediğiniz koda bir testten erişilebilir olması gerekir. Örneğin, bir gizli yöntemi doğrudan test edemezsiniz. Bunun yerine sınıfı herkese açık API'lerini kullanarak test edersiniz.
  • Birim testlerini izole olarak çalıştırmak için test edilen birimin bağımlılıkları, sahte veya diğer test çiftleri gibi kontrol ettiğiniz bileşenlerle değiştirilmelidir. Bu, özellikle kodunuz Android çerçevesine bağlıysa sorundur.

Android'de yaygın olarak kullanılan birim testi stratejileri hakkında bilgi edinmek için Neyi test etmelisiniz? başlıklı makaleyi okuyun.

Yerel test konumu

Varsayılan olarak, yerel birim testlerinin kaynak dosyaları module-name/src/test/ içine yerleştirilir. Android Studio'yu kullanarak yeni bir proje oluşturduğunuzda bu dizin zaten mevcut olur.

Test bağımlılıkları ekleme

Projenizin test bağımlılıklarını, JUnit test çerçevesi tarafından sağlanan standart API'leri kullanacak şekilde yapılandırmanız da gerekir.

Bunu yapmak için uygulamanızın modülünün build.gradle dosyasını açın ve aşağıdaki kitaplıkları bağımlılık olarak belirtin. Bu parametrelerin uygulama için değil, yerel test kaynağı grubu için geçerli olduğunu belirtmek amacıyla testImplementation işlevini kullanın:

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

Yerel birim test sınıfı oluşturma

Yerel birim test sınıfınızı JUnit 4 test sınıfı olarak yazarsınız.

Bunu yapmak için bir veya daha fazla test yöntemi içeren bir sınıf oluşturun (genellikle module-name/src/test/ bölümünde). Test yöntemi, @Test ek açıklamasıyla başlar ve test etmek istediğiniz bileşenin tek bir özelliğini uygulayıp doğrulamak için gereken kodu içerir.

Aşağıdaki örnekte, yerel birim test sınıfının nasıl uygulanacağı gösterilmektedir. Test yöntemi,uygulama içindeki bir yöntem olan emailValidator_correctEmailSimple_returnsTrue()doğrulamayı isValidEmail()yarar. isValidEmail() Doğru değerini de döndürürse test işlevi "true" değerini döndürür.

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

Uygulamanızdaki bileşenlerin beklenen sonuçları döndürüp döndürmediğini değerlendiren okunabilir testler oluşturmanız gerekir. junit.Assert, Hamcrest veya Truth gibi bir onaylama kitaplığı kullanmanızı öneririz. Yukarıdaki snippet, junit.Assert'nin nasıl kullanılacağına dair bir örnektir.

Sahte Android kitaplığı

Yerel birim testleri yürütürken Android Gradle Eklentisi, Android çerçevesinin tüm API'lerini projenizde kullanılan sürüme uygun olacak şekilde içeren bir kitaplık içerir. Kitaplık, bu API'lerin herkese açık tüm yöntemlerini ve sınıflarını içerir ancak yöntemlerin içindeki kod kaldırılmıştır. Yöntemlerden herhangi birine erişilirse test bir istisna atar.

Bu, Android çerçevesindeki Context gibi sınıflara referans verirken yerel testlerin derlenmesine olanak tanır. Daha da önemlisi, Android sınıflarında aldatma çerçevesi kullanmanıza imkan verir.

Android bağımlılıklarıyla alay etme

Tipik bir sorun, bir sınıfın dize kaynağı kullandığını bulmaktır. Context sınıfında getString() yöntemini çağırarak dize kaynakları elde edebilirsiniz. Ancak yerel bir test, Android çerçevesine ait olduğundan Context veya yöntemlerinden herhangi birini kullanamaz. İdeal olarak, getString() çağrısının sınıftan taşınması önerilir, ancak bu her zaman pratik değildir. Bunun çözümü, getString() yöntemi çağrıldığında her zaman aynı değeri döndüren bir Context örneği veya saplaması oluşturmaktır.

Sahte Android kitaplığı ve Mockito ya da MockK gibi aldatma çerçeveleri ile birim testlerinizde Android sınıflarının örnek davranışını programlayabilirsiniz.

Mockito'yu kullanarak yerel birim testinize örnek bir nesne eklemek için şu programlama modelini uygulayın:

  1. Test ortamınızı oluşturma bölümünde açıklandığı gibi, Mockito kitaplığı bağımlılığını build.gradle dosyanıza ekleyin.
  2. Ünite testi sınıfı tanımınızın başına @RunWith(MockitoJUnitRunner.class) ek açıklamasını ekleyin. Bu ek açıklama, Moockito test çalıştırıcısına çerçeve kullanımınızın doğru olduğunu doğrulamasını söyler ve örnek nesnelerinizin başlatılmasını kolaylaştırır.
  3. Android bağımlılığı için örnek nesne oluşturmak isterseniz alan bildiriminden önce @Mock ek açıklamasını ekleyin.
  4. Bağımlılığın davranışını belirlemek için when() ve thenReturn() yöntemlerini kullanarak bir koşul belirtebilir ve koşul karşılandığında değer döndürebilirsiniz.

Aşağıdaki örnekte, Kotlin'de Mockito-Kotlin ile oluşturulmuş örnek bir Context nesnesinin kullanıldığı birim testini nasıl oluşturabileceğiniz gösterilmektedir.

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

Mockito çerçevesini kullanma hakkında daha fazla bilgi için Mockito API referansına ve örnek koddaki SharedPreferencesHelperTest sınıfına bakın. Android Test Codelab'i de deneyin.

Hata: "Yöntem ... sahte değil"

Yöntemlerinden herhangi birine Error: "Method ... not mocked mesajıyla erişmeye çalışırsanız örnek Android kitaplığı bir istisna atar.

Atılan istisnalar testleriniz için sorun yaratıyorsa davranışı, yöntemlerin dönüş türüne bağlı olarak boş veya sıfır döndürmesi için değiştirebilirsiniz. Bunu yapmak için projenizin Groovy'deki üst düzey build.gradle dosyasına aşağıdaki yapılandırmayı ekleyin:

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