API istemcisini ve paketleyicileri test etme


14

Geliştirdiğim bir API istemci kütüphanesini test etmenin en iyi yolunu bulmaya çalışan çevrelerde dolaşıyorum. Kütüphane, Clienttemel olarak API ile 1: 1 eşleşmeye sahip bir Wrappersınıfa ve üstünden daha kullanıcı dostu bir arayüz sağlayan ek bir sınıfa sahiptir Client.

Wrapper --> Client --> External API

Ben ilk ikisine karşı bir sürü test yazmış Clientve Wrapperetkili bir şekilde sadece onlar ileri üzerinde işlem ne olursa olsun uygun fonksiyonlara (o test Wrapperçalışır Clientve Clientbir HTTP bağlantısı üzerinde çalışır). Bununla birlikte, bundan rahatsızlık duymaya başladım, çünkü arayüzden ziyade bu sınıfların uygulanmasını test ediyor gibi hissediyorum. Teorik olarak, sınıfları tamamen geçerli başka bir uygulamaya sahip olacak şekilde değiştirebilirim, ancak denemem beklenen fonksiyonlar çağrılmadığından testlerim başarısız olur. Bana kırılgan testler gibi geliyor.

Bundan sonra sınıfların arayüzünü düşündüm. Testler, sınıfların gerçekte nasıl yaptıklarından ziyade yapmaları gereken işi yaptığını doğrulamalıdır. Peki bunu nasıl yapabilirim? Akla ilk gelen harici API isteklerini saplamak. Ancak, dış hizmeti aşırı derecede basitleştirmek konusunda endişeliyim. Gördüğüm stubbed API'lerin birçoğu, sadece kodunuzun sahte API'nize karşı doğru çalışıp çalışmadığını test etmenin gerçekten kolay bir yolu gibi görünen hazır yanıtlar veriyor. Alternatif, sadece olanaksız olan ve gerçek hizmet her değiştiğinde güncel kalması gereken hizmeti alay etmektir - bu aşırıya kaçma ve zaman kaybı gibi hissettirir.

Son olarak, bunu SE programcılarının başka bir cevabından okudum :

Uzak bir API istemcisinin işi, belirli çağrılar yapmaktır - ne daha fazla ne daha az. Bu nedenle, testi bu çağrıları düzenlediğini doğrulamalıdır - daha fazla, daha az değil.

Ve şimdi az çok ikna oldum - test ederken, test Clientetmem gereken tek şey API'ya doğru isteklerde bulunması (Tabii ki, her zaman API'nin değişme olasılığı var, ancak testlerim geçmeye devam ediyor - ama bu entegrasyon testlerinin yararlı olacağı yerlerde). Yana Clientsadece 1'dir: API ile 1 haritalama, benim endişe gerçekten geçerli değildir başka bir geçerli uygulamadan değiştirme hakkında daha önce - her yöntem için yalnızca bir geçerli uygulama var Client.

Ancak, hala Wrappersınıfa takılı kaldım . Aşağıdaki seçenekleri görüyorum:

  1. ClientSınıfı saplamış ve sadece uygun yöntemlerin denendiğini test ediyorum . Bu şekilde, yukarıdakiyle aynı şeyi yapıyorum, ancak ClientAPI için bir stand-in olarak davranıyorum. Bu beni başladığım yere geri getiriyor. Bir kez daha, bu bana arabirimi değil, uygulamayı test etmekten rahatsızlık veriyor. WrapperÇok iyi bambaşka istemcisi kullanılarak uygulanabilir.

  2. Ben bir alay yarattım Client. Şimdi bununla alay etmek için ne kadar uzağa gideceğime karar vermeliyim - hizmetin tam bir alayını oluşturmak çok çaba gerektirecek (kütüphanenin kendisine gitenden daha fazla iş). API'nin kendisi basittir, ancak hizmet oldukça karmaşıktır (aslında bu veriler üzerinde işlemlere sahip bir veri deposu). Ve yine, alayımı gerçekle senkronize tutmak zorunda kalacağım Client.

  3. Sadece uygun HTTP isteklerinin yapıldığını test ediyorum. Bu, bu HTTP isteklerini yapmak Wrapperiçin gerçek bir Clientnesne üzerinden çağrılacağı anlamına gelir , bu yüzden aslında tek başına test etmiyorum. Bu biraz korkunç bir birim testi yapar.

Bu yüzden bu çözümlerin hiçbirinden özellikle memnun değilim. Sen ne yapardın? Bu konuda doğru bir yol var mı?


Ben bu işi senaryoların çoğunu yapan bir üçüncü taraf kütüphanesi var ve sadece bir sarıcı var bu senaryolarda birim test kaçınmak eğilimindedir (esas olarak bunu gerçekten anlamlı bir şey test bir şekilde yapmak için hiçbir fikrim yok çünkü). Genellikle bu durumlarda, muhtemelen sahte bir hizmetle entegrasyon testi yaparım. Belki birisi bunlar için gerçekten anlamlı bir birim testi yapmayı bilir - kontrolümüz altındaki sistemdeki en kritik bileşenlere öncelik verme eğilimindeyim. Burada kritik kısım bizim kontrolümüz dışında. :-(

Yanıtlar:


10

TLDR : Zorluğa rağmen, müşteri birimi testi için hizmeti saptamalı ve kullanmalısınız.


API, yalnızca her zaman sabit bir durum döndüren ve ne tüketip ne de üretmeyen uç noktalardan oluşmadığı sürece, "uzak bir API istemcisinin işi belirli çağrılar, daha fazla, daha az değil ..." vermekten emin değilim herhangi bir veri. Bu en kullanışlı API olmaz ...

Ayrıca, istemcinin yalnızca doğru istekleri gönderdiğini değil , yanıt içeriğini, hataları, yönlendirmeleri vb. Doğru şekilde işleyip işlemediğini de kontrol etmek istersiniz . Tüm bu durumları test edin.

Not ettiğiniz gibi, tüm yığınları sarmalayıcıdan -> istemci -> hizmet -> DB ve ötesinden kapsayan, ancak entegrasyon testlerinin her birinin bir parçası olarak çalıştırılabileceği bir ortamınız yoksa, ana sorunuzu cevaplamak için entegrasyon testlerine sahip olmalısınız. CI, çok fazla baş ağrısı olmadan (paylaşılan test veritabanları, vb.) Oluşturulursa, API'nın bir saplamasını oluşturmak için zaman ayırmalısınız.

Saplama, hizmetin çalışan bir uygulamasını oluşturmanıza izin verir, ancak hizmetin altında herhangi bir katman uygulamak zorunda kalmazsınız.

Bunu gerçekleştirmek için REST kaynaklarının altındaki Depo modelinin uygulanmasıyla DI tabanlı bir çözüm kullanmayı düşünebilirsiniz:

  • REST işleyicilerindeki tüm işlev kodlarını bir IWhateverRepository çağrılarıyla değiştirin.
  • REST kaynaklarından çıkarılan kodla birlikte bir UnitWhateverRepository ve birim sınama sırasında kullanılmak üzere hazır yanıtlar döndüren bir TestWhateverRespository oluşturun.
  • DI kapsayıcısını yapılandırmaya bağlı olarak ProductionWhateverRepository veya TestWhateverRepository DLL / sınıfını vb. Enjekte etmek için kullanın.

Her neyse, hizmetin inatçı ve / veya yeniden düzenlenmesi siyasi veya pratik olarak söz konusu değilse, muhtemelen yukarıdakine benzer bir şey üstlenirdim. Mümkünse, gerçekten iyi bir entegrasyon kapsamına sahip olduğunuzdan ve mevcut test kurulumunuz göz önüne alındığında bunları mümkün olduğunca sık çalıştırdığınızdan emin olurum.

HTH

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.