Yerel test, Android cihaz veya emülatör yerine doğrudan kendi iş istasyonunuzda çalışır. Bu nedenle, testleri çalıştırmak için 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şim kuramamak, çalıştırabileceğiniz test türlerini sınırlar.
Birim testi, kodun küçük bir bölümünün (test edilen birim) davranışını doğrular. Bunu, ilgili kodu çalıştırıp sonucu kontrol ederek yapar.
Birim testleri genellikle basittir ancak test edilen birim test edilebilirlik göz önünde bulundurularak tasarlanmadığında kurulumu sorunlu olabilir:
- Doğrulamak istediğiniz kodun bir testten erişilebilir olması gerekir. Örneğin, özel bir 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ı, kontrol ettiğiniz bileşenlerle (ör. sahte bileşenler veya diğer test çiftleri) değiştirilmelidir. Bu durum, özellikle kodunuz Android çerçevesine bağlıysa sorun yaratır.
Android'deki yaygın birim testi stratejileri hakkında bilgi edinmek için Neleri test etmelisiniz? başlıklı makaleyi okuyun.
Yerel testlerin konumu
Varsayılan olarak, yerel birim testlerinin kaynak dosyaları module-name/src/test/ dizinine yerleştirilir. Android Studio'yu kullanarak yeni bir proje oluşturduğunuzda bu dizin zaten mevcuttur.
Test bağımlılıkları ekleme
Ayrıca, JUnit test çerçevesi tarafından sağlanan standart API'leri kullanmak için projenizin test bağımlılıklarını yapılandırmanız gerekir.
Bunun 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. Bunların uygulamaya değil, yerel test kaynak grubuna uygulandığını belirtmek için 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 testi sınıfı oluşturma
Yerel birim testi sınıfınızı JUnit 4 test sınıfı olarak yazarsınız.
Bunun için genellikle module-name/src/test/ içinde bir veya daha fazla test yöntemi içeren bir sınıf oluşturun. Test yöntemi @Test ek açıklamasıyla başlar ve test etmek istediğiniz bileşenin tek bir yönünü uygulamak ve 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, uygulamadaki bir yöntem olan isValidEmail() yöntemini doğrulamaya çalışır. isValidEmail() da doğru değerini döndürürse test işlevi doğru değerini döndürür.emailValidator_correctEmailSimple_returnsTrue()
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 öğesinin nasıl kullanılacağına dair bir örnektir.
Taklit edilebilir Android kitaplığı
Yerel birim testlerini çalıştırdığınızda Android Gradle eklentisi, projenizde kullanılan sürüme uygun olarak Android çerçevesinin tüm API'lerini içeren bir kitaplık içerir. Kitaplık, bu API'lerin tüm herkese açık 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 hatası verir.
Bu sayede, Android çerçevesindeki Context gibi sınıflara referans verilirken yerel testler oluşturulabilir. Daha da önemlisi, Android sınıflarıyla bir taklit çerçevesi kullanmanıza olanak tanır.
Android bağımlılıklarını taklit etme
Sık karşılaşılan sorunlardan biri, bir sınıfın dize kaynağı kullandığını fark etmektir. Context sınıfındaki getString() yöntemini çağırarak dize kaynaklarını alabilirsiniz. Ancak yerel testler, Android çerçevesine ait oldukları için Context sınıfını veya yöntemlerini kullanamaz. İdeal olarak, getString() çağrısı sınıftan çıkarılmalıdır ancak bu her zaman mümkün olmayabilir. Çözüm, getString() yöntemi çağrıldığında her zaman aynı değeri döndüren bir Context taklidi veya taslağı oluşturmaktır.
Mockable Android kitaplığı ve Mockito veya MockK gibi taklit çerçeveleriyle, birim testlerinizde Android sınıflarının taklitlerinin davranışını programlayabilirsiniz.
Mockito kullanarak yerel birim testinize bir sahte nesne eklemek için aşağıdaki programlama modelini uygulayın:
- Test ortamınızı ayarlama bölümünde açıklandığı gibi, Mockito kitaplığı bağımlılığını
build.gradledosyanıza ekleyin. - Birim 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çeveyi doğru şekilde kullandığınızı doğrulamasını söyler ve sahte nesnelerinizin başlatılmasını basitleştirir. - Bir Android bağımlılığı için sahte nesne oluşturmak istiyorsanız alan beyanından önce
@Mockek açıklamasını ekleyin. - Bağımlılığın davranışını taklit etmek için
when()vethenReturn()yöntemlerini kullanarak bir koşul ve koşul karşılandığında döndürülecek değeri belirtebilirsiniz.
Aşağıdaki örnekte, Mockito-Kotlin ile oluşturulmuş Kotlin'de sahte bir Context nesnesi kullanan birim testinin nasıl oluşturulacağı 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ına ve örnek koddaki SharedPreferencesHelperTest sınıfına bakın. Android Test Codelab'ini de deneyebilirsiniz.
Hata: "Method ... not mocked" (Yöntem ... taklit edilmedi)
Mockable Android kitaplığı, Error: "Method ... not mocked mesajıyla yöntemlerinden herhangi birine erişmeye çalışırsanız bir istisna oluşturur.
Oluşturulan istisnalar testleriniz için sorun teşkil ediyorsa davranışı değiştirerek yöntemlerin dönüş türüne bağlı olarak null veya sıfır döndürmesini sağlayabilirsiniz. Bunu yapmak için projenizin üst düzey build.gradle dosyasına Groovy'de aşağıdaki yapılandırmayı ekleyin:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}