Android'de test ikililerini kullanın

Bir öğe veya sistem için test stratejisi tasarlarken test etmeyle ilgili üç unsur vardır:

  • Kapsam: Test, kodun ne kadarına dokunuyor? Testler tek bir yöntemi, uygulamanın tamamını veya bu ikisi arasında bir yeri doğrulayabilir. Test edilen kapsam test ediliyor ve genellikle Test Altındaki Konu olarak adlandırılsa da Sistem Test Ediliyor veya Test Altındaki Birim olarak da adlandırılmaktadır.
  • Hız: Test ne kadar hızlı yapılır? Test hızları milisaniye ile birkaç dakika arasında değişebilir.
  • Doğruluk: Testin "gerçek dünya" ne kadar geçerli olduğunu düşünüyorsunuz? Örneğin, test ettiğiniz kodun bir kısmının ağ isteğinde bulunması gerekiyorsa test kodu gerçekten bu ağ isteğini yapıyor mu yoksa sonuç sahte mi? Test gerçekten ağla konuşuyorsa doğruluğu daha yüksektir. Bunun karşılığında, testin çalışması daha uzun sürebilir, ağ kapalıysa hatalara neden olabilir veya kullanımı maliyetli olabilir.

Test stratejinizi tanımlamaya nasıl başlayacağınızı öğrenmek için neyi test edeceğinizi öğrenin.

İzolasyon ve bağımlılıklar

Bir öğeyi veya öğe sistemini test ederken bunu izole olarak yaparsınız. Örneğin, bir ViewModel'i test etmek için bir emülatör başlatmanıza ve Android çerçevesine bağlı olmadığından (veya gerektirmediğinden) bir kullanıcı arayüzü başlatmanıza gerek yoktur.

Ancak, test edilen öznenin işe yaraması için başkalarına bağımlı olabilir. Örneğin, ViewModel'in çalışması için bir veri deposuna bağlı olabilir.

Test edilen bir özneye bağımlılık sağlamanız gerektiğinde, yaygın olarak kullanılan bir uygulama test ikilisi (veya test nesnesi) oluşturmaktır. Test çiftleri, uygulamanızda bileşen olarak görünen ve hareket eden nesnelerdir ancak testinizde belirli bir davranış veya veri sağlamak için oluşturulurlar. Temel avantajları, testlerinizi daha hızlı ve basit hale getirmeleridir.

Çift test türleri

Test yinelemelerinin çeşitli türleri vardır:

Sahte Sınıfın "çalışan" bir uygulaması olan, ancak testler için iyi bir uygulama olup üretime elverişsiz bir şekilde uygulanmış bir test ikilisi.

Örnek: bellek içi veritabanı.

Sahte öğeler alaycı bir çerçeve gerektirmez ve hafiftir. Bunlar tercih edilir.

Yarım Programlama şeklinize göre davranan ve etkileşimleriyle ilgili beklentileri olan bir test ikilisi. Etkileşimleri, tanımladığınız koşulları karşılamıyorsa örnekler, testlerde başarısız olur. Örnekler genellikle tüm bunları başarmak için sahte bir çerçeve ile oluşturulur.

Örnek: Veritabanındaki bir yöntemin tam olarak bir kez çağrıldığını doğrulayın.

Stub Programlama şeklinize göre davranan ancak etkileşimleriyle ilgili beklentisi olmayan bir test ikilisi. Genellikle alaycı bir çerçeveyle oluşturulur. Kolaylık sağlaması açısından, sahte öğeler yerine geçici olarak oluşturulmuş öğeler tercih edilir.
Dummy Etrafta iletilen ancak kullanılmayan bir test ikilisi (örneğin, sadece parametre olarak sağlamanız gerekiyorsa).

Örnek: tıklama geri çağırması olarak iletilen boş bir işlev.

Casus Gerçek bir nesnenin üzerindeki sarmalayıcı, örneklere benzer şekilde bazı ek bilgilerin de kaydını tutar. Karmaşıklıktan genellikle kaçınılır. Bu nedenle sahtecilik ve taklitler casuslardan daha çok tercih edilir.
Gölge Robofactric'te sahte kullanılıyor.

Sahte kullanma örneği

UserRepository adlı bir arayüze bağlı olan ve ilk kullanıcının adını kullanıcı arayüzünde gösteren bir ViewModel'i birim test etmek istediğinizi varsayalım. Arayüzü uygulayıp bilinen verileri döndürerek sahte bir test ikilisi oluşturabilirsiniz.

object FakeUserRepository : UserRepository {
    fun getUsers() = listOf(UserAlice, UserBob)
}

val const UserAlice = User("Alice")
val const UserBob = User("Bob")

Bu sahte UserRepository ürününün, üretim sürümünün kullanacağı yerel ve uzak veri kaynaklarına bağlı olması gerekmez. Dosya, test kaynağı grubunda bulunur ve üretim uygulamasıyla birlikte gönderilmez.

Sahte bir bağımlılık, uzak veri kaynaklarına bağlı olmadan bilinen verileri döndürebilir
Şekil 1: Birim testindeki sahte bağımlılık.

Aşağıdaki test, ViewModel'in ilk kullanıcı adını görünüme doğru şekilde gösterdiğini doğrular.

@Test
fun viewModelA_loadsUsers_showsFirstUser() {
    // Given a VM using fake data
    val viewModel = ViewModelA(FakeUserRepository) // Kicks off data load on init

    // Verify that the exposed data is correct
    assertEquals(viewModel.firstUserName, UserAlice.name)
}

ViewModel, test kullanıcısı tarafından oluşturulduğundan UserRepository öğesini sahte bir öğeyle değiştirmek birim testinde kolaydır. Ancak daha büyük testlerde rastgele öğeleri değiştirmek zor olabilir.

Bileşenleri ve bağımlılık yerleştirmeyi değiştirme

Testler, test edilen sistemlerin oluşturulması üzerinde herhangi bir kontrole sahip olmadığında test çiftlerine ait bileşenlerin değiştirilmesi daha fazla işin içine girer ve uygulamanızın mimarisinin test edilebilir bir tasarıma uymasını gerektirir.

Uygulamanızdaki tam kullanıcı akışından geçen araçlı kullanıcı arayüzü testi gibi büyük uçtan uca testlerde bile test ikilileri kullanılabilir. Bu durumda, testinizi hermetik yapmak isteyebilirsiniz. Hermetik test, internetten veri getirmek gibi tüm harici bağımlılıkları önler. Bu, güvenilirliği ve performansı artırır.

Şekil 2: Uygulamanın çoğunu kapsayan ve sahte uzak veriler oluşturan büyük bir test.

Uygulamanızı bu esnekliğe manuel olarak ulaşacak şekilde tasarlayabilirsiniz, ancak test sırasında uygulamanızdaki bileşenleri değiştirmek için Hilt gibi bir bağımlılık ekleme çerçevesi kullanmanızı öneririz. Hilt test kılavuzuna bakın.

Robolektrik

Android'de, özel bir test ikilisi türü sağlayan Robofactric çerçevesini kullanabilirsiniz. Robofactric, testlerinizi iş istasyonunuzda veya sürekli entegrasyon ortamınızda çalıştırmanıza olanak tanır. Emülatör veya cihaz olmadan normal bir JVM kullanır. Bu model, gölge adı verilen test yinelemeleri ile görüntüleme sayısını, kaynak yüklemeyi ve Android çerçevesinin diğer bölümlerini şişirmeyi simüle eder.

Robofactric bir simülatördür. Bu nedenle, basit birim testlerinin yerine geçmemeli veya uyumluluk testi yapmak için kullanılmamalıdır. Hız sağlar ve bazı durumlarda düşük kaliteyi göz önünde bulundurarak maliyeti azaltır. Kullanıcı arayüzü testlerine yönelik iyi bir yaklaşım, testlerin hem Roboecric hem de enstrümanlı testlerle uyumlu olmasını sağlamak ve test işlevselliği veya uyumluluk ihtiyacına bağlı olarak ne zaman çalıştırılacağına karar vermektir. Hem Espresso hem de Compose testleri Roboecric'te çalıştırılabilir.