Küçük bir şirkette solo geliştirici olarak çalışıyorum. Aslında şirketteki tek geliştiriciyim. Düzenli olarak yazdığım ve sürdürdüğüm birkaç (nispeten) büyük projem var ve hiçbirinin bunları destekleyecek testleri yok. Yeni projelere başlarken bir TDD yaklaşımını denemem gerekip gerekmediğini merak ediyorum. Kulağa iyi bir fikir gibi geliyor, ama dürüst olmak gerekirse, bu ekstra işi asla haklı çıkaramam.
Tasarımımda ileri görüşlü olmak için çok çalışıyorum. Kesinlikle bir gün başka bir geliştiricinin kodumu korumak veya en azından sorunu gidermek zorunda olacağını anlıyorum. İşleri olabildiğince basit tutuyorum ve kavraması zor olan şeyleri yorumlayıp belgeliyorum. Ve gerçek şu ki, bu projeler o kadar büyük veya karmaşık değil ki, iyi bir geliştirici onları anlamak için mücadele edecek.
Testlerde gördüğüm birçok örnek, kodun tüm yönlerini kapsayan minutialara iniyor. Tek geliştirici olduğum ve tüm projedeki koda çok yakın olduğum için, bir yazma-sonra-manuel test desenini takip etmek çok daha verimli. Ayrıca, gereksinimlerin ve özelliklerin, testlerin sürdürülmesinin bir proje üzerinde önemli miktarda sürükleme sağlayacağı kadar sık sık değiştiğini görüyorum. Aksi halde işletme ihtiyaçlarını çözmek için harcanabilecek zaman.
Böylece her seferinde aynı sonuca varıyorum. Yatırım getirisi çok düşük.
Bir kişinin işe alınma tarihine göre şirkette kaç yıl olduğunu hesaplamak gibi, doğru bir algoritma yazdığımdan emin olmak için zaman zaman birkaç test yaptım. Ancak kod kapsamı açısından kodumun yaklaşık% 1'ini ele aldım.
Benim durumumda, hala birim testini düzenli bir uygulama haline getirmenin bir yolunu bulabilir misiniz yoksa bu ek yükten kaçınmak için haklı mıyım?
GÜNCELLEME: Durumumla ilgili dışarıda bıraktığım birkaç şey: Projelerim tamamen web uygulamaları. Tüm kodumu kapsamak için, otomatik UI testleri kullanmam gerekirdi ve bu, manuel testlerden hala büyük bir fayda görmediğim bir alandır.
Testlerde gördüğüm birçok örnek, kodun tüm yönlerini kapsayan minutialara iniyor.
Yani? Test etmek zorunda değilsiniz her şey. Sadece ilgili şeyler.
Ben tek geliştirici olduğum ve tüm proje koduna çok yakın olduğum için, bir yazma-sonra-manuel-test desenini takip etmek çok daha etkilidir.
Bu aslında yanlış. Daha verimli değil. Gerçekten sadece bir alışkanlık.
Diğer solo geliştiricilerin yaptığı şey bir taslak veya taslak yazmak, test senaryolarını yazmak ve ardından taslağı nihai kodla doldurmaktır.
Bu çok ama çok verimli.
Ayrıca, gereksinimlerin ve özelliklerin, testlerin sürdürülmesinin bir proje üzerinde önemli miktarda sürükleme sağlayacağı kadar sık sık değiştiğini görüyorum.
Bu da yanlış. Testler sürükleme değildir. Gereksinim değişiklikleri sürükle.
Testleri, gereksinimleri yansıtacak şekilde düzeltmeniz gerekir. Minutiaları olsun ya da olmasın; ilk yazılı veya son yazılı.
Testler geçene kadar kod yapılmadı. Yazılımın tek evrensel gerçeği budur.
Sınırlı bir "işte burada" kabul testine sahip olabilirsiniz.
Veya bazı birim testleriniz olabilir.
Veya ikisine de sahip olabilirsiniz.
Ancak ne yaparsanız yapın, yazılımın çalıştığını göstermek için her zaman bir test vardır.
Biraz formalite ve Nice birim test aracı paketinin bu testi çok daha kullanışlı hale getirdiğini öneririm.
Bir göz bağlantısında çalışabilecek ve yeşil veya kırmızı bir ışık yakabilecek bir test paketiniz olduğunu düşünün. Bu test paketinin test edildiğini düşünün her şey! Test paketini çalıştırmak için tek yapmanız gereken ^ T yazmaktı. Bu size hangi gücü verir?
Bir şeyi kırma korkusu olmadan kodda değişiklik yapabilir misiniz? Eski bir özelliği kırma korkusu olmadan yeni bir özellik ekleyebilir misiniz? Hasar görme korkusu olmadan dağınık kodu hızlı bir şekilde temizleyebilir misiniz?
Evet, tüm bunları yapabilirsin! Ve zamanla kodunuza ne olur? Temizlenir ve temizlenir, çünkü temizlik riski yoktur.
Diyelim ki omzunda küçük bir peri var. Her kod satırı yazdığınızda, peri, test takımına bu kod satırının amaçlananı yaptığını test eden bir şey eklerdi. Böylece her iki saniyede bir ^ T tuşuna basabilir ve yazdığınız son kod satırının işe yaradığını görebilirsiniz.
Ne kadar hata ayıklama yapacağınızı düşünüyorsunuz?
Bu fantezi gibi geliyorsa, haklısın. Ama gerçek çok farklı değil. Göz bağını birkaç saniye ve periyi TDD disiplini ile değiştirin ve hemen hemen aldınız.
Diyelim ki bir yıl önce inşa ettiğiniz bir sisteme geri dönüyorsunuz ve merkezi nesnelerden birini nasıl oluşturacağınızı unuttunuz. O nesneyi her yaratılışında yaratan testler vardır. Bu testleri okuyabilir ve hafızanızı çalıştırabilirsiniz. Bir API çağırmanız mı gerekiyor? Bu API'yi her şekilde çağrılabilecek testler vardır. Bu testler çok az belgeler, anladığınız bir dilde yazılmış. Tamamen açık. Onlar o kadar resmi ki yürütürler. Ve uygulama ile senkronize olamazlar!
Yatırım yapmaya değmez mi? Şaka yapıyor olmalısın! Nasıl birisi bu test paketini isteyemezdi? Kendinize bir iyilik yapın ve saçmalık üzerinde tartışmayı bırakın. TDD'yi iyi yapmayı öğrenin ve ne kadar hızlı gittiğinizi ve kodunuzun ne kadar temiz olduğunu izleyin.
Yaptığınız hata, testi anında geri dönüşü olmayan bir zaman yatırımı olarak görüyor olmanızdır. Mutlaka böyle çalışmaz.
Öncelikle testler yazma really size kodunuzun bu bölümünün ne yapması gerektiğine odaklanır.
İkincisi, onları çalıştırmak, aksi takdirde testte ortaya çıkacak hataları ortaya çıkarır.
Üçüncüsü onları çalıştırmak bazen aksi takdirde test gelmek olmaz ve daha sonra gerçekten üretim eşek eşek ısırır hatalar gösterir.
Dördüncüsü, çalışmakta olan bir sistemde bir hataya çarpar ve bunun için bir birim testi oluşturursanız, daha sonra bu hatayı yeniden tanıtamazsınız. Bu gerçekten büyük bir yardım olabilir. Yeniden verilen hatalar yaygın ve çok can sıkıcıdır.
Beşinci olarak, bir başkasına kod vermeniz gerekiyorsa, bir test takımı hayatlarını çok daha kolay hale getirecektir. Ayrıca, bir projeyi görmezden geldiyseniz ve birkaç yıl sonra geri döndüyseniz, artık ona çok yakın olmayacaksınız ve size de yardımcı olacaktır.
Deneyimlerim, bir projenin geliştirilmesinde, düzgün birim testleri yaptırmanın süreci her zaman daha hızlı ve daha güvenilir hale getirdiğidir.
JUnit'teki (Java Unit test framework) çocuklar, test etmek çok kolaysa, test etmeyin felsefesine sahiptir. Oldukça pragmatik olduğu gibi En İyi Uygulamalar SSS , okumanızı tavsiye ederim.
TDD, yazılımınızı yazmak için farklı bir işlemdir. Birim testinin arkasındaki temel öneri, hata ayıklayıcıda kod adımlarında daha az zaman harcayacağınız ve kod değişikliğinizin sistemde başka bir şeyi yanlışlıkla bozup bozmadığını daha çabuk anlayacağınızdır. TDD'ye uyuyor. TDD döngüsü şöyle:
TDD'nin uygulanmasında daha az belirgin olan şey yazma kodunuzun şeklini değiştirmesidir. Kodun çalışıp çalışmadığını nasıl test edeceğinizi/doğrulayacağınızı düşünmeye zorlayarak, test edilebilir kod yazıyorsunuz. Birim testi konuştuğumuz için, bu genellikle kodunuzun daha modüler hale geldiği anlamına gelir. Bana göre, modüler ve test edilebilir kod büyük bir kazanç.
Şimdi, C # özellikleri gibi şeyleri test etmeniz gerekiyor mu? Şöyle tanımlanmış bir özellik düşünün:
bool IsWorthTesting {get; set;}
Cevap "hayır" olacaktır, çünkü test etmeye değmez, çünkü bu noktada dil özelliğini test ediyorsunuz. Sadece C # platform adamlarının doğru anladığına güven. Ayrıca, başarısız olursa, düzeltmek için ne yapabilirsiniz ?
Ayrıca, kodunuzun düzgün test etmek için çok fazla çaba harcayacağı bazı bölümleri olduğunu göreceksiniz. Bu, bunu yapma anlamına gelmez, ancak zor sorun tarafından kullanılan/kullanılan kodu test ettiğinizden emin olun:
İster inanın ister inanmayın, TDD sürdürülebilir bir gelişim hızına girmenize yardımcı olacaktır. Bu sihir yüzünden değil, sıkı bir geri bildirim döngünüz olduğu ve gerçekten aptalca hataları hızlı bir şekilde yakalayabildiğiniz için. Bu hataları düzeltmenin maliyeti esasen sabittir (en azından planlama amaçları için yeterlidir) çünkü küçük hatalar asla büyük hatalar haline gelmez. Kod binge/debug tasfiye sprintlerin burst yapısı ile karşılaştırın.
Testin maliyetini hataların maliyetiyle dengelemeniz gerekir.
Bir dosyayı açan bir işlev için 10 satırlık birim sınaması yazmak ve hatanın "dosya bulunamadı" ifadesi anlamsızdır.
Karmaşık bir veri yapısı için karmaşık bir şey yapan bir işlev - açıkçası evet.
Zor bit arasında. Ancak, birim testlerin gerçek değerinin belirli bir işlevi test etmediğini, aralarındaki zor etkileşimleri test ettiğini unutmayın. Bu yüzden, bir bit koddaki bir değişikliğin, 1000 satır ötedeki farklı bir modüldeki bazı işlevleri kırdığını, kahve içindeki ağırlığına değer olduğunu gösteren bir birim testi.
Test kumar oynamaktır.
Bir test oluşturmak, bir ünitedeki hataların o testle yakalanıp yakalanmadığı (şimdi ve gelecekteki tüm kod revizyonları sırasında) maliyetinin, testi geliştirme maliyetinden daha yüksek olduğu bir bahistir. Bu test geliştirme maliyetleri, ilave test mühendisliği için bordro, pazara ek süre, diğer şeyleri kodlamamaktan kaynaklanan fırsat kayıpları vb.
Herhangi bir bahis gibi, bazen kazanırsınız, bazen kaybedersiniz.
Bazen çok daha az hata içeren geç yazılımlar, pazara ilk giren hızlı ama buggy şeyler üzerinden kazanır. Bazen tam tersi. Kendi alanınızdaki istatistiklere ve yönetimin ne kadar kumar oynamak istediğine bakmak zorundasınız.
Bazı hata türlerinin, ek spesifik testler oluşturmak için zaman ayırmaya değmeyecek şekilde yapılması veya herhangi bir erken akıl sağlığı testinden çıkarılması pek olası olmayabilir. Ancak bazen bir hatanın maliyeti o kadar büyüktür (tıbbi, nükleer vb.) Bir şirketin kaybedilen bir bahis alması gerekir (sigorta satın almaya benzer). Birçok uygulamanın bu kadar yüksek bir arıza maliyeti yoktur ve bu nedenle daha yüksek ekonomik olmayan sigorta kapsamına ihtiyaç duymazlar. Diğerleri yapar.
Benim tavsiyem sadece düzgün çalışmak istediğiniz kodu test etmektir.
Buggy olmak ve yolda sizin için sorunlara neden olmak istediğiniz kodu test etmeyin.
Bir TDD yaklaşımını denemem gerekip gerekmediğini merak ediyorum. Kulağa iyi bir fikir gibi geliyor, ama dürüst olmak gerekirse, bu ekstra işi asla haklı çıkaramam.
TDD ve Birim Testi aynı şey değildir.
Kod yazıp daha sonra birim testleri ekleyebilirsiniz. Bu TDD değildir ve fazladan bir iştir.
TDD, Kırmızı Işık döngüsünde kodlama uygulamasıdır. Yeşil ışık. Refactor yinelemeleri.
Bu, henüz mevcut olmayan kodlar için testler yazmak, testlerin başarısız olduğunu izlemek, testlerin çalışması için kodu düzeltmek, sonra kodu "doğru" yapmak anlamına gelir. Bu genellikle çalışmanızı azaltır
TDD'nin avantajlarından biri, trivia hakkında düşünme ihtiyacını azaltmasıdır. Tek tek hatalar gibi şeyler kaybolur. Döndürdüğü listenin 0 veya 1'de başlayıp başlamadığını öğrenmek için API belgelerini aramak zorunda değilsiniz, sadece yapın.
Neredeyse her şeyi test ettiğimiz bir sistem üzerinde çalıştım. Test için dikkate değer icralar PDF ve XLS çıktı kodu) idi.
Neden? Verileri toplayan ve çıktıyı oluşturmak için kullanılan modeli oluşturan parçaları test edebildik. Modelin hangi bölümlerinin PDF dosyalarına gideceğini anlayan parçaları da test edebildik. PDF = Tamam görünüyordu çünkü bu tamamen özneldi. PDF] içindeki tüm parçaların tipik kullanıcı ile okunabildiğini test edemedik çünkü bu da özneldi Veya çubuk ve pasta grafikler arasındaki seçim veri kümesi için doğru ise.
Çıktı öznel olacaksa, çabaya değer olanı yapabileceğiniz çok az birim testi vardır.
Birçok şey için, 'yaz-sonra-manuel-test' birkaç test yazmaktan daha fazla zaman almaz. Zaman tasarrufu, bu testleri istediğiniz zaman yeniden çalıştırabilmekten gelir.
Bir düşünün: Testlerinizde iyi bir özellik kapsamı varsa (kod kapsamı ile karıştırılmamalıdır) ve diyelim ki 10 özelliğiniz var - bir düğmeyi tıklamak kabaca, 10 Siz arkanıza yaslanıp kahvenizi yudumlarken testlerinizi yeniden yapıyorsunuz.
Ayrıca minutae test etmek için yok. Nitelikli ayrıntılara inmek istemiyorsanız, özelliklerinizi kapsayan entegrasyon testleri yazabilirsiniz ... IMO, bazı birim testleri, kodu değil dili ve platformu test etmek için çok hassas bir şekilde test edilir.
TL; DR Gerçekten hiçbir zaman uygun çünkü faydalar çok iyi.
Karşılaştığım iki çok iyi cevap burada:
Algılanan ek yükten kaçınmanın gerekçesi:
İşinizin kalitesinin kanıtı olarak harika bir ürünü yanınızdan bırakmak istemez misiniz? Bencil terimlerle konuşmak, sizin için daha iyi değil mi?
Profesyonel geliştiriciler ünite testleri yazarlar, çünkü daha uzun vadede zaman kazanırlar. Er ya da geç kodunuzu test edeceksiniz ve eğer kullanıcılarınız yapmazsanız ve daha sonra hataları düzeltmek zorunda kalırsanız, düzeltmek ve efektleri daha fazla çalmak daha zor olacaktır.
Hiçbir test ile kod yazıyorsanız ve hiçbir hata varsa o zaman iyi. Yine de sıfır hata içeren önemsiz bir sistem yazabileceğinize inanmıyorum, bu yüzden bir şekilde test ettiğinizi varsayıyorum.
Birim kodları, eski kodu değiştirdiğinizde veya yeniden düzenlediğinizde gerilemeleri önlemek için de çok önemlidir. Değil kanıtlamak Değişikliğiniz eski kodu kırmadı ama size çok güven veriyorlar (elbette geçtikleri sürece :))
Geri dönüp zaten göndermiş olduğunuz kod için bir dizi test yazmam, ancak bir dahaki sefere bir özelliği değiştirmeniz gerektiğinde, bu modül veya sınıf için testler yazmaya çalışmanızı öneririm, kapsamınızı% 70'e kadar alın + herhangi bir değişiklik yapmadan önce. Size yardımcı olup olmadığına bakın.
Eğer denerseniz ve dürüstçe o zaman yeterince adil bir yardım olmadığını söyleyebiliriz, ama yaklaşım denerken en azından sizin değerinize yardımcı olmak için yeterli endüstri kanıtı olduğunu düşünüyorum.
Her ne kadar soru TDD hakkında değil, genel olarak birim testleri hakkında sorulsa da, çoğu cevap TDD yanlısı gibi görünüyor.
Ünite testinin veya ünite testinin arkasında tamamen nesnel bir kural yoktur. Ancak, birçok programcının test etmediği birkaç kez var:
OOP felsefenize bağlı olarak, karmaşık rutinleri genel yöntemlerinizden ayırmak için özel yöntemler oluşturabilirsiniz.Genel yöntemler genellikle birçok farklı yerde çağrılır ve sıklıkla kullanılır ve özel yöntemler çok özel bir şey için bir sınıf veya modülde sadece bir veya iki genel yöntemle gerçekten çağırılır.Genel yöntemler için birim testleri yazmak genellikle yeterlidir, ancak sihirin bir kısmını gerçekleştiren temel özel yöntemler değil. özel yöntemle, genel yöntem birimi testleriniz bu sorunları algılayacak kadar iyi olmalıdır.
Birçok yeni programcı, ilk test etmeyi öğrendiklerinde buna karşı çıkıyor ve yürütülen her satırı test etmeleri gerektiğini düşünüyor. Harici bir kitaplık kullanıyorsanız ve işlevselliği yazarları tarafından iyi test edilmiş ve belgelenmişse, birim testlerde belirli işlevleri test etmek genellikle anlamsızdır. Örneğin, birisi, ActiveRecord modelinin veritabanında "before_save" geri çağırma özelliğine sahip bir öznitelik için doğru değere devam ettiğinden emin olmak için bir test yazabilir, ancak bu davranış Rails'te zaten ayrıntılı olarak sınanmış olsa bile. Geri aramanın çağırdığı yöntem (ler), belki de geri arama davranışının kendisi değildir. İçe aktarılan kütüphanelerle ilgili herhangi bir sorun, birim testlerden ziyade kabul testleri ile daha iyi ortaya çıkacaktır.
TDD yapsanız da yapmasanız da her ikisi de geçerli olabilir.
Ken, ben ve diğer birçok geliştirici, kariyerimiz boyunca birkaç kez sizinle aynı sonuca vardık.
Bulacağınıza inandığım gerçeği (diğerleri gibi), uygulamanız için test yazma ilk yatırımının göz korkutucu görünebileceği, ancak iyi yazılmış ve kodunuzun doğru kısımlarını hedeflediklerinde, gerçekten bir ton tasarruf edebilirler. zaman.
Benim en büyük sorunum, mevcut test çerçevelerinde oldu. Aradıklarım gibi hissetmedim, bu yüzden kendi basit çözümümü yedim. Beni regresyon testinin "karanlık tarafına" getirmeme gerçekten yardımcı oldu. Burada yaptığımın temel bir sözde parçacığını paylaşacağım ve umarım sizin için çalışan bir çözüm bulabilirsiniz.
public interface ITest { public string Name { get; } public string Description { get; } public List<ITest> SubTests { get; } public TestResult Execute(); } public class TestResult { public bool Succesful { get; set; } public string ResultMessage { get; set; } private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>(); public Dictionary<ITest, TestResult> SubTestResults { get { return subTestResults; } set { subTestResults = value; } } }
Bundan sonraki tek zor kısım, hangi projeyi yaptığınız için en iyi "paranın karşılığını bulmak" olduğunu düşündüğünüz ayrıntı düzeyini bulmaktır.
Bir adres defteri oluşturmak, kurumsal bir arama motorundan çok daha az test gerektirir, ancak temel bilgiler gerçekten değişmez.
İyi şanslar!