Yerel birim testleri oluşturma

Yerel test, bir Android cihaz veya emülatör yerine doğrudan kendi iş istasyonunuzda çalışır. Bu nedenle, 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, yani test edilen birimin davranışını doğrular. Bunu yapmak için ilgili kodu çalıştırıp sonucu kontrol eder.

Birim testleri genellikle basittir ancak test edilen birimin test edilebilirlik göz önünde bulundurularak tasarlanmadığı durumlarda kurulumları sorunlu olabilir:

  • Doğrulamak istediğiniz koda bir test üzerinden erişilebilir olması gerekir. Örneğin, gizli bir yöntemi doğrudan test edemezsiniz. Bunun yerine, sınıfı herkese açık API'lerini kullanarak test edersiniz.
  • Birim testlerini izolasyonda ç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 sorunludur.

Android'deki yaygın birim testi stratejileri hakkında bilgi edinmek için Neleri test etmelisiniz? bölümünü 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 de yapılandırmanız 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 değişkenlerin 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 ünite testi sınıfınızı JUnit 4 test sınıfı olarak yazacaksı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/ dahilinde). Test yöntemi, @Test ek açıklamasıyla başlar ve test etmek istediğiniz bileşenin tek bir yönünü uygulayıp doğrulamak için gereken kodu içerir.

Aşağıdaki örnekte, yerel birim testi sınıfının nasıl uygulanacağı gösterilmektedir. Test yöntemi,uygulama içindeki bir yöntem olan emailValidator_correctEmailSimple_returnsTrue()isValidEmail() özelliğini doğrulamaya çalışır. isValidEmail() doğru değerini de döndürürse test işlevi de 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şturmalısınız. 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 gerçekleştirdiğinizde Android Gradle Eklentisi, Android çerçevesinin tüm API'lerini içeren ve projenizde kullanılan sürüme uygun şekilde doğru olan bir kitaplık içerir. Kitaplık, bu API'lerin tüm herkese açık yöntemlerini ve sınıflarını barındırır 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 verilirken yerel testlerin derlenmesine olanak tanır. Daha da önemlisi, Android sınıflarında alaycı bir çerçeve kullanabilirsiniz.

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

Tipik bir sorun, bir sınıfın bir 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ı sınıftan taşınır, ancak bu her zaman pratik değildir. Çö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 sahte çerçevelerle, birim testlerinizde Android sınıflarının taklit 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ı ayarlama 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, Mockito 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. Bir Android bağımlılığı için örnek nesne oluşturmak üzere @Mock ek açıklamasını alan bildiriminden önce ekleyin.
  4. Bağımlılığın davranışını tespit etmek için when() ve thenReturn() yöntemlerini kullanarak bir koşul belirtebilir ve koşul karşılandığında yeni değer döndürebilirsiniz.

Aşağıdaki örnekte, Kotlin'de Mockito-Kotlin ile oluşturulmuş örnek bir Context nesnesinin kullanıldığı bir 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 edinmek için Mockito API referansı ve örnek koddaki SharedPreferencesHelperTest sınıfını inceleyin. Ayrıca Android Test Codelab'i de deneyin.

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

Error: "Method ... not mocked mesajıyla yöntemlerinden herhangi birine erişmeye çalışırsanız Sahte Android kitaplığı bir istisna oluşturur.

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

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