Her adım için ayrı test yöntemlerine sahip olmak iyi bir fikir mi?


10

Bir REST API'sini test ediyorum. Diyelim ki bir JSON yapısı döndürüyor. Sunucuyu test etmek için en iyi yaklaşım nedir? Her test adımı ancak önceki adımların tümü başarılı olduğunda başarılı olabilir.

Yapı A: her şeyi bir kerede test edin

- Test method 1:
    - make server request
    - assert http response code was 200
    - assert returned file is not empty
    - assert returned file has valid JSON syntax
    - assert returned JSON contains key X

Bu en iyi çözüm gibi görünüyor.

Avantajları:

  • Yalnızca bir sunucu isteği
  • Bir bütün olarak davranışı test ediyorum "Sunucu X anahtarıyla bir JSON döndürüyor mu?"

Yapı B: Her bir teste kademeli olarak ekler ekleyin

 - Test method 1:
     - make server request
     - assert http response code was 200
 - Test method 2:
     - make server request
     - assert returned file is not empty
 - Test method 3:
     - make server request
     - assert returned file has valid JSON syntax
 - Test method 4:
     - make server request
     - assert returned JSON contains key X

Bu şekilde yapmaya başladım ve her yolun tek bir şeyi test ettiği ve bu da daha iyi bir ayrılık yaratacağı için bunun bir yol olması gerektiğine ikna oldum . Ama şimdi, bunlar birim testler olmadığından ayrılmamın uygun olmadığını ve davranışı bir bütün olarak test etmem gerektiğini düşünüyorum.

Yapı C: bir kez istekte bulunun ve önbellek yanıtında ayrı test yöntemleri çalıştırın

- make server request and cache it (allow read-only access)

 - Test method 1:
     - assert http response code was 200 on cached server request
 - Test method 2:
     - assert returned file is not empty on cached server request
 - Test method 3:
     - assert returned file has valid JSON syntax on cached server request
 - Test method 4:
     - assert returned JSON contains key X on cached server request

Avantajları:

  • Tekrarlanan (pahalı) sunucu isteği yok
  • Hala tek onaylı test yöntemleri var

Kullanılması en mantıklı test yapısı hangisidir?


Lütfen daha sonra mevcut cevapları geçersiz kılacak şekilde sorunuzu değiştirmeyi bırakın! Teşekkürler.
Doc Brown

Rahatsızlık verdiğiniz için özür dileriz, ancak başka türlü yapmayı önerir misiniz?
mrplow

Öncelikle, sorunuzu gerçekten bu şekilde değiştirmeniz gerekiyorsa iki kez düşünün. Bazı cevapları geçersiz kılan bir şey eklemeniz gerektiğini düşünüyorsanız, yanıtlarının altına, metninde bir şey değiştirmek ya da eklemek isteyip istemediklerini soran bir yorum bırakarak tüm yazarları bilgilendirebilirsiniz.
Doc Brown

2
Aslında soru değiştirilirse cevap yazarlarının bildirildiğini varsaydım. Bu yüzden konu dışı ifadelerle yorumları spam yapmak istemedim. Gelecekte yazarları bilgilendireceğim. Ve soruma cevap verdiğiniz için teşekkür ederim.
mrplow

Yanıtlar:


3

En iyi uygulamaların her zaman bir amacı, bir nedeni vardır. Tasarımınızda bu nedenleri göz önünde bulundurmak her zaman iyi bir fikirdir - özellikle bu en iyi uygulamaları nasıl ve ne kadar zor uygulayacağınıza karar vermeye çalışırken.

Bu durumda, her test testini tek bir şey yapmanın arkasındaki temel sebep, ilk şey başarısız olursa, ikincisinin test edilmeyeceğidir. Çok fazla fikir üreticisi, her şeyi mümkün olan en küçük bitlere ayırmada ve her biti olabildiğince fazla şişkinlikte sarmada değer bulduğu için, bu, her testin tek bir iddia içermesi gerektiği fikrini doğurdu.

Bunu körü körüne takip etme. Her test bir şeyi test etse bile, yine de her "şeyin" ne kadar büyük veya küçük olması gerektiğine karar vermeniz gerekir ve bunu yapmak için her testin neden bir şeyi test etmesini istediğinizi aklınızda bulundurmalısınız - emin olmak için ilk şeydeki bir hata, ikinci şeyi denenmeden bırakmak değildir.

Yani, kendinize şunu sormalısınız - "burada gerçekten bu garantiye ihtiyacım var mı?"

Diyelim ki ilk test durumunda bir hata var - HTTP yanıt kodu değil 200. Bu yüzden kodu hacklemeye başlıyorsunuz, neden yanıt kodunu alamadığınızı anlayın ve sorunu düzeltin. Şimdi ne olacak?

  • Testi el ile tekrar çalıştırırsanız, düzeltmenizin sorunu çözdüğünü doğrulamak için, ilk hatanın gizlediği başka bir sorunla karşılaşmanız gerekir.
  • Manuel olarak çalıştırmazsanız (belki de çok uzun sürdüğü için mi?) Ve otomatik test sunucusunun her şeyi çalıştırmasını beklerken düzeltmenizi itin, farklı testlere farklı eklemeler koymak isteyebilirsiniz. Bu durumda döngüler çok uzundur, bu nedenle her döngüde çok sayıda hata keşfetmeye çalışmak önemlidir.

Dikkate alınması gereken birkaç şey daha var:

İddia bağımlılıkları

Açıkladığınız testlerin sadece bir örnek olduğunu biliyorum ve gerçek testleriniz muhtemelen daha karmaşıktır - bu yüzden söyleyeceğim şey gerçek testlerde çok fazla güçle geçerli olmayabilir, ancak yine de biraz etkili olabilir. düşünmek isteyebilir.

Yanıtları JSON biçiminde döndüren bir REST hizmetiniz (veya başka bir HTTP protokolünüz) varsa, genellikle normal nesneleri döndüren normal yöntemler gibi REST yöntemlerini kullanmanızı sağlayan basit bir istemci sınıfı yazarsınız. Müşterinin çalıştığından emin olmak için ayrı testler olduğunu varsayarsak, ilk 3 önermeden vazgeçirdim ve sadece 4 tane tuttum!

Neden?

  • İlk iddia gereksizdir - HTTP yanıt kodu 200 değilse istemci sınıfı bir istisna atmalıdır.
  • İkinci iddia gereksizdir - yanıt boşsa, sonuç nesnesi boş olacaktır veya boş bir nesnenin başka bir temsili olacaktır ve X anahtarını koymak için hiçbir yere sahip olmayacaksınız.
  • Üçüncü iddia gereksizdir - JSON geçersizse, ayrıştırmaya çalıştığınızda bir istisna alırsınız.

Bu nedenle, tüm bu testleri çalıştırmanıza gerek yoktur - sadece dördüncü testi çalıştırın ve hatalardan herhangi biri ilk üç deneme gerçekleşmeye çalışırsa, gerçek iddiayı bile almadan önce test uygun bir istisna ile başarısız olur.

Raporları nasıl almak istersiniz?

Diyelim ki bir test sunucusundan e-posta almıyorsunuz, bunun yerine KG departmanı testleri yürütüyor ve başarısız testler konusunda sizi bilgilendiriyor.

KG'den Jack kapıyı çalıyor. İlk test yönteminin başarısız olduğunu ve REST yönteminin hatalı bir yanıt kodu döndürdüğünü söylüyor. Ona teşekkür ediyorsun ve kök nedeni aramaya başlıyorsun.

Sonra QA'dan Jen geliyor ve üçüncü test yönteminin başarısız olduğunu söylüyor - REST yöntemi yanıt gövdesinde geçerli bir JSON döndürmedi. Ona zaten bu yönteme baktığınızı söylüyorsunuz ve kötü bir çıkış kodu döndürmesine neden olan şeyin aynı zamanda geçerli bir JSON olmayan ve daha çok istisna yığını izine benzeyen bir şey döndürmesine neden olduğuna inanıyorsunuz.

Çalışmaya geri dönüyorsunuz, ancak QA'dan Jim geliyor, dördüncü test yönteminin başarısız olduğunu ve yanıtta X anahtarı olmadığını söylüyor ...

Nedeni bile göremezsiniz çünkü bilgisayar ekranınız olmadığında koda bakmak zor. Jim yeterince hızlı olsaydı zaman içinde kaçabilirdi ...

Test sunucusundan gelen e-postaların işten çıkarılması daha kolaydır, ancak yine de - SADECE test yönteminde bir sorun olduğunu bildirmek ve ilgili test günlüklerine kendiniz bakmak istemez miydiniz ?


3

Aynı parametrelerle bir sunucu isteği yapmanın her zaman aynı davranacağını güvenli bir şekilde varsayarsanız, yöntem B neredeyse anlamsızdır - bir çağrı yeterli olduğunda aynı yanıt verisini dört kez almak için neden aynı yöntemi dört kez çağırmalısınız?

Ve bunu güvenli bir şekilde kabul edemez ve testin bir parçası yapmak istiyorsanız, A testini birkaç kez çalıştırmak için daha iyi olabilirsiniz.

B'nin fayda sağlayabileceği tek varsayımsal durum, test çerçeveniz yalnızca açık test yöntemlerinin açılıp kapatılmasına izin verdiğinde ve bunu testinizin bireysel adımları için yapma zorunluluğudur.

Alternatif C, A'yı yukarıda B için bahsettiğim tek fayda ile birleştiriyor gibi görünüyor. Test çerçeveniz, kodunuzun B'nin üzerinde fazla bir yük olmadan bu şekilde kolayca yapılandırılmasına izin veriyorsa, bu uygulanabilir bir yaklaşımdır. Bununla birlikte, bu A'ya bazı ek karmaşıklık ekler, bu yüzden sadece bireysel testleri açmak ve kapatmak istersem kullanırım, aksi takdirde YAGNI prensibini uygulayın ve en basit çözüme (A) sadık kalın.

TLDR: Tüm varsayımların her zaman tek bir testte çalıştırılmasını istediğinizden eminseniz A ile başlayın, bağımsız ekler hakkında dışarıdan daha kolay kontrole sahip olmanız gerektiğini fark ederseniz C'ye yeniden bakın.


0

Herhangi bir kod gibi, erken optimizasyondan kaçının. Önce testlerinizi, okunması ve bakımı kolay olacak şekilde yazın. Testler çok yavaşlamaya başladığında optimize edin. Oldukça basit örneğinizde, A ve B'nin her ikisinin de okunması ve bakımı kolay olacaktır, bu yüzden işler çok yavaş olana (B yapısı) veya çok karmaşık olana (A yapısı) kadar istediğinizi seçin.

Sunucunuz vatansızsa, iletinin tamamını tek seferde kontrol etmek için gerçek yanıtı beklenen bir yanıtla karşılaştırarak en iyi duruma getirebilirsiniz. Açıkçası bu okunabilirlik pahasına olacaktır.

Sunucunuz durumdaysa ve sunucuyu sınama durumuna getirmek için birden çok yavaş api çağrısı yapmanız gerekiyorsa, farklı bir yaklaşım izlemeniz veya sınamanızın çalışması birkaç dakika sürebilir. Örneğin, bir nesneyi test için uygun durumda hızlı bir şekilde alabilmeniz için bir test veritabanına veri enjekte etmek için bir veritabanı güncellemesi çalıştırabilirsiniz. Test hızlı ve okunabilir ancak bakımı daha zordur. Alternatif olarak, api'nin önüne bir cephe yazabilirsiniz, böylece birden fazla api çağrısı, test ettiğiniz iş süreciyle daha yakından eşleşen tek bir api çağrısı haline gelir.


0

Testler bir şeyleri paylaşmamalıdır - sıfırdan başlayarak bir testin diğeri üzerindeki etkisini önlersiniz. Bu ayrıca testleri rastgele sırayla çalıştırabilmenizi sağlar.
Bu yüzden C yolu kabul edilmemelidir.


Herhangi bir kod yazarken (veya belki de başka bir şey oluştururken), kendinize her zaman sorun: "neden böyle bir uygulama var?"
Neden her şey için farklı testler yapılması gerektiğini söylüyoruz?

Buna ihtiyacınız olduğunda iki durum söz konusudur:

  1. "her test adımı yalnızca öncekilerin tümü başarılı olduğunda başarılı olabilir"
  2. testlerinizin açıklayıcı onay mesajları olmadığında

Bu davalarla yüzleşmenizin iki nedeni vardır:

  1. "her test adımı yalnızca önceki tüm başarılı olmaları durumunda başarılı olabilir" ürün özelliğiniz için gerçekten geçerli değil
  2. deneyim veya zaman eksikliği veya ürün karmaşıklığı nedeniyle ürün hakkında yeterli bilgiye sahip değilsiniz

Eğer herhangi bir nedenle bu nedenlerden en az birini yer körü körüne B yapısına sahip olduğunu ilan edemezseniz .


Aksi takdirde (umarım buraya gelirsiniz) A'yı seçersiniz .


Ayrıca bu soruyu Yazılım Kalite Güvencesi ve Test Stackexchange sitesinde de sorabilirsiniz .

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.