Test-ilk programlamanın dezavantajları nelerdir?


47

Bugünlerde tüm öfke. "Herkes" bunu tavsiye ediyor. Bu kendi içinde beni şüpheli kılıyor.

Teste ilk (teste dayalı) geliştirme yaparken bulduğunuz bazı dezavantajlar nelerdir? Bilgili pratisyenlerin kişisel deneyimlerini arıyorum - İnternetteki başka bir yerdeki yüzlerce wabanın varsayımsal müziklerini okuyabilirim.

TDD'den nefret etmek istediğim için değil, yazılım geliştirme sürecini geliştirmek benim işim olduğundan ve insanların karşılaştığı sorunlar hakkında ne kadar fazla şey öğrenebilirsek, süreci iyileştirme şansımız o kadar fazladır.

Yanıtlar:


41

Çok az var, ancak avantajlar , dezavantajlardan çok daha ağır basıyor.

Dik bir öğrenme eğrisi var.

Pek çok geliştirici, ilk günden itibaren test-ilk programlama ile verimli olmalarını bekliyor gibi görünmektedir. Ne yazık ki, daha önce olduğu gibi aynı hızda deneyim ve program kazanmak için çok zaman alır. Etrafından geçemezsin.

Daha açık olmak gerekirse, yanlış anlaşmak çok kolaydır. Çok kolay bir şekilde (çok iyi niyetlerle) yanlış şeyleri korumak veya test etmek zor olan bir sürü test yazabilirsiniz. Burada örnekler vermek zor - bu tür sorunlar çözmek için tecrübe edinirler. Endişeleri ayırma ve test edilebilirlik için tasarım yapma konusunda iyi hissetmeniz gerekir. Buradaki en iyi tavsiyem TDD'yi gerçekten iyi bilen biriyle çift programlama yapmak.

Önde daha fazla kodlama yapıyorsun.

Test-ilk, testleri geçememeniz anlamına gelir (ki bu iyidir) ve daha fazla kod yazmadan önce bitireceğiniz anlamına gelir. Bu daha fazla zaman demektir. Yine, etrafından dolanamazsın. Bakımını kolaylaştıran, genişleten ve genel olarak daha az hata içeren kodla ödüllendirilirsiniz, ancak zaman alır.

Yöneticilere zorlu bir satış olabilir.

Yazılım yöneticileri genellikle yalnızca zaman çizelgeleriyle ilgilenir. Test-ilk programlamaya geçerseniz ve bir özelliği yerine bir özelliği tamamlamak için aniden 2 hafta harcarsanız, bundan hoşlanmayacaklardır. Bu kesinlikle savaşmaya değer bir savaş ve birçok yönetici onu alacak kadar aydınlandı, ancak zorlu bir satış olabilir.

Diğer geliştiriciler için zorlu bir satış olabilir.

Dik bir öğrenme eğrisi olduğundan, tüm geliştiriciler test-ilk programlama gibi değildir. Aslında, çoğu geliştiricinin ilk başta sevmediğini tahmin ediyorum . Hızlanmalarına yardımcı olmak için çift programlama gibi şeyler yapabilirsiniz, ancak zorlu bir satış olabilir.

Sonunda, avantajlar dezavantajlara göre daha fazladır, ancak sadece dezavantajları görmezden gelirseniz yardımcı olmaz. En başından beri neyle uğraştığınızı bilmek, dezavantajların tümü olmasa da bazılarını müzakere etmenize yardımcı olur.


Bunlar iyi cevaplar, ama # 1 hakkında daha spesifik olabilir mi? Özellikle programlama hızınızı nasıl kazanıp kazanamayacağınızı / TDD'yi yapmaya başladığınızı bilmediğinizi ne öğrendiniz?
Alex Feinman

Bazı açıklamalar getirmek için güncellendi
Jaco Pretorius 20:10

7
Şimdi test yapıyorsanız , geliştirme için harcanan toplam süre önemli ölçüde değişmemelidir. Sadece işler daha uzun sürüyor gibi görünüyor çünkü ünite testlerini yazmak ve sürdürmek için harcadığınız zamanı size veriyorsunuz.
ChrisF

1
@JeffO, "Kendime bir minivan yazacağım!" kodlama okulu?
Alex Feinman

1
@tvanfosson - çünkü bir kerede iki şeyi değiştirmeye çalışıyorlar - hem teste başlıyor hem de TDD - sorunlu olabilir. Aynı zamanda zaman tahminlerine de eklenir - oldukça doğru - bu yüzden yöneticiler ve müşteriler sadece öndeki artışı görürler, genel zamanın gerçekten bilindiği (bir kereliğine) değil, daha da az olabilirler. Bazı testler yapıyorlarsa, bu artış daha az olacaktır.
ChrisF

35

Test-ilk, şu şekilde kod yazdığınızı varsayar:

  • birim test yöntemiyle test edilebilir
  • geliştirdiğiniz şeyin açık bir yaklaşıma sahip olduğu ve kapsamlı prototipleme ya da deneme gerektirmediğini
  • çok fazla yeniden ateşlemeniz gerekmeyecek veya yüzlerce veya binlerce test vakasını tekrar tekrar yazmak için zamanınız olması
  • hiçbir şey mühürlü değil
  • her şey modüler
  • her şey enjekte edilebilir veya takılabilir
  • Kuruluşunuzun kaynak havuzunu doğrulamak için düşük kusurlara yeterince yüksek bir değer koyduğunu
  • Birim test düzeyinde test etmenin faydası olduğunu

Projeniz bu gereklilikleri karşılamıyorsa, zorluk çekeceksiniz. TDD'nin destekleyicileri, bu çizgilerin içine daha iyi girebilmek için ürününüzü yeniden tasarladığınızı önermek için bu soruya iyi cevap veremez. Bunun imkansız veya istenmeyen olduğu durumlar var.

Uygulamada, test-ilk testlerinin programın doğru işlevi hakkında bir şey kanıtladığını düşünen insanlarla ilgili büyük bir sorun olabilir. Çoğu durumda bu doğru değildir, ancak doğru olduğu durumlarda bile tam bir doğruluk tablosundan uzaktır. İnsanlar yüzlerce başarılı testi görüyorlar ve TDD'den önce sadece birkaç yüz test çalışması yaptıklarından daha az test yapmanın güvenli olduğunu varsayıyorlar. Tecrübelerime göre TDD, daha fazla entegrasyon testine sahip olmanız gerektiği anlamına gelir çünkü geliştiricilerin de sahte güvenliği olacaktır ve tüm testleri büyük bir redaktör yapmak için değiştirmenin verdiği acı, geliştiricilerin ilginç çalışmalar yapmasına neden olabilir.

Örnekler:

En iyi kişisel örnek asp.net için güvenlik kodu yazarken. Makine konfigürasyonundan düşmanca bir ortamda koşmaları isteniyorsa, gac'ed edilir, imzalanır ve mühürlenirler ve IIS tanrı nesnelerine karşı çalıştıkları için doğru bir şekilde alay etmeleri çok zordur. Performans ve bellek kullanımı için bazı kısıtlamalar ekleyin; kalan alanlarda yer tutucu nesneleri kullanma esnekliğini çok hızlı bir şekilde kaybedersiniz.

Herhangi bir mikro denetleyici veya düşük kaynak ortam kodunun herhangi bir türü, soyutlamalar optimize etmediğinden ve düşük kaynak limitleriniz olduğundan, gerçekten OO tarzı tasarım yapmak mümkün olmayabilir. Aynı durum birçok durumda yüksek performanslı rutinler için de söylenebilir.


Bazı örnekler verebilir misin? Birimce test edilebilir bir şekilde test edilebilir bir şey yazmıyorsam ne olur? Neden taklit edilebilir veya enjekte edilebilir bir kod yazmıyordum (kendi başına bir konu olan eski kod dışında)?
Alex Feinman

örnekler bölümü eklemek için düzenlendi
Bill

4
Kabul. TDD çalışması, üzerinde çalıştığınız makinelerle ilgili bir dizi varsayıma dayanıyor gibi görünüyor; projelerimin yaklaşık% 50'si için geçerli gözükmüyor.
Paul Nathan

Tamamen katılıyorum ... Harika cevap
Khelben 21:10

2
Bu oyunda bir şey gibi - başkaları için uygun olmayan birçok durumlar için uygun. Yazılım geliştirmenin herhangi bir alanında Bir Doğru Yolu savunan herkese dikkat edin .
Alan B,

25

Gördüğüm en büyük dezavantaj TDD'nin kendisiyle değil uygulayıcılarla. Her şeyin test edilmesi gereken dogmatik ve zealot bir yaklaşım benimsiyorlar . Bazen (çoğu kez), bu gerekli değildir. Ayrıca, pratik olmayabilir (.ie. TDD'ye bir organizasyon getirmek.)

İyi bir mühendis takas bulur ve ilk testin ne zaman / nerede / nasıl uygulanacağı konusunda doğru dengeyi kullanır. Ayrıca, kendinizi gerçek kod yerine testler geliştirmek için sürekli olarak daha fazla zaman harcıyorsanız (2-3 ya da daha fazla bir faktörle), başınız derde girer.

Başka bir deyişle, TDD ile pragmatik ve makul olun (veya bu konuda yazılım geliştirmede herhangi bir şey.)


Bu, belki de Michael Feathers'ın “Yeni” Eski Kod tanımının (yani “Testsiz Kod”) geldiği yer mi?
Phill W.

Bu tanım benim için işe yaramazdı :) Bana göre, üretimde çalışan ve değişime tabi olan herhangi bir kod, bağımsız kod veya test kalitesinden bağımsızdır. Genellikle "eski kod" u "kötü kod" veya "eski kod" ile ilişkilendiriyoruz, gerçekte kötü kod ve eski kod zaten yapım aşamasında henüz üretim kullanımı görmemiş olan kodda mevcut. Amacımız, kodumuzun başından beri geçerli olması ve yıllar boyunca kullanımda kalacak kadar kaliteli ve kullanışlı olması olmalıdır.
luis.espinal

6

2009 yılının Ağustos ayının başında TDD yapmaya başladım ve tüm şirketimi Eylül / Ekim 2009'da buna geçmeye ikna ettim. Halen, tüm ekip tamamen dönüştürülüyor ve test edilmemiş kodun repo'ya işlenmesi Kötü Bir Şey olarak değerlendiriliyor ve atılıyor. Bizim için çok iyi çalışıyor ve kovboy kodlamasına geri dönmeyi hayal edemiyorum.

Ancak, oldukça dikkat çeken iki sorun var.

Test paketi korunmalıdır

TDD konusunda ciddi olduğunuzda, birçok test yazmaya başlayacaksınız . Ayrıca, testlerin doğru ayrıntı derecesinin ne olduğunun farkına varmak biraz zaman alır ve tecrübe kazanır (aşırı doz almak, neredeyse yapmaktan daha kötüdür). Bu testler de koddur ve bitrot'a hassastırlar. Bu, onları başkaları gibi sürdürmeniz gerektiği anlamına gelir: bağlı oldukları kütüphaneleri yükseltirken güncelleyin, zaman zaman refaktör yapın ... Kodunuzda büyük değişiklikler yaptığınızda, bir çok test aniden geçersiz hale gelir veya düz yanlış bile. Şanslıysanız, onları kolayca silebilirsiniz, ancak çoğu zaman yararlı bitleri ayıklayıp bunları yeni mimariye uyarlayacaksınız.

Zaman zaman soyutlamaların sızdığını test etme

Oldukça iyi bir test çerçevesine sahip olan Django'yu kullanıyoruz. Ancak, bazen gerçeklik ile biraz çelişen varsayımlarda bulunur. Örneğin, bazı ara yazılımlar testleri kırabilir. Veya bazı testler, önbellekleme arka ucu ile ilgili varsayımlarda bulunur. Ayrıca, eğer "gerçek" bir db kullanıyorsanız (SQLite3 değil), db'yi testlere hazırlamak çok zaman alacaktır. Elbette, yerel olarak yaptığınız testler için SQLite3'ü ve bellekteki bir db'yi kullanabilirsiniz (ve kullanmalısınız), ancak bazı kodlar kullandığınız veritabanına bağlı olarak farklı davranacaktır. Gerçekçi bir kurulumda çalışan sürekli bir entegrasyon sunucusu kurmak şarttır.

(Bazı insanlar size veri tabanı gibi her şeyle alay etmeniz gerektiğini söylerler ya da testleriniz "saf" değildir, ancak bu sadece ideoloji anlamına gelir. Alaycı kodunuzda hata yaparsanız (ve bana inanın), Testsuite değersiz olacak.)

Tüm bunlar anlattığım sorunların sadece TDD konusunda oldukça gelişmiş olduğunuzda farkedilmeye başladığını gösteriyor ... TDD ile yeni başladığınızda (veya daha küçük projeler üzerinde çalışırken) test yeniden canlandırması bir sorun olmayacak.


3
+1. “korunmak zorunda”: ​​yeniden kullanılabilir kodu test ederken, arayüz ve davranışının normalde kararlı olması gerektiğinden bu çok daha az problemdir. Bu sebeple normalde sadece yeniden kullanılabilir kütüphanemiz için TDD yapıyorum.
Dimitri C.

4

Benim için, testleri TDD'de olduğu gibi yoğun bir şekilde uygulamaya çalıştığımda, testler ile ilgili derin bir psikolojik sorun var: eğer oradalarsa, dikkatlice kodluyorum çünkü testlerin herhangi bir problemle karşılaşacağına güveniyorum. Ancak, bir güvenlik ağı sağlayacak testler yoksa, dikkatlice kodluyorum ve sonuç her zaman testlerden daha iyidir.

Belki de sadece benim. Ama aynı zamanda, her tür güvenlik zili ve ıslıklı arabaların daha fazla çarpma eğiliminde olduğunu (sürücüler güvenlik özelliklerinin var olduğunu bildiği için) de okudum, bu yüzden belki de bu onaylanması gereken bir şey; TDD bazı bireylerle uyumlu olmayabilir.


Bu bana tuhaf geliyor, çünkü test edilebilir kod yazmak genellikle yavaşlamama ve kodladığım şey hakkında daha fazla düşünmeme neden oluyor. Aslında bugünlerde testler yapmadan biraz sinir kodları alıyorum.
Matt H,

1
Sadece farklı insanların gerçekten farklı tepki verdiklerini gösteriyor. TDD'nin temelini atmıyorum - açıkçası epeyce insan bunu faydalı buluyor - ama gerçek şu ki herkes için değil.
Joonas Pulakka

2
% 100 katılıyorum. Otomatik testler olmadan kodu daha iyi ve daha hızlı yazıyorum . Elbette test etmemek saçma olurdu, sadece otomasyonun kötü bir seçim olduğunu düşünüyorum (en azından benim için). Manuel testlerin hem bir test paketini hem de daha güvenli olmasını sağlamaktan daha hızlı ve daha güvenli olduğunu düşünüyorum - ancak aynı zamanda deneyimli bir geliştiriciyim, bu yüzden neyi, nerede ve niçin test edeceğimi bildiğim için çok iyiyim, bu yüzden kod eklerim ve faktörlerim regresyon muaf.
Ben Lee

1
Birlikte çalıştığım ekibin ve projelerin hem küçük hem de tüm mimariyi iyi bir şekilde anlayabileceğim kadar küçük olmasına rağmen - büyük bir ekipte veya çok büyük bir projede otomatik testleri daha yararlı görebiliyordum. o zaman hiçbir geliştirici, gerilemeleri önlemek için sınamaları gereken yeri koklayamaz.
Ben Lee

Yeniden ateşleme adımını bırakıyor musunuz?
rjnilsson

2

Test-ilkin gerçekten önümde olduğu bir durum, bir fikri çabucak denemek ve uygun bir uygulama yazmadan önce çalışıp çalışamayacağımı görmek.

Benim yaklaşımım normalde:

  1. Çalışan bir şey uygulayın (kavramın kanıtı).
  2. Çalışırsa, testler ekleyerek, tasarımı geliştirerek, yeniden düzenleme yaparak birleştirin.

Bazen 2. adıma geçemiyorum.

Bu durumda, TDD kullanmanın benim için avantajlardan daha fazla dezavantajı olduğu ortaya çıktı:

  • Kavram ispatının uygulanması sırasında testler yazmak beni yavaşlatıyor ve düşünce akışımı engelliyor: Bir fikri anlamak istiyorum ve ilk kaba uygulamamın ayrıntılarını test etmek için zaman harcamak istemiyorum.
  • Fikrimin bir değeri olup olmadığını öğrenmek daha uzun sürebilir.
  • Bu fikrin işe yaramaz olduğu ortaya çıkarsa, hem kodumu hem de güzel yazılı birim sınavlarımı atmalıyım.

Bu yüzden, bazı yeni fikirleri araştırmam gerektiğinde, TDD kullanmıyorum ve sadece yeni kodun bir yere ulaştığını hissettiğimde birim testleri yapıyorum.


1
Prototip kodunu kullanılabilir kodla karıştırıyormuşsunuz gibi geliyor. Prototip kodu test kodudur . Test edilmesine gerek yok ve buna karşı çalışan testler oluşturmamalısınız. Kaçırdığınız adım 1 ile 2 arasındadır: "Testler yazarak birleştirin" diyorsunuz. Sorun şu ki, birleştirecek bir şeyin yok, ama yazacak bir şeyin var. Prototip kodunu yeniden yazmayı planlayın , yeniden kullanmayı düşünmeyin. Yeniden kullanmak, uzlaşma için çok fazla alan bırakır. Yeniden yazma, keşif aşamanız ve "kalite kodunuz" aşaması arasındaki bölünmeyi resmileştirir.
utnapistim

3
@utnapistim: Prototip kodunu kullanılabilir kodla karıştırmıyorum, bunun yerine TDD zealotları onları karıştırıyor ve prototip kodu için de TDD kullanmanız gerektiğini öneriyor. Veya daha doğrusu, hiçbir prototip kodunun olmadığını varsayıyorlar. Ayrıca, prototipten gerçek uygulamaya geçtiğinizde sık sık yeniden yazmanız gerektiğine katılıyorum. Bazen prototip kodunun bölümlerini yeniden kullanabilirsiniz, ancak yeniden yazmaya hazır olmalısınız. Durumdan davaya gerçekten karar vermelisin.
Giorgio

3
@utnapistim: Ayrıca luis.espinal'in cevabına bakınız: "Gördüğüm en büyük dezavantaj TDD'nin kendisiyle değil uygulayıcılarla. Her şeyin test edilmesi gereken dogmatik ve zealot bir yaklaşım sergiliyorlar.".
Giorgio

1

TDD'nin Dezavantajları veya Maliyetleri

Not: Bir dizi TDD çeşidi vardır. Birim, BDD, ATDD veya diğer değişkenlerden bağımsız olarak, zorlukların çoğu

Yan etkiler

İster alaycı, ister demirbaşlar veya fonksiyonel testler, dış devletlere veya sistemlere bağımlılık, genellikle testlerde en karmaşık olmanın kaynağı, nasıl test edileceği konusunda karışıklık ve yanlış anlamada en büyük risk kaynağıdır. Gördüğüm birkaç sorun:

  • Mocking: aramaların sırasını savunmayı unut
  • Mocking: alay gerçek arama veya yanıtla eşleşmiyor
  • Fikstür: Test, gerçekçi olmayan verilere dayanıyor ve diğer sorunları maskeliyor
  • Fikstür: üretimde imkansız bir durumu sınamak
  • İşlevsel: bağımlı sistemin geçici olarak kullanılamaması nedeniyle hatalı derleme kesintileri
  • İşlevsel: Testin hızı çok yavaş

Kodlama yaklaşımınızı değiştirmek zorunda kalacaksınız, çünkü bazıları sert bir değişim olacak.

Farklı insanlar çılgınca farklı şekillerde kodlar. TDD'de belirli bir davranış sergileyen bir testle başlamanız ve ardından testin geçmesi için uygulamanız gerekir. Gördüm ve programlama TDD için elverişli olmayan bir programcıydı. Başlangıçta gelişim yaklaşımımı değiştirmeye alışmaya başladığımda yaklaşık 2 ay sürdü.

Sınamaya ne önem verdiğinizi ve sınamaya ne önem vermediğinizi anlamanız zaman alır.

Her takım testte çizgiyi nereye çekmek istediğine dair kesin bir karar vermelidir. Test etmek istedikleri şeylere değer verdikleri ve istemedikleri şeyler. Genellikle iyi testlerin nasıl yazılacağını ve gerçekten test ile ilgili neye önem verdiğinizi öğrenmek ağrılı bir süreçtir. Bu arada kod, hem tarz hem de yaklaşımda tutarlılık oluşuncaya kadar bir akış halinde olmaya devam edecek.

Birim Testine özgü: büyük refaktörler

On binlerce ünite testine sahip önemli bir kod tabanının büyük veya temel bir düzelticisi, tüm testleri güncellemek için büyük bir maliyet getirecektir. Bu, yapılacak doğru maliyet olsa bile, yapılacak olan doğru maliyet olsa bile, bir refaktör yapmanın önündeki engeller ile kendini gösterir.


0

Analojim, Scalextric pistteki engeller. Onları giyersen, daha az temkinli olursun.

İnsanlar ayrıca testleriyle ilgili biraz alan kazanıyor - iyi çalıştıkları için, kodun tamamen test edildiğine inanıyorlar, oysa test sürecinin sadece başlangıcı.

Aklıma TDD BDD için bir basamak taşıdır. Gerçekleştirilen testler, testlerin ne yaptığını bilmeden geliştiricilerin desteklenmesine gerçekten yardımcı olmaz. BDD ile, test çıktısı, testi belgeleyen ve böylece sistemin anlaşılmasını sağlayan İngilizce'dir.


-1

TDD'nin faydaları, kodunuzu anlamayan insanlara karşı sizi korumaya zorlamasıdır. Evet, bu genellikle kendinizi içerir. Ancak, kod korunmaya değmediğinde ne olur? İlk başta orada bulunmaması gereken bir sürü kod var! Bu yüzden TDD ile ilgili sorun, kötü kod yazan geliştiricilere gelincedir. TDD muhtemelen iyi kod yazmalarına yardım etmeyecek, korkunç testler de yazma olasılıkları çok daha yüksek. Böylece TDD onların durumunda sadece pisliğe eklenir; kötü yazılmış ve / veya gereksiz testler diğer kötü kod biçimlerinden daha eğlenceli değildir.


1
Kendi kodunuzu kendiniz anlamıyorsanız, milyarlarca olası test aracı arasında bir avuç, kodun yanlış olmasına nasıl karşı koyabilir?
Michael Shaw,

2
Çünkü onu yazarken anladım, ama yol boyunca unuttun mu?
Johan

+1 TDD, bir iş gereksinimini yanlış anlayan bir geliştiriciye karşı koruma sağlamaz. Burası BDD'nin geldiği yer ...
Robbie Dee
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.