Ünite testleri neden kötü görünüyor?


93

Bazı kuruluşlarda, görünüşte, yazılım sürüm sürecinin bir parçası birim testi kullanmaktır, ancak herhangi bir zamanda tüm birim testleri geçmelidir. Örneğin, yeşil renkte geçen tüm birim testlerini gösteren bir ekran olabilir - ki bunun iyi olması gerekiyor.

Şahsen, aşağıdaki nedenlerden dolayı olması gerektiği gibi olmadığını düşünüyorum:

  1. Kodun mükemmel olması gerektiği ve hiçbir hata olmaması gerektiği fikrini ortaya koyuyor - gerçek dünyada her boyutta bir program için kesinlikle mümkün değil.

  2. Başarısız olacak ünite testlerini düşünmek belirsizdir. Ya da kesinlikle düzeltmek zor olacak birim testleri ile gelip.

  3. Herhangi bir zamanda tüm ünite testleri geçerse, o zaman herhangi bir zamanda yazılımın durumunun büyük bir resmi yoktur. Yol haritası / hedefi yok.

  4. Uygulamadan önce ünite testleri yazıyor.

Başarısız ünite testlerine sahip yazılımı piyasaya sürmenin bile fena olmasının gerekmediğini bile söyleyebilirim. En azından o zaman yazılımın bazı yönlerinin sınırlamaları olduğunu biliyorsunuzdur.

Burada bir şey mi eksik? Kuruluşlar neden tüm birim testlerinin geçmesini bekliyor? Bu rüya dünyasında yaşamak değil mi? Ve aslında gerçek bir kod anlayışı caydırmaz mı?


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
maple_shaft

Yanıtlar:


270

Bu soru IMHO'ya çeşitli yanlış anlamalar içeriyor, ancak asıl konuya odaklanmak istediğim, yerel kalkınma dalları, ana hatlar, evreleme ya da serbest bırakma dalları arasında ayrım yapmaması.

Yerel bir dev dalında, neredeyse herhangi bir zamanda bazı başarısız ünite testlerinin yapılması muhtemeldir. Bagajda, sadece bir dereceye kadar kabul edilebilir, ancak asap işleri düzeltmek için zaten güçlü bir gösterge. Bagajdaki başarısız ünite testlerinin ekibin geri kalanını rahatsız edebileceğini unutmayın, çünkü herkesin son değişikliklerinin başarısızlığa neden olup olmadığını kontrol etmelerini ister.

Bir evreleme veya serbest bırakma dalında, başarısız testler "kırmızı alarm" dır ve bazı değişikliklerde, bagajdan serbest bırakma dalına birleştirildiğinde tamamen yanlış bir şey olduğunu gösterir.

Başarısız ünite testlerine sahip yazılımı piyasaya sürmenin bile fena olmasının gerekmediğini bile söyleyebilirim.

Belli bir ciddiyet altında bilinen bazı hataları olan yazılımı serbest bırakmak mutlaka fena değil. Bununla birlikte, bilinen bu hatalar, başarısız ünite testine neden olmamalıdır. Aksi halde, her birim test çalışmasından sonra, 20 başarısız birim testine bakmak ve başarısızlığın kabul edilebilir bir test olup olmadığını tek tek kontrol etmek gerekir. Bu, hantal, hataya açık hale gelir ve birim testlerinin otomasyon yönünün büyük bir bölümünü atar.

Gerçekten kabul edilebilir ve bilinen hatalar için testleriniz varsa, birim test aracınızın devre dışı bırakma / yoksay özelliğini kullanın (böylece varsayılan olarak değil, yalnızca istek üzerine çalıştırılırsınız). Ek olarak, sorun izleyicinize düşük öncelikli bir bilet ekleyin, böylece sorun unutulmaz.


18
Bence asıl cevap bu. OP, bir sürüm sunucusu gibi görünen "sürüm süreci" ve "bazı ekranlar [test sonuçlarını gösterir]" den bahseder. Serbest bırakma gelişme ile aynı değildir (üretimde gelişmeyin!); dev testlerinde başarısız olmaları iyi, onlar TODO'lar gibiler; derleme sunucusuna basıldığında hepsi yeşil (DONE) olmalıdır.
Warbo

7
En yüksek oylanandan çok daha iyi bir cevap. OP'nin bazı ideal dünya durumları hakkında onlara ders vermeden nereden geldiğinin anlaşıldığını gösterir, bilinen hataların olasılığını kabul eder (bunun için tüm yol haritasının bazı nadir köşe durumlarını düzeltmek için bırakılmadığı) ve birim testlerinin yalnızca kesin olarak yapılması gerektiğini açıklar. serbest bırakma dalında / işleminde yeşil olmalıdır.
Sebastiaan van den Broek

5
@SebastiaanvandenBroek: Olumlu cevabınız için teşekkürler. Bunu açıkça belirtmek için: IMHO başarısız ünite testleri bagajda bile ender görülmeli, çünkü bu tür sıkıntılara neden olmak sık sık başarısızlığa yol açan değişikliği yapanları değil tüm takımı rahatsız edecektir.
Doc Brown

4
Bence buradaki problem, tüm otomatik testlerin birim testleri olduğunu düşünüyorum. Pek çok test çerçevesi, başarısız olması beklenen testleri (genellikle XFAIL olarak adlandırılır) işaretleme özelliğini içerir. (Bu, hata sonucu gerektiren bir testten farklıdır. XFAIL testleri ideal olarak başarılı olur, ancak yapmaz.) Test paketi hala bu başarısızlıkla geçer. En yaygın kullanım durumu, yalnızca bazı platformlarda başarısız olan şeylerdir (ve bunlarda yalnızca XFAIL'dir), ancak şu anda düzeltmek için çok fazla çalışma gerektiren bir şeyi izlemek için özelliği kullanmak da mantıklıdır. Ancak bu tür testler genellikle birim testleri değildir.
Kevin Cathcart

1
+1, bu cümleyi ekleyen (koyu) hafif bir ekleme önermekle birlikte: "Bu hantal, hataya açık, insanların test paketindeki başarısızlıkları gürültü olarak görmemesine neden oluyor ve birim testlerinin otomasyonunun büyük bir bölümünü atıyor .
mtraceur

228

... yeşil renkte geçen tüm testler - bunun iyi olması gerekiyor.

O ise iyi. Bu konuda "olması gereken" yok.

Kodun mükemmel olması gerektiği ve hiçbir hata olmaması gerektiği fikrini ortaya koyuyor - gerçek dünyada her boyutta bir program için kesinlikle mümkün değil.

Hayır. Kod, bu noktaya kadar test edebileceğiniz kanıtıdır. Testlerin her durumu kapsaması tamamen mümkündür. Eğer öyleyse, herhangi bir hata nihayetinde hata raporlarında ortaya çıkacaktır ve sorunları yeniden üretmek için [başarısız] testleri yazacak ve ardından testleri geçecek şekilde uygulamayı düzelteceksiniz.

Başarısız olacak ünite testlerini düşünmek belirsizdir.

Başarısız veya olumsuz testler, başvurunuzun kabul edeceği ve kabul etmeyeceği konusunda kesin sınırlar koyar. Bildiğim çoğu program 30 Şubat’ın "tarihine" itiraz edecek. Ayrıca Geliştiriciler, bizim yaratıcılığımız türler, "bebeklerini" kırmak istemiyorlar. Sonuç olarak "mutlu yol" vakalarına odaklanma, çoğu zaman kırılan kırılgan uygulamalara yol açmaktadır.

Geliştirici ve Test Cihazının zihniyetini karşılaştırmak için:

  • Bir Geliştirici, kodun istediği şeyi yaptığı anda durur.
  • Artık bir Test Cihazı, kodu kıramadığı zaman durur.

Bunlar kökten farklı bakış açıları ve birçok Geliştiricinin uzlaştırması zor olanlardan biri.

Ya da kesinlikle düzeltmek zor olacak birim testleri ile gelip.

Kendin için çalışmak için testler yazmıyorsun. Kodunuzun yapılması gerekeni yaptığını ve daha da önemlisi, iç uygulamasını değiştirdikten sonra yapılması gerekenleri yapmaya devam ettiğinden emin olmak için testler yazıyorsunuz.

  • Hata ayıklama, kodun bugün yapmak istediğiniz şeyi yaptığını kanıtlar .
  • Testler kodu olduğunu "kanıtlamak" hala siz istediğiniz onu yapar zamanla .

Herhangi bir zamanda tüm ünite testleri geçerse, o zaman herhangi bir zamanda yazılımın durumunun büyük bir resmi yoktur. Yol haritası / hedefi yok.

Yalnızca "resim" testi size, test edildiği sırada "çalıştığı" kodunun bir anlık görüntüsünü verir. Bundan sonra nasıl geliştiğini farklı bir hikaye.

Uygulamadan önce ünite testleri yazıyor.

Tam olarak yapman gereken şey bu. Başarısız olan bir sınama yazın (çünkü test ettiği yöntem henüz uygulanmadı), ardından yöntemin çalışmasını sağlamak için yöntem kodunu ve dolayısıyla test geçişini yazın. Bu hemen hemen Test Odaklı Gelişmenin en önemli noktası.

Başarısız ünite testlerine sahip yazılımı piyasaya sürmenin bile fena olmasının gerekmediğini bile söyleyebilirim. En azından o zaman yazılımın bazı yönlerinin sınırlamaları olduğunu biliyorsunuzdur.

Bozuk testlerle kodu serbest bırakmak , işlevselliğinin bir kısmının artık eskisi gibi çalışmadığı anlamına gelir . Bu, kasıtlı bir davranış olabilir, çünkü bir hatayı düzelttiniz veya bir özelliği geliştirdiniz (ancak testten önce başarısız olmuş, daha sonra düzeltmeyi / geliştirmeyi kodlamış, testin çalışmasını sağlayan kod değiştirmiş olmalısınız). Daha da önemlisi: Hepimiz İnsanız ve hata yapıyoruz. Kodu kırarsanız, testleri yıkmanız ve bu bozuk testin alarm zillerini çalması gerekir.

Bu rüya dünyasında yaşamak değil mi?

Bir şey olsa bile, bu yaşıyor Gerçek Dünya Geliştiriciler, her şeyi bilen, ne de infallable ne olduğunu biz kabul etmekle, bunu hata yaparlar ve biz gerektiğini güvenlik ağı bizi yakalamak için eğer ve ne zaman yapmak pisliği!
Testleri girin.

Ve aslında gerçek bir kod anlayışı caydırmaz mı?

Belki. Bunun için testler yazmak için bir şeyin uygulanmasını anlamanız gerekmez (bu onların amacının bir parçası). Testler, uygulamanın davranışını ve sınırlarını tanımlar ve kasıtlı olarak değiştirmediğiniz sürece bunların aynı kalmasını sağlar.


7
@Tibos: Bir testi devre dışı bırakmak bir işlevi yorumlamak gibidir. Sürüm kontrolünüz var. Kullanın.
Kevin,

6
@Kevin 'Kullan' derken ne demek istediğini bilmiyorum. Bir testi 'atlandı' veya 'beklemede' veya test çalıştırıcımın kullandığı herhangi bir kural olarak işaretlerim ve bu atlama etiketini sürüm kontrolüne kabul ederim.
33'te dcorking

4
@dcorking: Ben kod dışında yorum yapmayın, silin. Daha sonra ihtiyacınız olduğuna karar verirseniz, sürüm kontrolünden geri yükleyin. Engelli bir test yapmak farklı değildir.
Kevin,

4
“Testlerin her durumu kapsamıyor olması tamamen mümkün.” Test edilen her önemsiz kod parçası için kesinlikle her vakanın ele alınmadığını söyleyeceğim .
corsiKa

6
@Tibos Ünite testinin savunucuları, başarısız testin yapılmasından kodun yazılmasına kadar geçen sürenin küçük olması gerektiğini söylemektedir (örneğin 20 dakika. Bazıları 30 saniye talep eder). Hemen kodu yazmak için vaktiniz yoksa, muhtemelen çok karmaşıktır. Karmaşık değilse, bırakılan özellik tekrar eklenirse, testi yeniden yazılabileceği için silin. Neden yorum yapmıyorsun? Özelliğin bir daha ekleneceğini bilmiyorsunuz , bu nedenle yorumlanan test (veya kod) sadece gürültü.
CJ Dennis

32

Ünite testleri neden kötü görünüyor?

Bunlar değil - teste dayalı gelişim başarısız testler kavramı üzerine kuruludur. Gelişimi teşvik etmek için birim testlerinin başarısız olması, hikaye geliştirmek için kabul testlerinin başarısızlığı ....

Kaçırdığın şey bağlam ; ünite testlerinde nerede hata yapılabilir?

Genel cevap, birim testlerinin sadece özel sanal alanlarda başarısız olmasına izin verilmesidir.

Temel fikir şudur: başarısız testlerin paylaşıldığı bir ortamda, üretim kodunda bir değişikliğin yeni bir hata getirip getirmediğini anlamak için ekstra çaba harcar. Sıfır ve sıfır olmayan arasındaki fark, N ile N arasındaki farktan daha kolay anlaşılır ve yönetilebilir

Ayrıca, paylaşılan kodu temiz tutmak, geliştiricilerin görevde kalabileceği anlamına gelir. Kodunuzu birleştirdiğimde, kaç testin başarısız olması gerektiği konusundaki anlayışımı kalibre etmek için çözdüğüm sorundan bağlamları değiştirmem gerekmez . Paylaşılan kod tüm testleri geçiyorsa, değişikliklerimde birleştirdiğimde ortaya çıkan herhangi bir hata kodum ile mevcut temiz taban çizgisi arasındaki etkileşimin bir parçası olmalıdır .

Benzer şekilde, yeni bir geliştirici, yeni bir geliştirici daha hızlı bir şekilde üretken olabilir, çünkü hangi başarısızlık testlerinin "kabul edilebilir" olduğunu bulmak için zaman harcamak gerekmez.

Daha kesin olmak gerekirse: disiplin, derleme sırasında yapılan testlerin geçmesi gerektiğidir.

En iyi söyleyebileceğim gibi, devre dışı bırakılmış testlerin yapılmasında yanlış olan hiçbir şey yoktur .

Örneğin, "sürekli entegrasyon" ortamında, yüksek bir kadansta kod paylaşıyor olacaksınız. Sık sık entegrasyon yapmak , değişikliklerin yayınlanmaya hazır olması gerektiği anlamına gelmez. Hazır olana kadar trafiğin kodun bölümlerine bırakılmasını önleyen karanlık dağıtım teknikleri çeşitleri vardır.

Aynı teknikler, başarısızlık testlerini de devre dışı bırakmak için kullanılabilir.

Bir noktadan yayınlanmaya çalıştığım egzersizlerden biri, birçok başarısız testle bir ürünün geliştirilmesiyle uğraşmaktı. Karşılaştığımız cevap, odadan geçmek, başarısız testlerden vazgeçip her birini belgelemekti . Bu, tüm etkin testlerin geçtiği bir noktaya hızla ulaşmamızı sağladı ve yönetim / hedef bağışçı / altın sahibi, bu noktaya ulaşmak için hangi işlemleri yaptığımızı görebildi ve temizleme ve yeni işlerle ilgili bilinçli kararlar alabildi.

Kısacası: İşi izleme için yapılmayan , çalışma grubuna bir sürü başarısızlık testi bırakmaktan başka teknikler de var .


Ben "Orada ... derdi hiçbir şey sahip yanlış başarısız testler şunlardır özürlü ".
CJ Dennis,

Bu değişiklik kesinlikle anlamını netleştiriyor. Teşekkür ederim.
VoiceOfUnreason

26

Çok güzel cevaplar var, ancak henüz iyi bir şekilde örtülü olmadığına inandığım başka bir açı daha eklemek istiyorum: Testlerin tam olarak anlamı budur.

Ünite testleri, kodunuzun hatasız olup olmadığını kontrol etmek için yoktur.

Bunun ana yanlış anlama olduğunu düşünüyorum. Bu onların rolü olsaydı, gerçekten her yerde başarısız testlerden geçmeyi beklerdiniz. Ama velakin,

Birim testleri, kodunuzun düşündüğünüzü yaptığını kontrol eder.

Aşırı durumlarda bu bilinen böcek olduğunu kontrol içerebilir değil sabit. Mesele kod kodunuz üzerinde kontrol sahibi olmak ve yanlışlıkla değişiklik yapmaktan kaçınmaktır. Bir değişiklik yaptığınızda, gayet iyi ve aslında bazı testleri bozması bekleniyor - kodun davranışını değiştiriyorsunuz. Taze kırılmış test şimdi neyin değiştiğini iyi bir iz. Bütün kırılmaların, değişiklikten ne istediğinizi uygun olduğunu kontrol edin. Eğer öyleyse, sadece testleri güncelleyin ve devam edin. Değilse - peki, yeni kodunuz kesinlikle hatalıdır, geri dönün ve göndermeden önce düzeltin!

Şimdi, yukarıdakilerin tümü yalnızca tüm testler yeşil olduğunda çalışır, güçlü bir pozitif sonuç verir: bu tam olarak kodun işleyişidir. Kırmızı testlerin o özelliği yok. “Bu kodun yapmadığı şey bu” nadiren faydalı bir bilgidir.

Kabul testleri aradığınız şey olabilir.

Kabul testi gibi bir şey var. Bir sonraki dönüm noktasını aramak için yapılması gereken bir takım testler yazabilirsiniz. Bunlar kırmızı olmalı, çünkü bunun için tasarlandılar. Ancak, birim testlerden çok farklı şeylerdir ve ne dediklerinin yerini alamazlar.


2
Bir zamanlar kütüphaneyi başka biriyle değiştirmek zorunda kaldım. Ünite testleri, tüm köşe kasalarının hala yeni kodla aynı şekilde ele alınmasını sağladı.
Thorbjørn Ravn Andersen

24

Kırık pencere sendromunun yazılım eşdeğeri olarak görüyorum .

Çalışma testleri bana kodun belirli bir kalitede olduğunu ve kod sahiplerinin bu konuyla ilgilendiğini söylemektedir.

Ne zaman kaliteyi önemsemelisiniz, bunun yerine hangi kaynak kod dalı / deposu üzerinde çalıştığınıza bağlıdır. Dev kodu, çalışmanın devam ettiğini gösteren kırılmış testler yapabilir (umarım!).

Canlı bir sistem için bir dalda / depoda yapılan kırık testler derhal alarm zillerini çalmalıdır. Testlerin başarısız olmasına devam etmesine izin verilirse veya kalıcı olarak "yoksay" olarak işaretlenmişlerse, numaralarının zamanla sürünmesini bekleyin. Bunlar düzenli olarak gözden geçirilmezse, emsal kırılmış testlerin bırakılmasının uygun olduğu kabul edilecektir.

Kırık testler, pek çok mağazada, kırılmış kodun bile işlenip işlenemeyeceği konusunda bir kısıtlamaya sahip olacak şekilde otoriter olarak görülmektedir .


9
Testler sistemin nasıl yapıldığını belgeliyorsa, mutlaka daima geçmelidir - eğer yapmazlarsa, değişmezlerin kırıldığı anlamına gelir. Ancak, bir sistemin olması gerektiği gibi bir belge oluştururlarsa , başarısız testler de kullanılabilir - birim test çerçeveniz onları "bilinen sorunlar" olarak işaretlemenin iyi bir yolunu desteklediği sürece ve bunları bir öğeyle ilişkilendirirseniz Sorun izleyicinizde. Her iki yaklaşımın da kendi yararları olduğunu düşünüyorum.
Luaan

1
@Luaan Evet, bu, tüm birim testlerinin eşit şekilde oluşturulduğunu varsaymaktadır. Yapı yöneticilerinin testleri ne kadar süreyle çalıştıklarına, ne kadar kırılgan olduklarına ve çeşitli diğer kriterlere bağlı olarak bazı özelliklerle dilimlemeleri ve parçalamaları nadir değildir.
Robbie Dee

Bu cevap benim kendi tecrübelerime göre çok güzel. Bazı insanlar bir grup başarısız testten yoksun kalmaya veya bazı noktalardaki en iyi uygulamaları kırmaya alışınca, birkaç ay geçsinler ve görmezden gelinen testlerin% 'sini çarpıcı bir şekilde artırarak kod kalitesini "kesmek" seviyesine bırakacaksınız . Ve herkesi sürece geri çağırmak çok zor olacak.
usr-local-ΕΨΗΕΛΩΝ

11

İşte temel mantıksal yanlışlık:

Tüm testler başarılı olduğunda iyi olursa, herhangi bir testin başarısız olması durumunda kötü olması gerekir.

Birim testler sayesinde, IS tüm testler geçtiklerinde iyi. Öyle AYRICA İYİ bir test başarısız olduğunda. İkisinin muhalefet olması gerekmez.

Başarısızlık testi, bir kullanıcıya ulaşmadan önce takımınızın yakaladığı bir problemdir. Bir hatayı yayınlanmadan düzeltmek için bir fırsat. Ve bu iyi bir şey.


İlginç düşünce hattı. Sorunun yanlış olduğunu daha çok görüyorum: "bir birim testinin başarısız olması iyi olduğu için tüm testlerin geçmesi kötü."
Doktor Brown

Son paragrafınız iyi bir nokta olsa da, problemin “tüm birim testlerinin geçmesi gereken herhangi bir zamanda” (kabul edilen cevabın belirttiği gibi) ve birim testlerinin noktasının yanlış anlaşılması gibi görünüyor.
18'de Dukeling

9

Phill W'ın cevabı harika. Değiştiremiyorum.

Bununla birlikte, karışıklığın bir parçası olabilecek başka bir kısma odaklanmak istiyorum.

Bazı kuruluşlarda, görünüşe göre, yazılım sürüm sürecinin bir parçası birim test kullanmaktır, ancak herhangi bir zamanda tüm birim testlerinin geçmesi gerekir

“herhangi bir zamanda” davanızı abartıyor. Önemli olan, başka bir değişiklik uygulamaya başlamadan önce , belirli bir değişiklik yapıldıktan sonra birim testlerinin geçmesidir . Bu, hangi değişikliğin bir hatanın ortaya çıkmasına neden olduğunu takip etmektir. Birim testler değişiklik 25 uygulandıktan sonra ancak değişiklik 26'yı uygulamadan önce başarısızlığa başladıysa , değişiklik 25'in hataya neden olduğunu biliyorsunuzdur.

Bir değişikliğin uygulanması sırasında , elbette, birim testleri başarısız olabilir; Tat, değişimin ne kadar büyük olduğuna bağlı. Küçük bir ince ayardan çok daha fazlası olan bir temel özelliği yeniden geliştiriyorsam, mantığımın yeni sürümünü uygulama işlemini bitirene kadar bir süre sonra testleri kıracağım.


Bu takım kurallarına göre çatışmalar yaratabilir. Aslında birkaç hafta önce bununla karşılaştım:

  • Her taahhüt / itme bir inşaa sebep olur. Derleme asla başarısız olmamalıdır (test yapılırsa veya herhangi bir test başarısız olursa, taahhüt veren geliştirici suçlanır).
  • Her geliştiricinin günün sonunda değişikliklerini (eksik olsa bile) zorlaması beklenir, böylece takım liderleri sabah kod incelemesini yapabilir.

Her iki kural da iyi olurdu. Ancak her iki kural birlikte çalışamaz. Tamamlanması birkaç gün süren büyük bir değişiklik yapmam durumunda, aynı anda her iki kurala da bağlı kalamam. Değişikliklerimi her gün yorumlayamazsam ve yalnızca her şey yapıldıktan sonra onlara yorum yapmadıysam; Bu sadece saçma bir iştir.

Bu senaryoda, buradaki sorun, birim testlerinin amacı yoktur; o da budur şirket gerçekçi olmayan beklentileri var . Keyfi kurallar tüm durumları kapsamaz ve kurallara uymama, bir kural başarısızlığı yerine geliştirici hatası olarak kabul edilir (benim durumumda olduğu gibi).


3
Bu tek yönlü olabilir çalışmak Devs taahhüt ve eksik ise temiz bir şekilde inşa etmek gerekmez dalları özelliği itmek şekilde, dallanma kullanmaktır, fakat temiz inşa gereken bir yapı, tetikler mi çekirdek dalına taahhüt.
Gwyn Evans

1
Eksik değişiklikleri zorlamak çok saçma, bunu yapmak için herhangi bir gerekçe göremiyorum. Değişiklik tamamlandığında neden kod incelemesi yapmıyorsunuz?
Callum Bradbury

Birincisi, sabit diskinin çalışmayı durdurması veya başka bir şekilde kaybolması durumunda, kodun yalnızca cihazın dizüstü bilgisayarında / iş istasyonunda olmamasını sağlamanın hızlı bir yolu - eğer çalışma ortasında olsa bile bir taahhüt politikası varsa sınırlı miktarda iş riski var.
Gwyn Evans

1
Özellik bayrakları, görünen paradoksu düzeltir.
RubberDuck

1
@Flater evet, mevcut mantığı da elden geçirmek için.
RubberDuck

6

Tüm ünite testlerini düzeltmezseniz, kimsenin kırılma testlerini düzeltmediği duruma hızlıca geçebilirsiniz.

  1. Birim testlerinin geçilmesi, kodun mükemmel olduğunu göstermediğinden yanlış mı

  2. Tasarım açısından da test edilmesi zor olan bir kod bulmak zor.

  3. Kod kapsamı orada yardımcı olabilir (her derde deva olmasa da). Ayrıca, birim testleri testin sadece bir yönüdür - siz de entegrasyon / kabul testleri istiyorsunuz.


6

Zaten iyi olan cevaplara birkaç nokta eklemek için ...

ancak herhangi bir zamanda tüm birim testlerinin geçmesi gerekir

Bu, bir serbest bırakma sürecinin anlaşılmadığını gösterir. Bir test hatası, TDD kapsamında henüz uygulanmayan planlı bir özelliği gösterebilir; veya gelecekteki bir sürüm için planlanan bir çözümü olan bilinen bir sorunu gösterebilir; veya basitçe, yönetimin bunu düzeltmek için yeterince önemli olmadığına karar verdiği bir şey olabilir, çünkü müşteriler farketmez. Tüm bu payların kilit noktası, yönetimin başarısızlıkla ilgili yargı kararı vermesidir.

Kodun mükemmel olması gerektiği ve hiçbir hata olmaması gerektiği fikrini ortaya koyuyor - gerçek dünyada her boyutta bir program için kesinlikle mümkün değil.

Diğer cevaplar testin sınırlarını kapsamıştır.

Neden böcekleri temizlemenin bir dezavantaj olduğunu düşündüğünü anlamıyorum. Kontrol ettiğiniz kodu (elinizden gelenin en iyisini yaparak) yapmak istemezseniz, neden yazılımda çalışıyorsunuz?

Herhangi bir zamanda tüm ünite testleri geçerse, o zaman herhangi bir zamanda yazılımın durumunun büyük bir resmi yoktur. Yol haritası / hedefi yok.

Neden bir yol haritası olmalı?

Ünite testleri başlangıçta işlevselliğin çalışıp çalışmadığını kontrol eder, ancak daha sonra (regresyon testleri olarak) yanlışlıkla herhangi bir şeyi bozmadığınızı kontrol edin. Mevcut birim testleri ile tüm özellikler için , hiçbir yol haritası yoktur . Her özelliğin çalıştığı bilinmektedir (test sınırları dahilinde). Bu kod bitmişse, yol haritası yoktur, çünkü üzerinde daha fazla çalışmaya gerek yoktur.

Profesyonel mühendisler olarak, altın kaplama tuzağından uzak durmamız gerekiyor. Hobileri, işe yarayan bir şeyle kenarlarından dolaşma zamanını boşa harcayabilirler. Profesyoneller olarak bir ürün teslim etmemiz gerekiyor. Bu, bir şeyi işe aldığımızı, çalıştığını doğruladığımızı ve bir sonraki işe geçeceğimizi gösterir.


6

Kodun mükemmel olması gerektiği ve hiçbir hata olmaması gerektiği fikrini ortaya koyuyor - gerçek dünyada her boyutta bir program için kesinlikle mümkün değil.

Doğru değil. neden imkansız olduğunu düşünüyorsun? burada çalıştığı program için örnek:

public class MyProgram {
  public boolean alwaysTrue() {
    return true;
  }

  @Test
  public void testAlwaysTrue() {
    assert(alwaysTrue() == true);
  }
}

Başarısız olacak ünite testlerini düşünmek belirsizdir. Ya da kesinlikle düzeltmek zor olacak birim testleri ile gelip.

Bu durumda, birim testi değil, karmaşıksa entegrasyon testi olabilir.

Herhangi bir zamanda tüm ünite testleri geçerse, o zaman herhangi bir zamanda yazılımın durumunun büyük bir resmi yoktur. Yol haritası / hedefi yok.

true, bir sebepten dolayı birim test denir , küçük bir kod birimini kontrol eder.

Uygulamadan önce ünite testleri yazıyor.

Geliştiriciler niyetyararlarını anlamadıkları takdirde herhangi bir test yazmayı zorlamakdoğası gereği (QA'dan gelmemişlerse)


“Geliştiriciler doğası gereği herhangi bir test yazmayı engelleyecektir” - bu tamamen saçmalık. TDD ve BDD'yi uygulayan geliştiricilerin tamamında çalışıyorum.
RubberDuck

@RubberDuck Söz konusu bir "gerçeğe" cevap vermeye çalıştım ve abartıyordum. Güncelleyeceğim
user7294900 23:18

Herhangi bir X ve Y için “Y'nin yararlarını anlamayanlarsa, Y, Y yapmaktan caydırılır.” Muhtemelen testleri yazmanın ve özellikle de bunu açıkça yapmanın yararlarını açıklamak daha mantıklı olacaktır.
18'de Dukeling

2
"herhangi bir boyutta bir program için imkansız", "hangi boyutta olursa olsun" tüm programlar anlamına gelmez, "önemli bir program (önemsiz bir uzunluğa sahip)" anlamına gelir "Buna karşı koyma denemeniz uygulanabilir değildir, çünkü ' t Önemli ve faydalı bir program.
Ben Voigt

@BenVoigt Cevap olarak "önemli bir program" vereceğimi sanmıyorum.
user7294900

4

Kodun mükemmel olması gerektiği ve hiçbir hata olmaması gerektiği fikrini teşvik eder.

Kesinlikle hayır. Testlerinizin başarısız olmaması gerektiği, daha fazla ve daha az olmayan bir şey olduğu fikrini destekler. Testlere sahip olmanın (hatta birçoğunun) "mükemmel" veya "hiç hata" hakkında bir şey söylediğini varsaymak bir yanlışlıktır. Testlerinizin ne kadar sığ veya derin olması gerektiğine karar vermek, iyi testler yazmanın önemli bir parçasıdır ve test kategorilerini ayrı ayrı ayırmamızın nedenidir ("birim" testleri, entegrasyon testleri, salatalık anlamında "senaryolar" vb.).

Başarısız olacak ünite testlerini düşünmek belirsizdir. Ya da kesinlikle düzeltmek zor olacak birim testleri ile gelip.

Teste dayalı gelişimde, her ünite testinin ilk önce, kodlamaya başlamadan önce başarısız olması zorunludur . Bu nedenle "kırmızı-yeşil döngüsü" (veya "kırmızı-yeşil-refaktör döngüsü") denir.

  • Testin başarısız olması durumunda, kodun gerçekten test tarafından test edilip edilmediğini bilmiyorsunuz. İkisi hiç ilişkili olmayabilir.
  • Kod değiştirerek tam olarak daha yeşil, hiçbir şey ve hiçbir şey az kırmızıdan testi dönüş yapmak, kendi kod (ihtiyacınız asla olabilir) çok daha fazla yapmak gerekiyordu ve ne değildir yapar oldukça emin olabiliriz.

Herhangi bir zamanda tüm ünite testleri geçerse, o zaman herhangi bir zamanda yazılımın durumunun büyük bir resmi yoktur. Yol haritası / hedefi yok.

Testler daha çok bir mikro amaçtır. Test odaklı geliştirmede, programcı önce bir test (tekil) yazacak ve daha sonra bazı kodları uygulamak için net bir amacı olacak; sonra bir sonraki test vb.

Testlerin işlevi kod yazılmadan önce tam olarak orada bulunmamaktır.

Doğru yapıldığında, bir dilde ve bu yaklaşıma çok uygun bir test kütüphanesiyle, bu aslında geliştirmeyi büyük ölçüde hızlandırabilir, çünkü hata mesajları (istisnalar / yığınlar) geliştiriciyi doğrudan iş yapması gereken yere yönlendirebilir. Sonraki.

Uygulamadan önce ünite testleri yazıyor.

Bu ifadenin nasıl doğru olacağını anlamıyorum. Test yazma ideal olarak uygulamanın bir parçası olmalıdır .

Burada bir şey mi eksik? Kuruluşlar neden tüm birim testlerinin geçmesini bekliyor?

Çünkü kuruluşlar, testlerin kodla alaka düzeyine sahip olmasını bekliyor. Başarılı olan testler yazmak, başvurunuzun bir bölümünü belgelemiş olduğunuz ve uygulamanın (test) söylediklerini yaptığını kanıtladığınız anlamına gelir. Daha fazla ve daha az değil.

Ayrıca, test yaptırmanın çok büyük bir kısmı "regresyon" dur. Güvenle yeni bir kod geliştirebilmek veya yeniden değerlendirebilmek istersiniz. Çok sayıda yeşil test yaptırmanız bunu yapmanızı sağlar.

Bu örgütselden psikolojik seviyeye kadar gider. Hatalarının yüksek olasılıkla testlerle yakalanacağını bilen bir geliştirici, çözmesi gereken problemlere akıllı ve cesur çözümler bulmakta çok daha özgür olacaktır. Öte yandan, testleri olmayan bir geliştirici, bir süre sonra (korkudan dolayı) durağan bir şekilde taşlayacaktır, çünkü uygulamanın geri kalanını kırarsa asla bilemez.

Bu rüya dünyasında yaşamak değil mi?

Hayır. Teste dayalı bir uygulama ile çalışmak saf bir zevktir - başka bir soruda tartışabileceğimiz herhangi bir nedenle ("daha fazla çaba" vb.) Konseptini beğenmiyorsanız.

Ve aslında gerçek bir kod anlayışı caydırmaz mı?

Kesinlikle hayır, neden olmasın?

Testleri asıl olarak, yazılımın asıl dokümanı olarak kullanan ve testin yanı sıra, yazılımın ana dokümantasyonu olarak kullanılan çok sayıda büyük açık kaynaklı proje buluyorsunuz. ayrıca uygulama / kütüphanenin kullanıcıları veya geliştiricileri için gerçek, çalışan, sözdizimsel olarak doğru örnekler de sunar. Bu genellikle muhteşem çalışır.

Açıkçası, kötü testler yazmak kötü. Ancak bunun testlerin işleviyle ilgisi yoktur.


3

(Orijinal yorumlarımdan)

Gerekli işlevsellik ve gelecekteki hedefler arasında bir fark var. Testler gerekli işlevsellik içindir: kesin, resmi, çalıştırılabilir ve yazılımın çalışmaması durumunda başarısız olurlar. Gelecekteki hedefler kesin veya resmi olmayabilir, her ne kadar çalıştırılabilir olsalar da, sorun / hata izleyiciler, belgeler, yorumlar vb. Gibi doğal dilde bırakılmaları daha iyi olur.

Bir alıştırma olarak, sorunuzdaki "birim testi" ifadesini "derleyici hatası" (veya derleyici yoksa "sözdizimi hatası") ile değiştirmeyi deneyin. Bir sürümün kullanılamaz olacağı için derleyici hataları olmaması gerektiği açıktır; Ancak derleyici hataları ve sözdizimi hataları, geliştiricinin makinesinde kod yazarken normal bir durumdur. Hatalar ancak bittiğinde kaybolur; ve tam olarak kodun basılması gerektiği zaman. Şimdi bu paragraftaki "derleyici hatasını" "birim testi" ile değiştirin :)


2

Otomatikleştirilmiş testlerin amacı, mümkün olan en kısa sürede bir şeyi ne zaman kırdığınızı söylemektir . İş akışı biraz şuna benziyor:

  1. Bir değişiklik yap
  2. Değişikliğinizi oluşturun ve test edin (ideal olarak otomatik)
  3. Testler başarısız olursa, daha önce işe yarayan bir şeyi kırdığınız anlamına gelir
  4. Testler başarılı olursa, yaptığınız değişikliğin yeni bir gerileme getirmediğinden emin olmalısınız (test kapsamına bağlı olarak)

Testleriniz zaten başarısız olduysa, 3. adım etkili şekilde çalışmaz - testler başarısız olur, ancak bunun araştırmadan bir şeyi kırıp kırmadığınız anlamına gelmez. Belki başarısızlık testlerinin sayısını sayabilirsiniz, ancak daha sonra bir değişiklik bir hatayı düzeltir ve diğerini kırabilir veya bir test farklı bir nedenden ötürü başarısız olabilir. Bu, bir şeylerin bozulup çözülmediğini bilmeden önce, tüm sorunlar çözülene veya her başarısız testin incelenmesine kadar bir süre beklemeniz gerektiği anlamına gelir.

Birim testlerinin yeni ortaya çıkan hataları olabildiğince erken bulma kabiliyeti, otomatik testlerle ilgili en değerli şeydir - bir kusur ne kadar uzun süre keşfedilirse giderilmesi o kadar pahalı olur.

Kodun mükemmel olması gerektiği ve hiçbir hata olmaması gerektiği fikrini ortaya
koymaktadır.

Sana hiçbir şey söyleme çalışmayan şeyler için testler - şeyler için birim testleri yazma yapmak işi veya düzeltmek üzere olduğunu. Yazılımınızın hatasız olduğu anlamına gelmez, bu, daha önce birim testleri yazdığınız hataların hiçbirinin tekrar geri gelmediği anlamına gelir.

Önde yazılan birim testlerini algılar

Sizin için işe yararsa, daha sonra testleri önceden yazın, geçene kadar ana / bagajınızda kontrol etmeyin.

Herhangi bir zamanda tüm ünite testleri geçerse, o zaman herhangi bir zamanda yazılımın durumunun büyük bir resmi yoktur. Yol haritası / hedefi yok.

Birim testleri bir yol haritası / hedef belirlemek için değildir, bunun yerine belki bir backlog kullanabilirsiniz? Tüm testleriniz başarılı olursa, "büyük resim" yazılımınızın bozulmadığıdır (test kapsamınız iyi ise). Aferin!


2

Var olan cevaplar kesinlikle iyidir, ancak sorudaki bu temeli yanlış algılamayı ele alan hiç kimseyi görmedim:

herhangi bir zamanda tüm birim testlerinin geçmesi gerekir

Hayır. En kesin olarak, bu doğru olmayacak. Yazılım geliştirirken, NCrunch genellikle kahverengi (yapı hatası) veya kırmızı (başarısız testi).

NCrunch'ın yeşil olması gerektiği yerde (geçen tüm testler) kaynak kontrol sunucusuna bir taahhüt vermeye hazır olduğumda, çünkü bu noktada diğerleri koduma bağımlı olabilir.

Bu aynı zamanda yeni testler oluşturma konusunu da beslemektedir: Testler, kodun mantığını ve davranışını kanıtlamalıdır. Sınır koşulları, arıza koşulları vb. Yeni testler yazarken, koddaki bu "sıcak noktaları" tanımlamaya çalışıyorum.

Ünite testleri, kodumun nasıl çağrılmasını beklediğimi - ön koşullar, beklenen çıktılar vb.

Bir değişiklikten sonra bir test kesilirse, kodun veya testin hatalı olup olmadığına karar vermem gerekir.


Bir yan not olarak, birim testi bazen Test Tahrikli Geliştirme ile el ele gider. TDD'nin ilkelerinden biri kırık testlerin sizin rehberleriniz olduğudur. Bir test başarısız olduğunda, testi geçmesi için kodu düzeltmeniz gerekir. İşte bu hafta başından itibaren somut bir örnek:

Arka plan : Geliştiricilerimiz tarafından Oracle sorgularını doğrulamak için kullanılan bir kütüphaneyi yazdım ve şimdi destekledim. Sorgunun bazı beklenen değerlerle eşleştiğini iddia eden testler yaptık; bu durum, durumu önemli kılan (Oracle'da değil) ve beklenen değeri tamamen eşleştikleri sürece geçersiz sorguları neşeyle onayladı.

Bunun yerine, kütüphanem Antlr ve Oracle 12c sözdizimini kullanarak sorguyu ayrıştırır ve ardından sözdizimi ağacının kendisinde çeşitli iddiaları tamamlar. Bunun gibi şeyler geçerlidir (ayrıştırma hatası oluşmaz), tüm parametreleri parametre koleksiyonu tarafından karşılanır, veri okuyucusu tarafından okunan beklenen tüm sütunlar sorguda bulunur, vb. Bunların hepsi kaymış öğelerdir. çeşitli zamanlarda üretim.

Mühendislerimden biri, Pazartesi günü bana hafta sonu boyunca başarısız olan (veya başarısız olması gerektiğinde başarılı olan) bir sorgu gönderdi. Kütüphanem sözdiziminin iyi olduğunu söyledi ancak sunucu çalıştırmayı denediğinde patladı. Sorguya baktığında, neden olduğu belliydi:

UPDATE my_table(
SET column_1 = 'MyValue'
WHERE id_column = 123;

Projeyi yükledim ve bu sorgunun geçerli olmaması gerektiğini iddia eden bir birim testi ekledim. Açıkçası, test başarısız oldu.

Ardından, başarısızlık testinde hata ayıkladım , istisna atmasını beklediğim yerde kodun üzerine çıktım ve Antlr'in önceki kodun beklediği şekilde değil, açık parede bir hata oluşturduğunu belirledim. Kodu değiştirdim, testin şimdi yeşil (geçen) olduğunu ve diğerlerinde işlem sırasında kırılmadığını, taahhüt edildiğini ve itildiğini doğruladım.

Bu belki 20 dakika sürdü ve bu süreçte kütüphaneyi önemli ölçüde geliştirdim, çünkü şimdi daha önce görmezden geldiği bir dizi hatayı destekledi. Kütüphane için birim testleri yaptırmasaydım, konuyu araştırmak ve düzeltmek saatler alabilirdi.


0

Önceki cevaplardan çıkmadığımı düşündüğüm bir nokta, iç testler ve dış testler arasında bir fark olduğudur (ve pek çok projenin ikisini ayırt edecek kadar dikkatli olmadığını düşünüyorum). Dahili bir test, bazı dahili bileşenlerin olması gerektiği gibi çalıştığını test eder; harici bir test, sistemin bir bütün olarak olması gerektiği gibi çalıştığını gösterir. Tabii ki, sistemde bir arızaya neden olmayan bileşenlerde arıza olması oldukça muhtemeldir (belki de sistemin kullanmadığı bir bileşen özelliği vardır, ya da belki de sistem, sistemin arızalarından kurtarır). bileşen). Sistem arızasıyla sonuçlanmayan bir bileşen arızası, salıverilmenizi durdurmamalıdır.

Çok fazla iç bileşen testi yaparak felce uğramış projeler gördüm. Bir performans geliştirmeyi her denediğinizde ve uyguladığınızda, onlarca testten kaçarsınız çünkü bileşenlerin davranışını sistemin dışından görünmez davranışını değiştirmeden değiştirirsiniz. Bu, bir bütün olarak projede çeviklik eksikliğine yol açar. Dış sistem testlerine yapılan yatırımın genellikle iç bileşen testlerine yapılan yatırımdan çok daha iyi bir kazanç sağlayacağına inanıyorum, özellikle de çok düşük seviyeli bileşenlerden bahsediyorsanız.

Başarısız ünite testlerinin gerçekten önemli olmadığını öne sürdüğünüzde, aklınızdaki şeyin bu olup olmadığını merak ediyorum. Belki de uygulamanın dışarıdan görülebilen davranışını doğrulayan testlere odaklanırken, birim testlerinin değerini değerlendirip değerinden daha fazla soruna neden olanları atmanız gerekir.


"Dış testler" olarak tanımladığınız şeyin başka yerlerde "entegrasyon" testleri olarak tanımlandığını düşünüyorum.
GalacticCowboy

Evet, fakat terminolojideki farklılıklar ile karşılaştım. Bazı insanlar için, entegrasyon testi konuşlandırılmış yazılım / donanım / ağ konfigürasyonu hakkındadır, oysa geliştirmekte olduğunuz bir yazılımın dış davranışından söz ediyorum.
Michael Kay

0

"ancak herhangi bir zamanda tüm birim testlerinin geçmesi gerekiyor"

Şirketinizdeki tutum buysa, bu bir problemdir. Bir CERTAIN zamanında, yani kodun bir sonraki ortama geçmeye hazır olduğunu bildirdiğimizde, tüm birim testleri geçmelidir. Ancak geliştirme sırasında, birçok birim testinin başarısız olmasını rutin olarak beklemeliyiz.

Hiçbir makul kişi, bir programcının ilk denemede çalışmalarını mükemmelleştirmesini beklemiyor. Makul bir şekilde beklediğimiz şey, bilinen bir sorun yaşanmadıkça üzerinde çalışmaya devam edeceğidir.

“Başarısız olacak ünite testlerini düşünmek, ya da kesinlikle düzeltilmesi zor olan ünite testleriyle gelmek bir fikirdir.” Kuruluşunuzdaki biri olası bir testten bahsetmemesi gerektiğini düşünüyorsa, başarısız olabileceği ve düzeltmek için daha fazla çalışmasına neden olabileceği için, bu kişi işleri için tamamen niteliksizdir. Bu feci bir tutum. "Ameliyat yaparken, kasıtlı olarak dikişlerin doğru olup olmadığını kontrol etmemizi ister misin?" Diyorlarsa; işlemi bitirme yavaşlatır "?

Ekip, kod üretilmeden önce hataları tanımlayan programcılara düşmanca davranıyorsa, bu ekibin tutumu ile ilgili gerçek bir sorun yaşarsınız. Yönetim, teslimatı yavaşlatan hataları tespit eden programcıları cezalandırırsa, olasılıklar şirketinizin iflasa yönelmiş olmasıdır.

Evet, bazen rasyonel insanların “Son tarihe yaklaşıyoruz, bu önemsiz bir sorundur ve şu anda kaynakları düzeltmek için harcayacağına değmez” der. Fakat bilmiyorsanız, bu kararı rasyonel olarak veremezsiniz. Bir hatalar listesini rahatça incelemek ve bunları düzeltmek için öncelikleri ve programları atamak rasyoneldir. Kasıtlı olarak kendinizi problemleri görmezden getirin, bu yüzden bu kararı vermek zorunda değilsiniz aptalca. Müşterinin bilmek istemediği için öğrenmeyeceğini mi düşünüyorsun?


-7

Bu, insanların mevcut inançlarını doğrulayan bilgileri aramaya meyilli olduğu belirli bir önyargı örneğidir .

Bunun bir ünlü örneği, 2,4,6 oyunda.

  • Kafamda üç sayıdan oluşan herhangi bir dizinin geçip geçmeyeceğine dair bir kuralım var.
  • 2,4,6 bir pas
  • Üç sayı kümesini listeleyebilirsiniz; bunlar başarılı veya başarısız olursa size söyleyeceğim.

Çoğu insan bir kural seçer, "1. ve 2. sayı arasındaki boşluk 2. ve 3. arasındaki boşlukla aynıdır" deyin.

Bazı numaraları test edecekler:

  • 4, 8, 12? Geçmek
  • 20, 40, 60? Geçmek
  • 2, 1004, 2006? Geçmek

"Evet, her gözlem benim hipotezimi doğruluyor, doğru olmalı." Diyorlar. Ve kurallarını bilmeceyi veren kişiye duyurun.

Ancak hiçbir zaman üç sayı grubuna tek bir 'başarısızlık' almadılar. Kural, gerçekte sahip oldukları tüm bilgiler için 'üç sayının sayı olması gerekir' olabilirdi.

Kural aslında sadece sayıların artan sırada olmasıdır. İnsanlar genellikle bu bilmeceyi ancak başarısızlık için test ediyorlarsa düzeltebilirler. Çoğu kişi, daha belirli bir kural seçerek ve yalnızca bu belirli kurala uyan numaraları test ederek yanlış anlar.

İnsanların neden onay önyargılarına düştükleri ve ünite testlerinin bir sorunun kanıtı olarak başarısız olduklarını görebileceklerine gelince, onay önyargılarını benden daha iyi açıklayabilen birçok psikolog var. kendilerini yanlış kanıtlamak için.


2
Soru ile ne ilgisi var? Birim başarısızlık testleri , tanım olarak bir sorunun kanıtıdır.
Frax

1
Sen kesinlikle birim testleri olabilir gerektiren bir arıza moduna girmek test edilen sistemi. Bu asla bir testin başarısız olduğunu görmekle aynı şey değil.
TDD'nin
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.