Teste dayalı gelişim (TDD) aslında gerçek bir dünya projesine fayda sağladı mı?


36

Kodlamada yeni değilim. 15 yıldan uzun bir süredir (ciddi olarak) kodlama yapıyorum. Kodum için her zaman bazı testler yaptım. Ancak, son birkaç ay boyunca Ruby on Rails kullanarak test odaklı tasarım / geliştirme (TDD) öğrendim . Şimdiye kadar, fayda göremiyorum.

Bazı şeyler için test yazarken bazı faydalar görüyorum, ama çok az. Ve önce testi yazma fikrini sevsem de, gerçek kodun hatalarını ayıklamaktan daha çok gerçekten ne demek istediklerini söylemelerini sağlamak için testlerimde hata ayıklamaya çalışmakla daha fazla zaman harcıyorum. Bunun nedeni muhtemelen test kodunun genellikle test ettiği koddan daha karmaşık olmasıdır. Umarım bu sadece mevcut araçlarla deneyimsizliktir ( bu durumda RSpec ).

Yine de şunu söylemeliyim ki, bu noktada hayal kırıklığı yaratan performans eksikliği ile karıştırılan hayal kırıklığı seviyesi kabul edilemez düzeydedir. Şimdiye kadar TDD'den gördüğüm tek değer, diğer projeler / dosyalar için şablon görevi gören büyüyen bir RSpec dosyaları kütüphanesi. Asıl proje kod dosyalarından çok daha kullanışlı, belki daha az kullanışlı değildir.

Mevcut literatürü okurken TDD'nin öne doğru büyük bir zaman geçirdiğini görünmesine karşın, sonunda işe yaradığını fark ediyorum. Sadece merak ediyorum, gerçek dünya örnekleri var mı? Bu büyük hayal kırıklığı gerçek dünyada hiç karşılığını alıyor mu?

Umarım bu soruyu burada başka bir yerde kaçırmamışımdır. Ben aradım, ancak tüm sorular / cevaplar bu noktada birkaç yıllık. TDD ile ilgili kötü bir şey söyleyebilecek bir geliştirici bulduğumda nadir bir durumdu, bu yüzden bu konuya sahip olduğum kadar zaman harcadım. Ancak, kimsenin gerçek dünyaya özgü örnekleri göstermediğini fark ettim. 2011'de kodu ayıklayan adamın, eksiksiz bir test test paketi hazırladığınız için teşekkür edeceğini söyleyen bir cevabı okudum (sanırım 2008'de yorum yapıldı).

Öyleyse merak ediyorum, bunca yıldan sonra, sonunda kazancın gerçek olduğunu gösteren herhangi bir örneğimiz var mı? TDD ile tasarlanan / geliştirilen ve eksiksiz bir birim test seti olan ve gerçekten bir getiri hisseden biri var mı? Yoksa testin neyi test ettiğini anlamak için çok zaman harcadığınızı mı buldunuz (ve neden önemliydi) sadece tüm karışıklığı atıp kodun içine koydunuz mu?


1
Bana birkaç kez kazandırdı: çünkü aynı projede çok fazla insan var, çünkü mücevher güncellemelerinin bazı bilinmeyen yan etkileri olabilir, çünkü her şey yeşilse ve bir hatam varsa kökünü bulmanın layık olmadığını biliyorum.
saat


3
butunclebob.com/ArticleS.UncleBob.JustTenMinutesWithoutAtest İşte Bob Amca'nın karşılaştığı gerçek dünya durumu hakkında bir hikaye.
Hakan Deryal

1
İlk başta, böceklerin nerede olmadığını bilmek için testlerin harika olacağını düşündüm, ama Bob Amca'nın makalesinde @Hakan'ın da belirttiği gibi hızlı bir şekilde öğrendim, genellikle bir test vakasını kaçırdığınız için ortaya çıkıyor. Bu da testleri çok işe yaramaz hale getiriyor. Aslında, bu makale, Artımlı Gelişimin işe yaradığı şey olduğuna işaret ediyor.
James

1
“Gerçek kodun hatalarını ayıklamaktan daha çok ne demek istediğimi söylemelerini sağlamak için testlerimde hata ayıklamaya çalışmak için çok daha fazla zaman harcıyorum” : ancak bu tam olarak bir fayda değil mi? Daha sonra, "gerçek kod" hata ayıklamak için hala çok zaman harcıyor musunuz? TDD'nin savunucuları, kodunuzu test edilebilir hale getirmenin bir yolunu bulmak için harcanan zamanın aslında kodunuza fayda sağlayacak bir tasarım çalışması olduğunu savunuyorlar .
Andres F.

Yanıtlar:


26

Bu makale TDD'nin, benzeri olmayan projelerde hata yoğunluğundaki% 40-90'lık bir azalmaya karşılık% 15-35 gelişme süresi eklediğini göstermektedir.

Makale, tam makale (pdf) - Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat ve Laurie Williams. “Test odaklı geliştirme yoluyla kalite iyileştirmenin gerçekleştirilmesi: dört sanayi ekibinin sonuçları ve deneyimleri”. ESE 2008 .

soyutTest odaklı geliştirme (TDD), onlarca yıldır sporadik olarak kullanılan bir yazılım geliştirme uygulamasıdır. Bu uygulama ile bir yazılım mühendisi, başarısız ünite testleri yazma ve bu testleri geçmek için uygulama kodu yazma arasında dakika dakika döngü yapar. Testdriven geliştirme, son zamanlarda çevik yazılım geliştirme metodolojilerinin kritik bir olanak sağlayan uygulaması olarak yeniden ortaya çıkmıştır. Bununla birlikte, çok az deneysel kanıt, bu uygulamanın faydasını endüstriyel bağlamda desteklemektedir veya reddetmektedir. Microsoft'ta üç geliştirme ekibi ve biri TDD'yi benimseyen IBM'de vaka çalışmaları yapılmıştır. Vaka çalışmalarının sonuçları, dört ürünün ön salım öncesi kusur yoğunluğunun TDD uygulamasını kullanmayan benzer projelere göre% 40 ile% 90 arasında azaldığını göstermektedir. Öznel,

Tam makale ayrıca TDD ile ilgili ampirik çalışmaları ve bunların yüksek seviye sonuçları (bölüm 3 İlgili Çalışmalar ), George ve Williams 2003, Müller ve Hagner (2002), Erdogmus ve ark. (2005), Müller ve Tichy (2001), Janzen ve Seiedian (2006).


2
Meta.StackOverflow üzerinde bir tartışma Başına , siz de bu soruyu bulmak gelecek insanlar olarak asker ile ilgili olabilir kağıttan ek bilgi eklemek olabilir?
Thomas Owens

2
@ThomasOwens, ben sonuca düşünce ( "TDD kusur yoğunluğunda% 40-90 azalma karşılığında% 15-35 geliştirme zamanı ekler") oldu ek bilgi bu cevaplar orijinal soru <_ <

4
Bu gönderi yeterli bilgi içermediği için işaretlendi. Makaleyi henüz okumadım ama görünen o ki, insanlar cevabın gövdesine daha fazla bilgi eklemek istiyor. Belki de çalışmada kullanılan spesifik koşullar hakkında daha fazla tartışınız?
Thomas Owens

Tüm istatistiklerin% 99'u kurgusaldır. : P Ama gerçekten bağlamla ilgili. Ne tür bir takımda? Büyük bir vasat Java devs sürüsü? Evet, TDD'nin onlara verimlilik konusunda yardımcı olacağına inanıyorum. Ancak bu, ilk önce sağlam kod tasarlama ve değerleme mimarisi becerilerine sahip olmak anlamına gelmez, IMO ve ilk önce test eden TDD, bunları nasıl doğru bir şekilde yapabileceklerini öğrenmelerini çok kolay bir şekilde önleyebilir. Ve evet, tasarıma yardımcı olduğunu duydum. Belli bir dereceye kadar, muhtemelen doğrudur, ancak hala onaylanamaması ve IMO'nun kök problemi için bir grup yardımcısı bulunmamasıdır.
Erik Reppen

ACM Dijital Kütüphanesi'nden bazı gazeteler ya da eklenmiş arama motoru için kullanılacak anahtar kelimeler listelenirse iyi olurdu . çevik ve TDD hakkında konuşurken cevaplarımızda daha fazla titizliğe ihtiyacımız var
Rudolf Olah

16

Bazı şeyler için test yazarken bazı faydalar görüyorum, ama çok az. Ve önce testi yazma fikrini sevsem de, gerçek kodun hatalarını ayıklamaktan daha çok gerçekten ne demek istediklerini söylemelerini sağlamak için testlerimde hata ayıklamaya çalışmakla daha fazla zaman harcıyorum.

Son üç yıldır TDD'de çalışıyorum ve deneyimim tam tersi. Ünite testlerini yazmamış olsaydım, kodun hatalarını ayıklayacağım ünite testleri yazmak için daha az zaman harcıyorum.

Sadece TDD yapmam, dışarıda çalışmam, yani ilk önce üst / gui katmanı TDD'yi uygularım. Üst katmanın uygulanması, özellik için gereken tüm kod uygulanıncaya kadar TDD vb. Kullanarak geliştirdiğim sistemdeki bir sonraki katman için gereksinimleri tanımlar. Genelde, bunun gibi bir özelliği uyguladıktan sonra, bu özelliği gerçek sistemde test ederken sigara kullanıyorum, ilk kez çalıştığını görüyorum. Her zaman değil, ama sık sık.

Ve gerçek bir sistemde bir özelliği test etmek bir kaç ünite testi yapmaktan daha uzun sürdüğü için, çok fazla zaman kazanıyorum. TDD kullanarak bir özellik uygulamak benim için birim testleri yazmayan bir özelliği uygulamamaktan daha hızlı.

Ancak birim testleri yazmak, tıpkı diğer programlama becerilerinde olduğu gibi öğrenilmesi ve öğrenilmesi gereken bir beceridir. TDD yapmaya başladığımda, programlama konusunda 12 yıllık mesleki deneyime sahiptim ve çok başarılı bir programcıydım. Sistem kodu için büyük test paketleri yazmanın basit olacağını düşündüm. Ancak, test kodunun miktarı arttıkça ve sistemin farklı bölümleri değiştikçe ve mevcut testlerin değiştirilmesi gerektiğine göre, yapılanma ve yazma ünite testinin kendi başına öğrenilmesi ve ustalaşması gereken bir beceri olduğunu öğrendim. Ayrıca tüm kodlar eşit olarak test edilebilir değildir. Sistem kodunun, verimli bir şekilde test edilebilir olması için çok gevşek bir şekilde bağlanması gerekir. Aslında TDD'yi öğrenmek, sistem kodunu daha gevşek bir şekilde birleştirmeme yardımcı oldu.

Fakat benim TDD çalışmalarındaki mevcut verimliliğim, hem birim testleri nasıl yazılacağına hem de sistemin uygulandığı teknolojide uzmanlaşmaya dayanıyor (bu durumda C #).

TDD'yi yeni bir teknoloji öğrenirken yapmak zor olabilir, örneğin biraz iPhone programlama yaptım, ancak önemli miktarda ünite testi yazmıyorum, çünkü dilde, hedef c'de ustalaşmıyorum. kütüphane. Bu nedenle, birim testlerimi nasıl yapılandıracağım, hatta sistem kodunu nasıl test edilebilir yapılacağı hakkında daha az bir fikrim yok.

Ama gerçek projelerde ne kadar iyi çalışıyor?

Son birkaç yıldır üzerinde çalıştığım projede, kodun birim testler tarafından yeterince kapsanması gerektiği halde, ilk önce testleri yazan ekipte ben varım. Ancak büyük test paketi, sistemi yeniden aktarabilmem konusunda bana güven veriyor ve test paketi geçerse sistemin doğru çalışacağına inanıyor.

Ancak ne yazık ki, testlerin çoğu sistem kodundan sonra yazıldığı için testlerin pek çoğu hatalıdır, yani test etmek istediklerini gerçekten test etmezler. Bu imho önlenemez. Her bir kod parçasını her yazışınızda, kodun istediğiniz gibi çalışmama olasılığı vardır, yani bir hata vardır. Aynı test kodu için de geçerli. Bu nedenle, test etmesi gereken kod amaçlandığı gibi çalışmasa da başarılı olan bir test yazmanız ihtimali vardır.

Öncelikle testi yazmak, sadece bir test hatası alıp almadığınızı doğrulamakla kalmayıp, testin sistem kodunu uygulamadan önce tam olarak beklediğiniz hata mesajıyla başarısız olduğunu doğrulamak, ünite test kodundaki hata riskini ciddi şekilde azaltır.

Özetlemek gerekirse, benim deneyimimde TDD sanatında ustalaştığınızda, uzun vadede sadece zamandan tasarruf etmeyecek, önden zaman kazanacaksınız. Ancak deneyimli bir programcı için bile TDD sanatında ustalaşmak zaman alıyor. Ve TDD sanatında ustalaşmak için çeşitli becerilere sahip bir geliştiricilerden oluşan bir ekibin daha da uzun sürmesi gerekiyor.


9

Büyük ölçüde faydalandık.

1. Kademe Tüccarıyız, bu da yılda altı milyondan fazla ödeme işlemini gerçekleştirdiğimiz anlamına gelir.

Ödeme ağ geçidi sistemimiz binlerce birim ve entegrasyon testine sahiptir. Bu testler bize ödemeleri işleme yeteneğimize güveniyor. Araba frenlerinin çalıştığına emin olmak istiyorsun, değil mi? İşlerimizi kaybetmediğimizden emin olmak istiyoruz çünkü ödemeleri işleme koyamıyoruz.

Kod kapsamı size bu güven verir. Tabii kendi başına yeterli değil, ama çok iyi bir başlangıç.

Ödeme ağ geçidi sistemimizin çoğu TDD kullanılarak yazılmıştır. Bazı yönleri test etmek oldukça zor oldu, bu yüzden bazı kod kapsamlarından ödün vererek köşeleri kesmeye karar verdik. Sonunda geri dönüp bu sorunları çözeceğiz.

Şahsen, test yazmadan önce herhangi bir mantık yazmayı zor buluyorum. Bunu söyledikten sonra TDD tarzında düşünmeye başlamak biraz zaman aldı.

Visa PCI Referansı: http://usa.visa.com/merchants/risk_management/cisp_merchants.html


3
“Sonunda geri dönüp bu sorunları ele alacağız.” - Muhtemelen hayır ... orospuları seni korkunç bir böcekle tokatlamadıkları sürece. Bu alanlar her şey için bel kemiği olacak ve tüm tasarımların ilerleyişini yönlendirecektir çünkü hiç kimse kaynakları tekrar yapmak için yatırım yapmak istemeyecek ve hiç kimse kötü bir şey yapabilecek herhangi bir değişikliği zorlamak istemeyecektir. Her zaman olur: P
Edward Strange

Tahmin ediyorum, size şirkette neler olup bittiğini anlatırken. Taahhüt ettiğimizde,% 70 kod kapsamı ile kod işleyebiliriz. Bu, CI liderliği tarafından sürekli artmaktadır. Aylar içinde, minimum kod kapsamı eşiği küçük bir yüzde oranında artırılacaktır. Bundan sonra başka seçenek kalmayacak, ancak daha fazla test getirecek.
CodeART

7

Testler çoğu zaman sadece bazı insanlar tarafından çok fazla yapılmanın bir yolu olarak görünse de, bazı durumlarda bu gerçekten sıkıntıya değeceğini düşünüyorum.

Yaklaşık 3 aydır okul için bir Katil Sudoku Çözücü geliştiriyorum, olasılıkları ve çözümleri kaldırmak için birçok "strateji" kullanıyor. Gerçek şu ki, bir olasılıktaki bir hata ölümcül olabilir ve sudoku çözmek için bir sorunla sonuçlanabilir, çünkü bazı olasılıklar ortadan kalktığında, artık denemezsiniz ve çözüm buysa, program çözemez. artık ızgara.

Ama manuel olarak test etmek gerçekten zor, demek istediğim bir ızgara var, gerçek dünya örneğinde hangi sınıfların ne yaptığını görebiliyorum, ancak bir stratejinin ne zaman uygulandığını her zaman kontrol edemiyorum çünkü bu çok fazla veriyi temsil ediyor.

Ve belirli bir şebekeye uygulanan stratejiler oldukça "rastgele" dir, yani belirli bir şebekede hepsini kullanmayacaksınız.

Bu yüzden her bir strateji için testler yazdım, sonuçları her hücrede kontrol ederek, sadece basit durumları kullanarak (örneğin, sadece iki hücre olasılıkları zaten ortadan kaldırdı) ve maalesef çözülemeyen bir şebekeye sahip olduğumda günde saatlerce kurtardı. Çünkü sorunun nerede olduğunu zaten biliyordum.


2
Bu sorunun ilk testte daha fazla dürtme olduğunu hissediyorum, daha sonra straterji uygulayın. Testler elbette, her olasılığı kendiniz test etmenin sıkıcı olduğu uygulamalarda hata ayıklamak için kullanışlıdır.
Alex Hope O'Connor

6

TDD'nin avantajı, kodunuzu yazmadan önce kodunuzu nasıl arayacağınızı bulmanızdır.

Başka bir deyişle, TDD API'nizi tasarlamanıza yardımcı olur.

Tecrübelerime göre bu daha iyi API'lerle sonuçlanıyor ve bu da daha iyi kod veriyor.


EDIT: Yazdığım gibi, bu “benim deneyimimde”, yani “gerçek dünya projeleri yazarken” ama ne yazık ki bu, kapalı bir kaynak kod tabanı ile, dünyanın görmesine izin veremem. Bu tür projelerin varlığının bir teyidi değil , aslında bunun ne istendiğini yorumlardan anlayabiliyorum .

Ayrıca kişisel deneyimime göre, bakım moduna girdiğinizde asıl fayda göstermenin, çünkü gereksinimler değişme eğiliminde olduğunu buldum. Temizleyici API'ler test kodunda yeni veya değiştirilmiş gereksinimleri ifade etmeyi çok kolaylaştırdı ve tüm testler gelecekteki bir bakımcı için kodun nasıl çağrılacağını ve ne beklenebileceğini görmeyi çok kolaylaştırdı.

Test durumları şartnamenin sürümlerini çalıştırıyor ve API'nizi nasıl çağıracağınızı çok, çok kolay bir şekilde görmenizi sağlar. Bu belki de şu ana kadar gördüğüm "HOW" belgesinin en kullanışlı şeklidir ( JavaDoc gibi "WHY" belgesine kıyasla) (doğru olmasa da testin kesin sonuç vermeyeceğinden).

Son zamanlarda, uygulamanın çalışma şeklini etkileyen çok büyük seçeneklere sahip bir komut dosyası ftp istemcisini sürdürmek zorunda kaldım. TDD son zamanlarda yeni işlevler için tanıtıldı ve büyük test paketi kullanılmış işlevselliğin hala beklendiği gibi çalıştığından emin olurken düzeltmeler yapmamızı sağlıyor. Başka bir deyişle, bu geçişin çok hızlı bir şekilde karşılığını verdi.


8
Bu cevap, tamamen gerçek sorulardan ibaret olduğundan, sorunun tamamının yanında olduğu görülüyor . Ancak üç kişi "bu cevap yararlı" diye düşündüğünden, bir şey eksik olmalı.

3
Anlaştım, ancak oy kullanma konusundaki itibarı yetersiz. Bu, sadece "TDD daha iyi sonuçlar verir" dir, kaçınmak istediğim cevabı destekleyecek TDD'den türetilmiş bir projenin örneği yoktur.
James

Şimdi birkaç kişi benimle aynı fikirdeyken, aşağı oy kullanmaya cüret ediyorum. Herhangi bir destekçi veya yazar, lütfen yukarı çıkıp bize bunun neden iyi bir cevap olduğunu söyler mi?

@delnan "Aşağı oy kullanmaya cüret et" - kelimelerin ilginç bir seçimi. Düzenleme zevkinize düştü mü?

Evet, şimdi dikkatimi çektiğim için oyumdaki oyu kaldırdım.

5

Test için belirli bir yaklaşımın ne kadar değerli olduğu, geliştirilmekte olan sistemin ne kadar kritik olduğu ve diğer bazı kritik görev sistemlerinin ne kadar bağımlı olduğuna bağlıdır. Web siteniz için basit bir ziyaretçi defteri komut dosyası, kritik bir görev olarak kabul edilmeyebilir, ancak üzerinde çalıştığı web sitesi, veritabanına filtrelenmemiş girdi girilmesine izin veren bir hata ile tehlikeye girebilirse ve bu site çok önemli bir hizmet sunarsa, o zaman aniden çok daha fazlası olur. Ziyaretçi defteri betiğinin iyice test edilmesi için önemlidir. Aynısı çerçeve / kütüphane kodu için de geçerlidir. Hata içeren bir çerçeve geliştirirseniz, bu çerçeve özelliğini kullanan her uygulamanın da aynı hatayı vardır.

Teste dayalı geliştirme, testlerde size ekstra bir güvenlik katmanı sağlar. Testleri yanına veya test etmek istediğiniz koddan sonra bile yazarsanız, testlerin yanlış yapılması riski vardır. Önce tüm testleri yazarsanız, kodun dahili olarak nasıl çalıştığını yazdığınız testleri etkileyemez ve bu nedenle yanlışlıkla belirli bir hatalı çıkışın doğru olduğunu düşünen testleri yazmanız olasılığını azaltır.

Test odaklı geliştirme, geliştiricilerin test etmesi kolay bir kod yazmasını da teşvik eder, çünkü kendilerine yapacak daha fazla iş vermek istemezler! Test edilmesi kolay olan kod, anlaşılması, tekrar kullanılması ve bakımı kolay bir kod olma eğilimindedir.

Bakım, TDD'nin ödüllerini gerçekten alacağınız yerdir. Yazılıma harcanan programlama çabasının büyük çoğunluğu bakımla ilgilidir. Bu, yeni özellikler vermek, hataları düzeltmek veya yeni durumlara uyarlamak için canlı kodda değişiklik yapmak anlamına gelir. Bu tür değişiklikler yaparken, yaptığınız değişikliklerin istenen etkiye sahip olduğundan ve daha da önemlisi, beklenmedik bir efekt etkisi olmadığından emin olmak istersiniz. Kodunuz için eksiksiz bir test paketiniz varsa, yaptığınız değişikliklerin başka bir şeyi bozmadığını doğrulamak kolaydır ve yaptığınız değişiklikler başka bir şeyi bozarsa nedenini hemen bulabilirsiniz. Yararları uzun vadelidir.

Sorunuzda aşağıdakileri söylediniz:

Bazı şeyler için test yazarken bazı faydalar görüyorum, ama çok az. Ve önce testi yazma fikrini sevsem de, gerçek kodun hatalarını ayıklamaktan daha çok gerçekten ne demek istediklerini söylemelerini sağlamak için testlerimde hata ayıklamaya çalışmakla daha fazla zaman harcıyorum. Bunun nedeni muhtemelen test kodunun genellikle test ettiği koddan daha karmaşık olmasıdır. Umarım bu sadece mevcut araçlarla deneyimsizliktir (bu durumda rspec).

Bu bana pek test yaptırmadığınızı gösteriyor. Bir birim testinin son derece basit olması beklenir, yalnızca bir yöntem çağrıları dizisi, ardından beklenen sonucu gerçek sonuçla karşılaştırmak için bir iddia. Basit olmaları gerekir çünkü testlerinizdeki hatalar felaket olur ve teste döngüler, dallanma veya başka bir program atma kontrolü eklerseniz, testin içine bir hata girmesi olasılığı artar. Çok fazla zaman ayıklama testi yapıyorsanız, testlerinizin aşırı karmaşık olduğunu ve basitleştirmeniz gerektiğini gösterir.

Testler basitleştirilemiyorsa, bu gerçek tek başına test edilen kodda yanlış bir şey olduğunu gösterir. Örneğin, sınıfınızın uzun yöntemleri varsa, çok sayıda if / elseif / else veya switch deyimine sahip yöntemler veya sınıfın şu anki durumu tarafından dikte edilen karmaşık etkileşimlere sahip çok sayıda yöntem varsa, o zaman testlerin gerekliliği gereği karmaşık olması gerekir. tam kod kapsamı sağlamak ve tüm olasılıkları test etmek. Sınıfınızın diğer sınıflara zor kodlanmış bağımlılığı varsa, bu, kodunuzu etkili bir şekilde test etmek için tekrar atlamak zorunda kalacaksınız.

Sınıflarınızı küçük tutup yüksek odaklanmış, birkaç çalışma yoluna sahip kısa yöntemlerle tutarsanız ve dahili durumu ortadan kaldırmaya çalışırsanız, testler basitleştirilebilir. Ve bu da meselenin özü. İyi kod, doğal olarak test edilmesi kolaydır. Kodun test edilmesi kolay değilse, muhtemelen yanlış bir şeyler vardır.

Birim testleri yazmak, uzun vadede size fayda sağlayan bir şeydir ve onlardan kaçınmak, daha sonra sorun yaşamanızı sağlar. Teknik borç kavramına aşina olmayabilir, ancak finansal borçlara çok benziyor. Test yazmamak, kod yazmamak, kodlanmış bağımlılıklarda yazmak ve böylece borçlanmanın yolları vardır. Köşeleri daha erken keserek zamanınızı ödünç alırsınız ve bu, sıkı bir son tarihe ulaşmanıza yardımcı olabilir, ancak projede daha önce kazandığınız zaman ödünç verilir. Kodu temizlemeden, düzgün yorum yapmadan veya bir test takımı oluşturmadan geçen her gün ilginizi çekecektir. Ne kadar uzun sürerse, ilgi de o kadar artar. Sonunda, kodunuzun istenmeyen sonuçları tetiklemeden değişiklik yapamayacağınız karışık bir karmaşa haline geldiğini keşfedeceksiniz.

Ünite testlerini erken yazmayı ve bunları "teknik kredi" biçimi olarak güncel tutmayı düşünebilirsiniz. İyi uygulamaların takibi için projeye erken zaman ayırarak bankaya zaman ayırıyorsunuz. Daha sonra projenin bakım aşamasına geçtiğinde bu öngörüye ilgi kazanacaksınız. Bir değişiklik yapmak istediğinizde, değişikliğin doğruluğunu kolayca doğrulayabilirsiniz ve istenmeyen yan etkileri yoktur ve hızlı ve telaşsız bir şekilde kapıdan güncellemeleri alabilirsiniz. Hatalar ortaya çıkarsa, hatayı uygulayan yeni bir birim testi ekleyebilir, ardından kodu kodda düzeltebilirsiniz. Ünite testini bir sonraki çalıştırışınızda, hatanın çözüldüğünü ve başka sorunlara neden olmadığını doğrulayabilirsiniz. Dahası, "gerilemeler" den kaçınacaksınız,

TL: DR - Evet, onlar gerçek bir dünya yardımı, ancak bir yatırım. Avantajlar ancak daha sonra belirginleşir.


1
Bu mantığı aylar önce satın aldım. TDD'nin ardındaki fikri seviyorum, sadece gerçeğini biraz rahatsız edici buluyorum. Ayrıca, burada bile TDD tabanlı bir projenin miras almasının karşılığını veren hiçbir gerçek örnek olmadığını gördüm. Gerçekten bir sürü ünite testinden geçmiş eski bir kod üssüne döndün mü ve parasını ödedi.
James

Ne yazık ki, çünkü başka hiç kimse birim testleri oluşturuyor gibi görünmüyor, en azından önceki geliştiricilerden aldığım kodların hiçbirinde. Hayatım olsaydı çok daha kolay olurdu. Rails yerine PHP için gerçek dünya örnekleri olan bağlantıdaki kitabı kontrol etmenizi öneririm. amazon.com/…
GordonM

Genel bir kullanım eleştirmeniyim ama bu yaklaşımı gömülü veya eleştirel bir finansal sistemde kullanmaktan kimseye hata yapmam.
Erik Reppen

4

İşyerinde çok sık TDD kullanıyorum. Tecrübelerim TDD'nin kendisini haklı çıkarması çünkü ek zaman veya emek harcamamanız, tasarruf etmeniz.

  • TDD kullandığım için hata ayıklama veya daha az zaman harcıyorum. Bu sadece başlangıçtan beri işe yarıyor çünkü test kodunu geçmediği sürece üretken kodu yazmam.

  • Kalite Güvencesi çok daha az hata bildirir, bu nedenle sürümden sonra kodumuzu onarma maliyetinden tasarruf ederiz. Bunun nedeni TDD'nin test yapmadan kod yazmanıza izin vermemesidir, bu nedenle kod kapsamı çok daha iyidir.

  • (Üretken) kodumu çok daha sık ve daha hızlı çalıştırabilirim çünkü tüm uygulama sunucusunu başlatmam gerekmiyor. Birim testine başlamak, daha hızlı bir büyüklük sırasıdır. Tabii ki, yalnızca üretici kodu denemek istediğimde test zaten çalıştırılabilirken faydalanıyorum. Testler daha sonra geldiğinde bu avantaj kaçırılmış olur.

  • Daha az manuel test yapıyorum. TDD uygulamayan meslektaşlarım, yeni kodun uygulandığı noktaya gelinceye kadar başvuruyu tıklatarak çok zaman harcıyorlar. Sürüm kontrolüne geçmeden önce sadece bir kez manuel olarak test ediyorum.

  • Bir hata ayıklayıcı kullansam bile, bir testin yürütülmesinde hata ayıklamak tüm uygulamadan daha hızlıdır.

Belki de birim testlerini regresyon testi olarak düşünürsünüz. Bu onların amaçlarından biridir ancak bir araç olarak onları anlama için geliştirme onları çok daha değerli hale getirir.


Kalite ücretsiz!
MathAttack

2
Kötü kalite pahalı!
Wolfgang

3

Bir başka avantaj (cevap veren diğer kişilerin söylediğine ek olarak), müşteri kabul test uzmanlarının veya (cennet yasağı) üretim kullanıcılarının bir hata bulduğunda ortaya çıkar. Hata raporunu hatalı görünen sınıf için TDD tarzı bir test haline getirin. Başarısız olduğunu izle. Düzelt. Geçmesini izle. O zaman hatayı düzelttiğini biliyorsun. Bu teknik beni saatlerce kurtardı.


2

Şahsen geliştiricilerimden iki kat daha hızlı olduğumdan kişisel olarak fayda sağladığımı ve yaptıkları hataların yarısından daha azını yazdığımı biliyorum çünkü TDD yapmıyorlar. Muhtemelen benden daha iyi olması gereken insanlar bile ... Onları en az 2 kat daha yüksek performans gösteriyorum.

Oraya hemen gelmedim. Kelepçeden ve kablo demeti olmadan kod yazmakta oldukça iyiyim. Tüm bu ekstra saçma yazmak için büyük bir atık gibi görünüyordu. Ancak, (özel değil) dahil olmak üzere çeşitli şeyler yapar:

  • Dekuplaj ve yeniden kullanıma yönelik bir tasarımın zorlanması (her şeyin bir birim testinde yeniden kullanılması gerekir).
  • Küçük parçalarda ve modüllerde kod geliştirmek için bir platform sağlamak, bu nedenle basit bir "Çalıştırma ve hatta girdi bile" türünden bir test yapmadan önce her şeyi anlamak ve bitirmek zorunda kalmıyorum.
  • İnsanlar beklediğim özellik değişikliklerini istediğinde değişiklik yapmak için hızlı bir test platformu sağlamak.

Daha sonra bu bit üzerine bir örnek, şu anda üzerinde çalıştığım projenin, aniden 0 sebepten dolayı kullandığı iletişim protokolünü TOTALLY olarak yeniden yazmaya karar verdiği bir projedir. Bu değişikliğe 2 saat içinde cevap verebildim, çünkü şimdiden her şeyden ayrıldım ve üzerinde en son bir araya gelene ve test aşamasını bütünleştirinceye kadar tamamen bağımsız olarak çalışabildim. İş arkadaşlarımın çoğu muhtemelen bir gün veya daha fazla bir süredir burada olacaktı çünkü kodları çözülmeyecek ve burada, orada, her yerde, her yerde ... hepsini derleyecekti ... entegrasyon testi ... tekrarla, tekrarla ... Bu şekilde çok daha uzun sürüyor ve hiçbir yere yakın durmuyor.


2

Cevap Evet. Şirketimde 20 yılı aşkın bir süredir bir C ++ uygulaması geliştiriyoruz. Geçen yıl bazı yeni modüllerde TDD'ye girdik ve hata oranları önemli ölçüde azaldı. O kadar sevdim ki, bazılarımız eskiden bir şeyi her değiştirdiğimizde eski kodlara bile testler ekliyor.

Dahası, baştan sona tüm bir modül, hiç hata göstermeden üretime geçerek tamamlandı (ve bu da kritik bir modül). Gelişmesi normalden daha hızlıydı, çünkü genellikle başka bir şey olacaktı, bir modülün "düzeltilmiş" olması, hata düzeltmeleri için beta testinden sadece 4-5 kez geri dönmek. Önemli bir gelişme oldu ve geliştiriciler de yeni süreçten daha memnun kaldılar.

Çok fazla Rails TDD yapmadım, ancak C ++, C #, Java ve Python'da çok şey yaptım. Size kesinlikle işe yaradığını söyleyebilirim. Tahminimce test isimlerini düşünmek için çok zaman harcıyorsun çünkü yeterince kendine güvenmiyorsun. Önce testini yaz, ama yaratıcılığının akmasına izin ver

TDD'nin gerçekten asılmasından sonra, “Bu testi nasıl adlandıracağım… argh!” Konusuna biraz daha az bakmaya başladığınızı farkettim ve şimdiden yazılı olarak yeniden düzenleme ve uyarlama yapıyorsunuz. Mevcut duruma uygun testler.

Bir bahşiş zamanı

1. İpucu

Bu yüzden size en çok yardımcı olması gerektiğini düşündüğüm ipucu çok fazla endişe etmemektir. TDD hakkındaki en güzel şeylerden biri, zaten yazılı ve çalışan şeyleri değiştirme konusunda size cesaret vermesidir. Ve bu testleri içerir.

2. İpucu

Yeni sınıf testlerine basitçe "canCreate" testi ile başlayın, zihninizi doğru yöne ayarlamak için, "Tamam, şimdi bu sınıf üzerinde çalışıyorum ... doğru."

Ardından, daha fazla test eklemeye başlayın, ancak bir seferde yalnızca bir tane oluşturun ve oluşturduğunuz her testin, bu noktada aklınıza gelen bir sonraki en basit durum olduğundan emin olun (30 saniyeden fazla düşünmeyin ve zaman aşımına uğrar En iyi o noktada sahipsin).

Ve Hatırla

Var olan testleri yeniden düzenlemekten, hatta eski ya da fazla olanları kaldırmaktan endişe etmeyin. Pek çok insan bunu fark etmiyor, ancak TDD'de aslında 1'in fiyatına 2 güvenlik ağı alıyorsunuz. Testleriniz üretim kodu değişiklikleri için bir güvenlik ağıdır, ancak üretim kodunuz da testleri yeniden düzenlemek için bir güvenlik ağıdır. İlişki karşılıklı. Aslında bu iyi bir sıkı bağlantı durumu.

Başka bir şans ver. Ve özellikle TDD ile ilgili olanları temiz kod yayınlarını izlemenizi tavsiye edeyim .


1

Gerçek dünya önemsiz olmayan örnek:

Bir veri yapısı dönüştürme işlevi yazmak zorunda kaldım. Girdi bir veri yapısı (aslında bir ağaç gibi iç içe geçmiş bir veri yapısı) ve çıktı benzer bir veri yapısı olacaktır. Aklımdaki gerçek dönüşümü görselleştiremedim. TDD'nin temel faydalarından biri (benim için zaten), nasıl ilerleyeceğinizi bilmiyorsanız bebek adımlarının uygulanmasıdır (bkz. Kent Becks, "Örnek ile TDD"). Bunun nereye gittiğini bilmiyordum çünkü boş ya da önemsiz girdiler gibi basit temel durumlarla başladım ve hepsini örtbas edene kadar daha karmaşık durumlara kadar çalıştım. Sonunda çalışma algoritması ve bunu kanıtlayan testlerim vardı. Testler sadece şu an uygulamamın çalıştığını kanıtlamakla kalmıyor, aynı zamanda daha sonra bir şeyi batırmamı engelliyor.


-1

Herhangi bir genel tavsiyeye kör bir şekilde uyma fikrini sevmiyorum, çünkü çoğu geliştiricinin daha üretken olmasına ve uygulamalardaki hataları azaltmasına yardımcı olacak tek bir öneri olduğuna inanmıyorum. Tecrübelerime göre, kalite konusunda ne kadar endişe duyuyorsanız, sunulan yeni özellikler kadar kaybedersiniz. Bu nedenle kaliteye ve teslim edilebilirliğe vermek istediğiniz önem düzeyi aslında ürününüze ve mevcut stratejinize bağlı olacaktır ve büyük olasılıkla şu an için neyin daha önemli olduğuna stratejik olarak karar verecek bir başkası olacaktır: sağlamlık veya teslim edilebilirlik.

Bu karar bile siyah ya da beyaz değil. Büyük olasılıkla, uygulamanızın bazı bölümlerinin, diğerlerinin mecbur kalmamasına rağmen, sağlam olması gerekir. Hangi parçaların yüksek kalitede olması gerektiğini belirledikten sonra, bu parçalara yüksek kalite sağlamak istediğinizden test perspektifinden bunlara odaklanmalısınız.

Şimdiye kadar söylediklerimin, özellikle uygulamadan önce test yazarken TDD ile ilgisi yoktur, ancak ilk önce test yazarken kod yazmanın yararlarını ayırmanın önemli olduğuna inanıyorum.

Testin kendisinin TDD olsun ya da olmasın faydalarını anladıktan sonra, testlerle kapsanmak istediğiniz kod için test stratejisini tartışabilirsiniz. Bazı insanlar testleri daha sonra yazarsanız, testlerinizde bazı koşulları kaçıracağınızı, ancak bunun sizin için geçerli olup olmadığını değerlendirmek için siz olmanız gerektiğine inanıyorum. Bu kesinlikle benim için geçerli değil.

İşte benim için nasıl işliyor. Test yazmamı sağlayacak iki temel durum var: sadece kaliteyi artıracak veya bazı özelliklerin gelişimini de hızlandıracak. Bu nedenle, test yazacağım bir durum, birikimde yeni özellikler olmadığı zamandır ve daha sonra uygulamanın performansını artırmaya, kod tabanını basitleştirmeye veya test takımını iyileştirmeye karar verebilirim. Diğer bir durum, böceklerin gerçek müşteriler üzerinde yeterince büyük bir etkiye sahip olacağı sağlam bir çalışma koduna ihtiyaç duyulmasıdır. Yine bir diğeri üzerinde çalışırken kırılması kolay olan karmaşık kodu test etmek içindir. Örnek olarak, kod tabanımda birçok kullanım durumuyla ilgilenen bir QueryBuilder sınıfı var ve bir hatayı düzeltirken ya da yeni bir özellik eklerken bazılarını kırmak kolay olacak.

Son olarak, testlerin yazılmasının önce bir özelliği daha hızlı yazmamı, sonra testleri yazmamamı sağladığı bir durum var. Bu QueryBuilder da bu kuralın uygulandığı bir durumdu, ancak TDD'nin de en iyi yol olacağı anlamına gelmiyor. TDD'nin geliştirme hızına yardımcı olması için bir başka örnek, örneğin Excel neslinin test edilmesi içindir; gerçek uygulamada, nesildeki belirli bir koşulu test etmek istediğiniz her seferde birkaç adım uygulamanız gerekebilir. Veya bir özelliği test etmek için bazı kayıtlar oluşturmanız gerekiyorsa ve kodu el ile test ettikten sonra bunları manuel olarak silmek zor veya imkansızdır.

Bu nedenle, bazı geliştirme kodlarını programlı olarak (testler aracılığıyla) çalıştırmak için gereken adımları yeniden oluşturmanız daha kolaysa, bunun için gidin. Ancak testi yazmak daha karmaşıksa, daha sonra manuel olarak test ediyorsanız, kaliteye odaklanmanın zamanının olup olmadığına ya da birikiminizde çok fazla istek olup olmadığına ve şirketteki birinin muhtemelen daha iyi bileceğine ve sizi bilgilendireceğine karar vermelisiniz. Mevcut ihtiyaç ve şirket stratejilerine göre nereye odaklanmanız gerektiğini bilir.

İdeal bir dünyada tüm kodlar test edilir, ancak bir takas olmadığına inanılamaz ve TDD'nin her zaman en iyi ve tek yol olduğunu varsayalım. Tüm en iyi uygulamalarda olduğu gibi, sizin için daha iyi olanın yerine, çalıştığınız şirket için neyin en iyisine odaklanmalısınız. Serbest meslek sahibi olduğunuzda, en iyi yol olduğunu düşünüyorsanız, TDD'yi her zaman yapmaya karar vermekte özgürsünüz. Şirketiniz tüm kodların test edilmesi gerektiğine inanıyorsa, yazdığınız tüm kodlar için testler yazmalısınız. Ancak çoğu durumda, herhangi bir karar almadan önce büyük resmi elde etmeniz ve takasları anlamanız gerekir. Üzgünüz, ama bu kesin bir bilim değil ve her seferinde izlemeniz gereken kolay (veya zor) tek beden uyan bir cevap yok.

Tasarım desenleriyle aynı. Nasıl çalıştıklarını ve neden yaratıldıklarını ve ne tür problemleri çözdüklerini ve dezavantajlarının ne olduğunu anlayın. Gerekçenin önerilen çözümleri hatırlamaktan çok daha önemli olduğunu anlayın. Bugün pahalı bir operasyon olan yarın diğer teknolojilerle kolayca başarılabilir. Bazı iyi bıçaklanmış bir çözüm için öncül artık geçerli değilse, büyük olasılıkla çözüm artık kullanılacak en iyi çözüm değildir. Gereksinimler, mevcut teknoloji veya şirketin stratejisi değiştiğinde, araç kutunuzu her zaman yeniden değerlendirmelisiniz ve bu olduğunda, neden her yolu en iyi seçenek olarak kabul etmek yerine ilk sırada seçtiğinizi anlamanız gerekir.


bu, sorulan soruyu cevaplamaya bile kalkışmaz: "nihayetinde geri kazanımın gerçek olduğunu gösteren herhangi bir örneğimiz var mı? TDD ile tasarlanan / geliştirilen ve eksiksiz bir dizi testlere sahip olan herhangi bir kişi gerçekten miras almış veya geri dönmüş mü? Aslında bir ödeme hissettim? "
gnat

1
Cevap veriyor, ancak fikrimi paylaşmadığınız için -1 veriyorsunuz :) Temel olarak TDD'nin değerlerini göstermeye çalışmayan herkes sizin bakış açınızdan istenmeyen bir cevap verecek;) Tahmin edeyim . Sen bir TDD değişmezisin, değil mi? :) Bu arada, yazarın asıl sorusu TDD'nin işe yarayıp yaramadığı. Buna cevap vermek için TDD'yi uygulamanız gerekmez. Fortran web uygulamaları yazmak için ödeme yapıyor mu? Cevap vermeden önce denedin mi?
rosenfeld

TDD hakkında bir fikrim yok ve oyları beğenme / beğenmeme gibi kullanmıyorum (bir soru ve cevap sitesi, Facebook değil). Okuduğumda, bu "cevap" sadece, ne olumlu ne de olumsuz yönde sorulan hiçbir soruyu ele almıyor
gnat

Benim bakış açıma göre, bu "nginx ile X'i nasıl yapabilirim?" Gibi teknik bir soru değil. Yazar, TDD hakkındaki başkalarının görüşlerini ve buna değip değmeyeceğini bilmek istediğinde, bunun gibi soruların doğru cevapları vardır, ancak bunun gibi nitel ve öznel sorular için değil. Bu benim bakış açımı gösterme girişimdi. Bir cevabın nasıl doğru olabileceği hakkında hiçbir fikrim yok, çünkü hepsi bana kişisel görüşler gibi geliyor. TDD'nin değer olup olmadığını etkili bir şekilde ölçemezsiniz. Bunu yapmaya çalışan tüm makaleler temel olarak yanlıştır.
rosenfeld

"Bu site tüm tur cevapları alıyor . Bu bir tartışma forumu değil ..."
gnat
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.