Daha sonra yorumlanma eğiliminde olduklarından veya entegrasyon testleri daha değerli olduklarından ünite testleri yazmamak mantıklı mı?


35

Birim / entegrasyon testini bir meslektaşımla tartışıyordum ve ünite testleri yazmaya karşı ilginç bir dava açtı . Ben büyük bir ünite sınavıyım (öncelikle JUnit) savunucuyum, ancak ilginç noktalara değindiği için başkalarının aldıklarını duymak istiyorum.

Puanlarını özetlemek için:

  • Büyük kod değişiklikleri gerçekleştiğinde (yeni POJO kümesi, büyük uygulama yeniden düzenlemesi vb.), Birim testleri elden geçirilmek yerine yorumlanma eğilimindedir.
  • Kullanım kapsamını kapsayan entegrasyon testlerinde zaman harcanması daha küçük kapsamlı testleri daha az / hiç önemli yapmaz.

Bununla ilgili düşünceler? Entegrasyon testleri en azından bu kadar değerli olsa da hala birim yanlısı test yapıyorum (sürekli olarak kod geliştirdiğini görüyorum).


9
Sen kendin söyledin: birim testleri yazmak daha iyi kod üretir, çünkü sizi test edilebilir bir kod yazmaya zorlar. Birimin test edilebilir kodu, genel kalitesini artıran çok önemli özelliklere sahiptir.
Robert Harvey

1
@Robert Harvey - Kabul - Bu özelliklerin bir listesini görmek isterdim.
Jeff Levine

18
İlk olarak, temel olarak birim testlerinin bir dezavantajının, onları kullanmadığınızda çalışmadıklarını söylüyorsunuz. Başka bir uygulama için de aynı şeyi söyleyebilirsiniz. Ayrıca, pasif sesi kullanımınız, birinin ünite testlerini aktif olarak yorumladığı gerçeğini yansıtıyor. Öyleyse, ekipteki geliştiricilerin katılımından hoşlanmıyorsunuz, bu farklı bir problem.
JacquesB


Yanıtlar:


62

Arkadaşınla yüzleşme eğilimindeyim çünkü çoğu zaman, birim testleri yanlış şeyleri deniyor .

Birim testleri doğal olarak kötü değildir. Ancak genellikle girdi / çıktı akışı yerine uygulama ayrıntılarını test ederler. Bu olduğunda, tamamen anlamsız testler yaparsınız. Benim kendi kuralm, iyi bir birim testinin size bir şeyi kırdığınızı söylemesidir; Kötü bir birim testi sadece bir şeyi değiştirdiğinizi söyler.

Başımın üstünden bir örnek, birkaç yıl önce WordPress'e sıkışmış bir test. Test edilen işlevsellik, birbirini çağıran filtreler etrafında döndürüldü ve testler, geri aramaların doğru sırada alınacağını doğruladı. Ancak, (a) geri aramaların beklenen sırada çağrıldığını doğrulamak için zinciri çalıştırmak yerine, testler (b) başlangıçta maruz kalmaması gereken bazı içsel durumları okumaya odaklandı. İç kısımları değiştirin ve (b) kırmızı olur; oysa (a) sadece içsel değişiklikler yapıldığı takdirde beklenen sonucu kırarsa kırmızıya döner. (b) bence açıkça anlamsız bir sınavdı.

Dış dünyaya birkaç yöntem gösteren bir sınıfınız varsa, benim görüşüme göre test edilecek doğru şey sadece ikinci yöntemlerdir . İç mantığı da test ederseniz, iç mantığı dış dünyaya maruz bırakarak, karmaşık test yöntemlerini kullanarak veya herhangi bir şeyi değiştirmek istediğinizde kaçınılmaz olarak kıran birim testlerin bir likitine sahip olabilirsiniz.

Tüm bunların söylediği gibi, arkadaşınızın önerdiğiniz gibi kendi başına birim testleri konusunda kritik olup olmadığına şaşırdım. Aksine, pragmatik olduğunu toplamak isterdim. Yani yazılan birim testlerinin uygulamada çoğunlukla anlamsız olduğunu gözlemledi. Alıntı: "ünite testleri elden geçirilmek yerine yorumlanma eğiliminde". Bana göre orada gizli bir mesaj var - yeniden çalışmaya ihtiyaç duyuyorlarsa onu emmek eğilimindedirler. Varsayılırsa, ikinci teklif şöyledir: geliştiriciler yanlış anlaşılması zor olan kod yazarken daha az zaman harcarlardı - yani entegrasyon testleri.

Dolayısıyla, birinin daha iyi ya da daha kötü olmasıyla ilgili değil. Sadece birinin yanlış anlaşılması çok daha kolay ve uygulamada gerçekten çok yanlış.


13
Bu, bu, bunun yüzlerce katı. Bu, test odaklı geliştirme hakkında harika bir şey. Öncelikle testler yazmak, uygulamanızın ayrıntılarını test etmeyen, ancak uygulamaya çalıştığınız davranışları test eden testler yazmanıza yardımcı olacaktır.
wirrbel

9
Kırılgan birim testlerinin, birim testlerin doğal bir özelliği olmadığını, bunun yerine hangi birim testlerin yapıldığını yanlış anlamak yerine bence. Burada ihtiyacımız olan şey geliştiriciler için daha iyi bir eğitim. Test uygulama ayrıntılarını birime verirseniz, yanlış yaparsınız . Özel yöntemleri "test etmek için" açıklarsanız, yanlış yaparsınız . Her zaman uygulama arayüzünden daha az değişmesi gereken genel arayüzü ve davranışı test edin!
Andres F.

2
@DocBrown: Gerçekten de değil. Demek istediğim, OP'nin meslektaşının çoğu durumda - veya en azından birim test takıntılı firmalarda karşılaştığım tüm durumlarda - doğru olması yanlış olması çok yanlış.
Denis de Bernardy

3
@DisisdeBernardy: benim açımdan: yazdığınız her şey kesinlikle pratikten gelen bilgelikle kesin olarak doğrudur, ancak meslektaşımla olan OPs davası için ne anlama geldiğine dair bir sonuca varmıyorum. daha iyi bir alternatif ".
Doktor Brown,

5
Doc Brown'a şiddetle katılıyorum. Temel olarak, konumunuz, birim testlerinin iyi olduğu görülüyor, ancak kötü yazıldığında, bir güçlük haline geliyorlar. Bu nedenle, OP'nin meslektaşı ile hiç bir şekilde aynı fikirde değilsiniz, sadece onların yararlılıklarını iddia etmeden önce birim testleri yazdığınızdan emin olmalısınız. Bence cevabınız çok kafa karıştırıcı çünkü ilk cümle durum göründüğü zaman OP'nin meslektaşıyla aynı fikirde olduğunuzu belirtiyor. Genel olarak ünite testlerine karşı bir dava değil, daha kötü yazılmış ünite testleri hakkında bir rant gibi görünüyor (pratikte bir sorun, kabul ediyorum).
Vincent Savard,

38

Büyük kod değişiklikleri gerçekleştiğinde, birim testleri yeniden çalışmaktan ziyade yorumlanma eğilimindedir.

Disiplinsiz bir sürü kovboy kodlayıcıyla, tüm testlerin yorumlanmasında "yeşil" olduğunu gösteren tüm testlerin yapıldığını düşünen: tabii ki. Yeniden işleme birimi testleri, ilk elden yazdıkları kadar disiplini alır, bu yüzden üzerinde çalışmanız gereken takımınızın "bitmiş tanımı" dır.

Daha küçük kapsamlı testleri daha az / hiç önemli olmayan kullanım durumlarını kapsayan entegrasyon testlerinde zaman harcanması daha iyidir.

Bu ne tamamen yanlış ne de tamamen doğru. Yararlı entegrasyon testleri yazma çabası ne tür bir yazılım yazdığınıza bağlıdır. Entegrasyon testlerinin neredeyse birim testler kadar kolay yazılabildiği bir yazılımınız varsa, hala hızlı çalışırlar ve size kodunuzun iyi bir şekilde verilmesini sağlarlarsa meslektaşınızın bir noktası vardır. Fakat gördüğüm birçok sistem için bu üç noktanın entegrasyon testleriyle kolayca yapılamayacağını gördüm, bu yüzden birim testlerini yapmak için çaba göstermelisiniz.


Bunu tartışırken hissettiğim şey buydu. Tam ve ilgili entegrasyon testlerinin bir kullanım durumu için yazılabileceğini varsayarsak, birim testi bir tartışma noktası olacak gibi görünüyor. (Şimdi bunu yazdığım halde, beklenmeyen gelecekteki vakaları düşünüyorum - arka uçlarımız başka bir uygulama için web servisine çevrilmiş gibi).
Jeff Levine

+1 "Yaptığınız tanım üzerinde çalışmak zorundasınız". İyi dedi!
Andres F.

14

Meslektaşımın argümanlarını kabul ettiğimi bilmiyorum.

  1. Ünite testleri açıklanırsa, bunun nedeni birisinin tembel olması. Bu, ünite testlerinin hatası değil. Ve tembel bir mazeret olarak kullanmaya başlarsanız, biraz çaba gerektiren hemen hemen her uygulamaya karşı tartışabilirsiniz.
  2. Doğru yapıyorsanız, birim testlerinin uzun sürmesi gerekmez. Daha önemli bir iş yapmanı engellemiyorlar. Bozuk kodun düzeltilmesinin her şeyden daha önemli olduğu konusunda hepimiz hemfikiriz, bir birim testi oldukça önemlidir. Mesaj koşullarını test etmenin kolay bir yolu. Onsuz, koşul sonrası garantileri yerine getirdiğinizi nereden biliyorsunuz? Ve eğer yapmadıysanız, kodunuz bozulur.

Birim testlerine karşı daha zorlayıcı başka argümanlar var. Tam olarak onlara karşı değil. DHH'nın Test kaynaklı tasarım hasarı ile başlayın . O eğlenceli bir yazar, o yüzden oku. Ondan ne aldım:

Ünite testlerinizi gerçekleştirmek için büyük tasarım değişiklikleri yaparsanız, projenizdeki diğer hedefleri engelleyebilir. Mümkünse, hangi yaklaşımı takip etmenin daha kolay olduğunu tarafsız bir kişiye sorun. Test edilebilir kodunuzun anlaşılması zorsa, birim testinden elde ettiğiniz tüm faydaları kaybedebilirsiniz. Çok fazla soyutlamanın bilişsel yükü sizi yavaşlatır ve sızdıran hataları kolaylaştırır. İndirme.

Farklı ve felsefi olmak istiyorsanız, birçok harika kaynak var:


Bu makale için +1, OP'lerin vakasına burada yazdıklarımızdan daha iyi bir cevap olabilir-
Doc Brown

Tembellik için bir mazeret olmak üzere puan 1 için +1. Bunun ne kadar sinir bozucu olduğunu yeterince vurgulayamıyorum. Ben orada oldum. Son zamanlarda aslında.
Greg Burghardt,

3
Sebep 1, birim testlerinin hatası değil, yine de birim testlerine karşı bir neden.
user253751

DHH'nin makalesini okuduktan sonra, Kent Beck ve Martin Fowler ile konuştuğu videolara baktığınızdan emin olun. Bu tartışmalarda biraz daha da geliştirdi.
Jules

6

Büyük kod değişiklikleri gerçekleştiğinde (yeni POJO kümesi, büyük uygulama yeniden düzenlemesi vb.), Birim testleri elden geçirilmek yerine yorumlanma eğilimindedir.

Yapma bunu. Bunu yapan birini bulursanız, onları öldürün ve ürememelerini sağlayın, çünkü çocukları bu kusurlu geni devralabilir. CSI televizyon programlarını izlemekten gördüğüm gibi, her yerde çok sayıda yanıltıcı DNA örneği yaymak. Bu şekilde, olay yeri olayını o kadar çok kirletiyorsunuz ki, DNA testinin pahalı ve zaman alıcı niteliği göz önüne alındığında, bunu size bağlama ihtimalleri astronomik olarak düşüktür.


4

ünite testleri elden geçirilmek yerine yorumlanma eğilimindedir.

Hangi noktada kod inceleme işlemi "birim testlerini düzeltin" diyor ve bu artık bir sorun değil :-) Eğer kod inceleme süreciniz gönderilen kodda bu tür ana kusurları yakalamıyorsa, o zaman sorun budur.


3

Büyük kod değişiklikleri gerçekleştiğinde (yeni POJO kümesi, büyük uygulama yeniden düzenlemesi vb.), Birim testleri elden geçirilmek yerine yorumlanma eğilimindedir.

Her zaman yeniden düzenlemeyi ve işlev değişikliğini ayrı tutmaya çalışıyorum. İkisini de yapmam gerektiğinde, genellikle önce yeniden düzenlemeyi taahhüt ederim.

İşlevsellik değiştirmeden kod yeniden aktive edildiğinde mevcut birim testlerinin yeniden aktive etmenin yanlışlıkla işlevselliği bozmadığından emin olması gerekir. Bu yüzden böyle bir taahhüt için birim testlerini devre dışı bırakmayı ya da kaldırmayı büyük bir uyarı işareti olarak kabul ediyorum. Bunu yapan herhangi bir geliştiriciye, kod gözden geçirilirken yapmamaları söylenmelidir.

İşlevselliği değiştirmeyen değişikliklerin hala hatalı birim testleri nedeniyle birim testlerinin başarısız olmasına neden olması mümkündür. Değiştirdiğiniz kodu anlıyorsanız, bu tür birim sınama hatalarının nedeni genellikle hemen açık ve düzeltilmesi kolaydır.

Örneğin, bir işlev üç argüman alıyorsa, işlevin ilk iki argümanı arasındaki etkileşimi kapsayan bir ünite testi, üçüncü argüman için geçerli bir değer sağlamaya özen göstermemiş olabilir. Birim testindeki bu hata, test edilen kodun yeniden düzenlenmesi sonucu ortaya çıkabilir, ancak kodun ne yapması gerektiğini ve birim testinin ne test ettiğini anlarsanız düzeltmesi kolaydır.

Mevcut işlevselliği değiştirirken, bazı ünite testlerini de değiştirmek genellikle gerekli olacaktır. Bu durumda ünite testleri, kodunuzun işlevselliği amaçlandığı şekilde değiştirmesini ve istenmeyen yan etkileri olmamasını sağlar.

Hataları düzeltirken veya yeni işlevler eklerken, genellikle daha fazla birim testi eklemek gerekir. Bunlar için önce birim testlerini yapmak ve daha sonra hataları düzeltmek veya yeni işlevler uygulamak yardımcı olabilir. Bu, yeni birim testlerinin eski kodla geçmediğini, ancak yeni kodla geçmediğini doğrulamayı kolaylaştırır. Bu yaklaşım tamamen dezavantajsız olsa da, aynı zamanda hem yeni birim testlerini hem de kod güncellemelerini aynı anda gerçekleştirme lehine argümanlar var.

Kullanım kapsamını kapsayan entegrasyon testlerinde zaman harcanması daha küçük kapsamlı testleri daha az / hiç önemli yapmaz.

Bunun için bazı gerçekler var. Yazılım yığınının alt katmanlarını kapsama alabilirseniz, yazılım yığınının yüksek katmanlarını hedefleyen testlerle kodunuzu yeniden test ederken testleriniz daha yararlı olabilir.

Bununla birlikte, bir birim testi ve bir entegrasyon testi arasındaki kesin ayrım konusunda bir anlaşma bulacağınızı sanmıyorum. Ve bir geliştiricinin bir birim testini, bir diğerini de bir entegrasyon testini çağırdığı, yararlı bir test durumu olduğu konusunda hemfikir oldukları bir test durumunuz varsa endişelenmem.


3

Entegrasyon testleri, sistemin her zaman iş değeri olan gerektiği gibi davranıp davranmadığını kontrol etmek için yapılır. Birim testleri her zaman bunu yapmaz. Birim testleri, örneğin ölü kodu test ediyor olabilir.

Size bilgi vermeyen herhangi bir testin israf olduğunu söyleyen bir test felsefesi var. Bir kod parçası üzerinde çalışılmadığında, birim testleri her zaman (veya neredeyse her zaman) yeşil olur, size çok az bilgi verir veya hiç bilgi vermez.

Her test yöntemi eksik olacaktır. Bazı metrikler tarafından% 100 kapsama elde etseniz bile, hala neredeyse tüm olası girdi verileri kümesinden geçmiyorsunuz. Bu nedenle, birim testlerinin sihir olduğunu düşünmeyin.

Sıklıkla birim testleri yaptırmanın kodunuzu iyileştirdiği iddiasını gördüm. Bana göre, birim testlerinin koda getirdiği gelişmeler, kodlarını küçük, iyi faktörlü parçalara bölmeye alışık olmayan insanları zorlamakta. Normalde kodunuzu küçük, iyi faktörlü parçalar halinde tasarlamaya alışırsanız, sizi daha fazla zorlamanız için birim testlerine ihtiyacınız olmadığını görebilirsiniz.

Ünite testinin ne kadar yoğun olduğuna ve programınızın ne kadar büyük olduğuna bağlı olarak, çok fazla ünite testi yapmanız gerekebilir. Öyleyse, büyük değişiklikler zorlaşır. Büyük bir değişiklik birçok başarısız birim testine neden oluyorsa, değişikliği yapmayı reddedebilir, çok sayıda testi düzeltmek için çok çalışabilir veya testleri çöpe atabilirsiniz. Seçimlerden hiçbiri ideal değil.

Birim testleri araç kutusundaki bir araçtır. Size hizmet etmek için oradalar, tam tersi değil. En azından koyduğun kadarını aldığından emin ol.


3

Birim testi kesinlikle bazı destekçilerin iddia ettikleri bir gümüş kurşun değildir. Ancak genel olarak çok olumlu bir maliyet / fayda oranına sahiptirler. Kodunuzu "daha iyi", belki daha modüler yapmazlar. “daha ​​iyi”, “test edilebilirlik” in ima ettiğinden çok daha fazla faktöre sahiptir. Ancak, düşündüğünüz tüm durumlarda ve kullanımlarda işe yarayacağına ve böceklerin çoğunu (muhtemelen daha önemsiz olanlar) ortadan kaldıracağına dair güvence verecekler.

Ünite testlerinin en büyük yararı, kodunuzu daha esnek ve değişime dayanıklı hale getirmeleridir. Yeniden canlandırabilir veya özellikler ekleyebilir ve hiçbir şeyi bozmadığınızdan emin olabilirsiniz. Bu tek başına onları çoğu proje için değerli kılar.

Arkadaşınızın yaptığı noktalara değinmek:

  1. POJO eklemek, birim testlerinizi ihlal ederse, muhtemelen çok kötü bir şekilde yazılmıştır. POJO'lar genellikle sizin alanınız hakkında konuşmak için kullandığınız dildir ve çözmekte olduğunuz problemler, onları değiştirmek açıkça tüm işletme mantığınız anlamına gelir ve muhtemelen sunum kodunun değişmesi gerekir. Programınızın bu kısımlarının değişmemesi için neyin güvence vereceğini bekleyemezsiniz ...

  2. Ünite testlerinin kötü olduğundan şikayet etmek, çünkü insanlar bunları yorumluyor, insanlar emniyet kemeri taktıklarından şikayet ediyor gibi çünkü insanlar onları giymiyor. Eğer biri test kodunu yorumlarsa ve bir şeyi kırarsa, patronuyla çok ciddi ve nahoş bir sohbete son vermesi gerekir ...

  3. Entegrasyon testleri, birim testlerinden çok daha üstündür. soru yok. özellikle bir ürünü test ediyorsanız. Ancak, birim testinin size sağladığı aynı değeri, kapsamı ve doğruluğunu sağlayacak olan iyi ve kapsamlı entegrasyon testleri yazmak inanılmaz derecede zor.


2

Birim testlerine karşı sadece bir argüman düşünebilirim ve oldukça zayıf.

Birim testleri, daha sonraki bir aşamada kodları değiştirdiğinizde veya değiştirdiğinizde değerlerinin çoğunu gösterir. Özellik eklemek ve hiçbir şeyi bozmadığınızdan emin olmak için gereken sürede büyük bir azalma görüyorsunuz.

Bununla birlikte: Ancak, ilk başta testlerin yazılması zamanında (küçük) bir maliyet söz konusudur.

Bu nedenle: Eğer bir proje yeterince kısaysa ve devam eden bakım / güncelleme gerektirmiyorsa, test yazma maliyetinin faydalarından ağır basması mümkündür.


Sorulan soruyu ciddiyetle cevaplamaya çalışmak için +1.
RubberDuck

2
Birim testin maliyeti kesin olarak küçük değildir. İyi birim testleri genellikle yazmakta olduklarından daha fazla zaman alır. Yararları çoğu zaman maliyeti aşmaktadır.
AK_

1
sadece teoride - yeniden kırıldığınızda, neredeyse her zaman çok ayrıntılı olduklarından ünite testlerini güncellemek için büyük bir maliyete sahip olursunuz. İyi bir entegrasyon test odasına sahip olmaktan bahsediyor olsaydın haklıydın.
gbjbaanb

Eğer bir proje yeterince kısaysa ve devam eden bakım / güncelleme gerektirmiyorsa - eski sistemlerin çoğu testler olmadan kısa bir proje olarak başlamış - ve testsiz yetiştirilen sistemi sürdürmek için daha fazla geliştirici işe almakla sonuçlanmış
Fabio
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.