Birim testleri gerçekten bu kadar faydalı mı? [kapalı]


98

CS’de yeni mezun oldum ve şu anda Junior .NET Developer (C #, ASP.NET ve web formları) olarak bir işim var. Hala üniversitedeyken, birim sınama konusu ele alındı, ancak bunun yararlarını hiç görmedim. Ne yapması gerektiğini anladım, yani bir kod bloğunun kullanıma uygun olup olmadığını belirlemek. Ancak, daha önce hiç bir birim testi yazmak zorunda kalmamıştım ya da ihtiyacım olduğunu hiç hissetmedim.

Daha önce de belirttiğim gibi, genellikle ASP.NET web formları ile geliştiriyorum ve son zamanlarda bazı birim testleri yazmayı düşünüyorum. Ama bunun hakkında birkaç sorum var.

Birim testlerinin genellikle "alaycı" yazarak gerçekleştiğini okudum. Bu kavramı anlasam da, tamamen dinamik olan web siteleri için nasıl alaycı yazacağımı ve neredeyse her şeyin bir veritabanından gelen verilere bağlı olduğunu anlayamıyorum. Örneğin: Lot’un ItemDataBound olayları vb. Olan tekrarlayıcıları kullanıyorum (yine "bilinmeyen" verilere bağlı olarak).

Öyleyse soru 1: ASP.NET web'i için birim testleri yazmak sıkça yapılan bir şey oluşturur mu ve eğer: "dinamik ortam" sorununu nasıl çözebilirim?

Gelişmekte olduğumda birçok deneme yanılma geçiriyorum. Bu, ne yaptığımı bilmediğim anlamına gelmez, ama ben genellikle bazı kodlar yazıp vurur Ctrl F5ve ne olduğunu görürüm. Bu yaklaşım çoğu zaman işi yaparken, bazen biraz bilgisiz olduğum hissine kapılıyorum (küçük deneyimim yüzünden). Bazen bunun gibi çok zaman harcıyorum.

Öyleyse, soru 2: Birim testleri yazmaya başlamamı tavsiye eder misiniz? Gerçek uygulamada bana yardımcı olabileceğini düşünüyorum, ama sonra yine beni yavaşlatıyor gibi hissediyorum.


1
Sadece bunun diğer tarafının pratik yapmasını gerektiren bazı yerlerin olduğunu söylemek istiyorum. Şu anda bir birimdeyim, ünite testleri kapsamında olmadığı sürece kodu kontrol etmemize izin verilmedi. Bu yüzden, onlara inanmasanız bile, onları yoldan aşağı yapmanız gerekebileceğini not etmek gerekir. Cephaneliğinde öğrenmenin ve öğrenmenin faydalı bir yetenek olduğunu düşünüyorum. Ben birçok kez testler yapmaktan kaynaklanan kodumda küçük hatalar ve aksilikler göreceksiniz, kendinizle neredeyse küçük bir QA oturumu.
Adam,

9
Herhangi bir ünite testi yazmadan ünite testini tam olarak nasıl yaptınız? Bu okullardan biri "kendini notlandır" veya "kendi müfredatını tasarla" okullarından biri miydi?
JeffO

4
Ünite testleri sorgulanabilir - Dinamik diller için harika, diliniz ne kadar katı olsa da, TESTLERİNİ YAPIN. Birim testi olmaları gerekmez, ancak gerçekten JUnit ile çalıştırabileceğiniz entegrasyon testlerine sahip olmalısınız, bunlar çok faydalıdır.
Bill K,

13
-1 Üzgünüm, aynı fikirde olmasam da, hepiniz iyi tartışmalar için geliyorum ama bu yanlış. Hiç kimse "birim testleri yeni kodta hata yakalamak için" diye iddia etmiyor, bu da saman yönetimi - birim testleri gerilemeleri yakalamak içindir . Ve Dijkstra teklifi bağlam dışına çıkarıldı - bağlam, problemin resmi bir belirtimine sahipseniz testin anlamsız olmasıdır .
sleske

9
"birim testleri, gerilemeleri yakalamak içindir". Hayır. Otomatik testler gerileme yakalamak içindir. Regresyonlar her zaman aynı testlerin yüzlerce kez yapılmasını gerektirir, bu yüzden onları otomatikleştirmek için çaba harcayacaktır. Maalesef, bu soruya verilen cevapların ve yorumların birçoğu "Otomatikleştirilmiş testler yardımcı oluyor mu?" Sorunuyla gerçekten ilgileniyor. Birim testleri, bir otomatik test biçimi olabilir, ancak tamamen farklı bir odağa sahiptirler. Otomatik olarak yapılan testlerin altınları ağırlığına değeceklerini düşünüyorum, ancak birim testlerini (veya bu konuda TDD'yi haklı çıkarmak için bir argüman olarak kullanılmamalıdır).
njr101

Yanıtlar:


124

Benim düşünceme göre: evet onlar, evet de yapmalısın.

  1. Yaptığınız değişikliklerde size güven veriyorlar (her şey hala çalışıyor). Bu güven kodu biçimlendirmek için ihtiyacınız olan şeydir, aksi takdirde bir şeyleri değiştirmekten korkabilirsiniz.

  2. Kodunuzu daha iyi hale getirirler; en basit hatalar, birim testleriyle erken yakalanır. Hataların erken yakalanması ve düzeltilmesi, daha sonra, örneğin uygulama üretimdayken, düzeltilmesinden daha ucuzdur.

  3. Kodunuzun nasıl çalıştığı ve nasıl kullanılacağı konusunda diğer geliştiriciler için bir dokümantasyon görevi görür.

Karşılaştığınız ilk sorun, ASP.NET'in kendi içinde birim sınamaları yazmanıza yardımcı olmamasıdır - aslında size karşı çalışır. Herhangi bir seçeneğiniz varsa , birim testi göz önünde bulundurularak oluşturulan ASP.NET MVC'yi kullanmaya başlayın . ASP.NET MVC'yi kullanamıyorsanız, ASP.NET'te MVP şablonunu kullanmalısınız, böylece en azından mantığınızı kolayca test edebilirsiniz.

Bunun yanı sıra, sadece ünite testleri yazma konusunda uzman olmanız gerekir. TDD'yi uygularsanız, kodunuz test edilebilir (başka bir deyişle güzel ve temiz) oluşturulur.

Sana pratik yapmanı ve programı eşleştirmeni tavsiye ederim. Okurken:

Veya ilk bakış için:


4
Ünite testine yeni başlamış olmakla aynı fikirdeyim. TDD yaklaşımı ile birlikte sadece iyi bir alışkanlık ve kullanışlılık sağlamakla kalmıyor, aynı zamanda çok da zaman alıyor. Yeni bir özellik ekledikten veya bir hatayı düzelttikten sonra bile her şeyin düzgün çalıştığını doğrulayamazsam projelerimin bu kadar kullanışlı olabileceğini düşünmüyorum. Regresyon testi yapmayı başka bir şekilde düşünemiyorum.
kwelch

21
Ünite testleri bir dokümantasyon olarak çalışıyorsa, bir sorun var demektir. 5 satır kodun nasıl çalıştığını anlamak için 500 satır kod okunuyor.
Kodlayıcı

4
@Coder: Daha üst seviye metodları test ederken, 5 kod satırından daha fazlasını içerir.

7
@coder: bir sınıfın belgelendirilmesi size sınıfın örneklerinin sağladığı hizmetleri gösterir. Size, bu sınıfın örneklerinin daha geniş bağlamda, yani nesneler arasındaki etkileşimin nasıl kullanıldığı hakkında daha az bilgi verir. Testler, bazı durumlarda, başlangıç ​​noktası kadar değerli olan bazı durumlarda onları hesaba katmam bile normal olmayan etkileşim kodunu verir.
Stefano Borini

21
@ Kod: Kodun ne yaptığını değil , kodun doğasında olan varsayımları , yani neden ve ne zaman çalışması gerektiğini belgeliyor . Temel varsayımlar SUT'taki bir değişiklikle geçersiz hale gelirse, bir veya daha fazla birim testi başarısız olmalıdır. Bu, üst düzey tasarım / mimari belgelerinin veya hatta XML belgelerinin yerini almaz, ancak bu şeylerin asla yapamayacağı şeyleri kapsar.
Aarona

95

Hayır.

Ünite testlerinin arkasındaki konsept, ünite testinden önce icat edildiğinden beri yanlış olduğu bilinen bir öncül üzerine kuruludur: testlerin kodunuzun doğru olduğunu kanıtlayabileceği fikri.

Herkesin geçeceği çok sayıda test olması bir şeyi ve sadece bir şeyi kanıtlar: hepinizin geçtiği çok sayıda testiniz olduğu. Testlerin neyin test edildiğinin şartnameye uyduğunu kanıtlamaz. Kodunuzu, testleri yazarken hiç göz önünde bulundurmadığınız hatalardan arınmış olduğunu kanıtlamaz. (Test etmeyi düşündüğünüz şeyler odaklandığınız muhtemel konulardı, bu yüzden onları yine de haklamışsınızdır!) Ve son olarak, en önemlisi, testlerin kendileri tarafından kodlandığı kanıtlanamaz. böcek ücretsizdir. (Sonunu mantıklı bir sonuca kadar takip edin ve sonuna kadar kaplumbağalarla bitirin .)

Djikstra , 1988'de, doğruluk kanıtı olarak yapılan testler kavramını 1988'de geri çevirdi ve yazdıklarının bugün olduğu kadar geçerli:

Program testinin böceklerin varlığını ikna edici bir şekilde gösterebildiğine, ancak bunların bulunmadığını asla gösteremediğine dikkat çektiğinden yirmi yıl geçti. Bu kamuoyuna açıklanacak sözünü açık bir şekilde aktardıktan sonra, yazılım mühendisi günün sırasına geri döner ve tıpkı krizokosmik saflaştırmalarını daraltmaya devam eden eski zaman simyacısı gibi test stratejilerini iyileştirmeye devam eder.

Ünite testindeki diğer sorun, kodunuzla test takımı arasında sıkı bir bağlantı oluşturmasıdır. Kodu değiştirdiğinizde, bazı testlerin yapılmasına neden olacak bazı hataların görünmesini beklersiniz. Ancak, gereksinimlerin kendileri değiştiği için kodu değiştiriyorsanız, çok fazla başarısız test alırsınız ve her birini el ile gözden geçirmeniz ve testin hala geçerli olup olmadığına karar vermeniz gerekir. (Ayrıca, daha az yaygın olsa da, geçersiz olması gereken mevcut bir testin hala geçmesi olasıdır, çünkü değiştirilmesi gereken bir şeyi değiştirmeyi unutmuşsunuzdur.)

Ünite testi, gerçekten iyi bir programcı olmadan çalışma kodunu yazmayı kolaylaştıracak vaat eden uzun bir gelişim sürecinin sonuncusudur. Hiçbiri vaatlerini yerine getirmeyi başaramadı ve hiçbiri de yapamadı. Çalışma kodunun nasıl yazılacağını bilmek için kısayol yoktur .

Kararlılık ve güvenilirliğin çok önemli olduğu durumlarda, otomatik testlerin gerçekten yararlı olduğu konusunda bazı raporlar bulunmaktadır. Örneğin, SQLite veritabanı projesi. Ancak , güvenilirlik seviyelerine ulaşmak için gerekenler çoğu projede ekonomik değildir: neredeyse 1200: 1 olan bir test-gerçek-SQLite kod oranı. Çoğu proje bunu karşılayamaz ve yine de buna ihtiyaç duymaz.


69
Bu testler için kodunuzun doğru davrandığını kanıtlar . Bana sorarsan çok garip bir şey.
Stefano Borini

111
Bugün kim aslında birim testlerinin "doğruluk kanıtı" olduğuna inanıyor? Bunu kimse düşünmemeli. Yalnızca bu sınamaların geçtiğini kanıtlamaları doğru, ancak birim sınamalarını yazmadan önce sahip olduğunuzdan daha fazla veri noktası olması doğru. Kodunuzun kalitesine ilişkin bilgi edinmek için birçok farklı katmanda test yapmanız gerekir. Birim testleri, kodunuzun hatasız olmadığını kanıtlamaz, ancak kodun sizin için tasarladığınız şeyi yaptığına ve bugün ne yaptığını yarın yapmaya devam edeceğinize dair güveninizi artırır (veya gerekir).
Bryan Oakley

40
> but if the test itself is buggy, then you have false confidenceve manuel test cihazı işini doğru şekilde yapmazsa, ayrıca yanlış güven duyuyorsunuz.
Stefano Borini

33
@MasonWheeler: Üzgünüm, Mason, ikna olmadım. Birkaç on yıldan fazla bir süredir programlamada, bir testin sahte bir güvenlik hissi verdiği kişisel bir olay gördüğümü sanmıyorum. Belki bazıları yaptı ve biz onları düzelttik, ama hiçbir şekilde bu ünite testlerinin maliyeti, sahip olmanın muazzam faydalarından ağır basmadı. Ünite düzeyinde test etmeden kod yazabiliyorsanız, etkilendim, ancak programcıların büyük çoğunluğu, bunu tutarlı bir şekilde yapamıyor.
Bryan Oakley

41
Kodunuzun geçtiğine dair bir deneme testi yazdıysanız, kodunuz da muhtemelen buggy’dir. Buggy kodu ve buggy testi yazma şansı, yalnızca buggy kodundan çok daha az. Birim testleri her derde deva değil. Manuel test cihazlarındaki yükü azaltmak için iyi bir ekstra katmandır (ihtiyatlı).
Telastyn

60

Okul için küçük bir kod parçasını test etmek için ana bir yöntem yazmanın faydasını gördüyseniz, birim testi aynı uygulamanın profesyonel / kurumsal versiyonudur.

Ayrıca, kodu oluşturmayı, yerel web sunucunuzu başlatmayı, söz konusu sayfaya göz atmayı, verileri girmeyi veya girdiyi uygun test tohumuna ayarlamayı, formu göndermeyi ve sonuçları analiz etmeyi düşünün… nUnit run düğmesi.

İşte çok eğlenceli bir resim. görüntü tanımını buraya girin

Bu resmi burada buldum:
http://www.howtogeek.com/102420/geeks-versus-non-geeks-when-doing-repetitive-tasks-funny-chart/


2
Evet yapabilirsin. Web yapılandırmasını (URLS, giriş doğrulama, vb.) Test etmek için web katmanını birim sınamalarınızda yalıtın. Web ve veritabanı katmanlarını saplayarak, iş katmanını bir veritabanı veya web sunucusu olmadan test edebilirsiniz. DB'imi sınamak için dbunit kullanıyorum. İsterseniz hala tam entegrasyon testi yapabilirsiniz, ancak bunu geliştirme sonrası belirli bir görev olarak yapıyorum.
Heath Lilley

12
Sevimli grafik, ama ölçeği çok yanlış. Cevabımda belirttiğim gibi, SQLite'in tam test kapsamı, testlerdeki ürünün gerçek kodundan ziyade yaklaşık 1200x daha fazla kod gerektiriyor. Tam kapsama konusunda o kadar takıntılı olmasanız bile , testlerinizde herhangi bir faydalı kapsam seviyesine yaklaşmak için bile üründen birkaç kat daha fazla teste ihtiyacınız var. Burada doğru olması için, bu kırmızı çizginin dikey kısmının yaklaşık 3 sayfa uzunluğunda yukarı ve yukarı doğru devam etmesi gerekir.
Mason Wheeler,

27
@MasonWheeler Bu çok güzel bir at, attığın çok güzel bir at, sanırım yine de ölmüş olabilir ... SQLite çok fazla test yapmış çünkü lanet olası bir veritabanı. İşe yaradığından emin olmak istiyorum. Başka bir örnek olarak, Silverstripe çerçevesi 1: 1 test oranına yakın: kod, bu yüzden SQLite'nin temsil ettiği gibi değil.
12'de Aatch

15
@MasonWheeler Zeno'nun paradokslarının ilkinde başarısız oluyorsunuz . Bu görüntüyü SQLite test seviyesine yükseltmek istiyorsanız, X ekseni aynı zamanda mevcut uzunluğunun 100 katı gibi bir şey genişletmek zorunda kalacak.
Izkata

2
Bu, özellikle arka uç mantığınızı test edebilmeniz için siyah beyaz bir web sayfası oluşturmaya başlama zamanı olmayan bir arka uç geliştiricisi olduğunuzda geçerlidir. Yapmam gereken tek şey, sahte istek ve oturum nesneleri sağlamak ve denetleyicilerimi bir birim testiyle çalıştırmak ve bunların sonunda doğru mu yanlış mı olduğunu biliyorum. DI kullanıyorsanız, veritabanınızın değişmemesi veya atması için basit bir veri tabanı ile etkileşime giren bir DAO enjekte Exceptionedin. Birim testine EVET diyorum.
Varun Achar

49

Ünite testinin bugünlerde bu konuda gizemli bir şeyleri var. İnsanlar,% 100 test kapsamı kutsal bir kâse ve ünite testi, yazılım geliştirmenin Tek Doğru Yolu gibi görünüyor.

Noktayı kaçırıyorlar.

Ünite testi cevap değildir. Test etmek.

Şimdi, bu tartışma ne zaman ortaya çıksa, birisi (çoğu zaman ben bile) Dijkstra'nın sözünü ortadan kaldıracaktır: "Program testi böceklerin varlığını gösterebilir, ancak onların yokluğunu asla göstermez." Dijkstra haklıdır: Yazılımın amaçlandığı gibi çalıştığını kanıtlamak için test yapmak yeterli değildir. Ancak bu gereklidir : bir düzeyde, yazılımın istediğini yaptığını göstermek mümkün olmalıdır .

Birçok insan elle test eder. Hatta TDD meraklıları bile bazen kabul etmeyecekleri halde manuel test yapacaklar. Yardımcı olamaz: Yazılımınızı müşterinize / patronunuza / yatırımcılarınıza / vb. Gibi göstermek için konferans odasına girmeden hemen önce çalışacağından emin olmak için elden geçireceksiniz. Bunda yanlış olan bir şey yok ve aslında herşeyin elle geçmeden her şeyin yolunda gitmesini beklemek delilik olurdu - yani, test -% 100 ünite test kapsamınız olsa ve testlerinize maksimum güven duysanız bile .

Ancak yazılım oluşturmak için gerekli olsa bile manuel testler nadiren yeterlidir . Neden? Çünkü manuel testler sıkıcı ve zaman alıcıdır ve insanlar tarafından gerçekleştirilir. Ve insanlar sıkıcı ve zaman alıcı görevler yapmakta zorlanıyorlar: mümkün olduğunda bunları yapmaktan kaçınıyorlar ve çoğu zaman zorlandıkları zaman iyi yapmıyorlar.

Makineler , diğer taraftan, olan mükemmel sıkıcı ve zaman alıcı görevleri yerine de. Sonuçta bilgisayarların icat ettiği şey buydu.

Bu nedenle testler çok önemlidir ve otomatik testler , testlerinizin tutarlı bir şekilde kullanılmasını sağlamanın tek mantıklı yoludur. Yazılım geliştirildiğinden test etmek ve yeniden test etmek de önemlidir. Buradaki bir başka cevap, regresyon testinin önemine işaret etmektedir . Yazılım sistemlerinin karmaşıklığı nedeniyle, sistemin bir bölümünde sıkça görünüşte zararsız değişiklikler sistemin diğer bölümlerinde istenmeyen değişikliklere (yani hatalara) neden olur. Bu istenmeyen değişiklikleri bir tür test yapmadan keşfedemezsiniz. Testleriniz hakkında güvenilir veriler elde etmek istiyorsanız, testlerinizi sistematik bir şekilde yapmanız gerekir, bu da bir çeşit otomatik test sistemine sahip olmanız gerektiği anlamına gelir.

Bütün bunların birim testiyle ne ilgisi var? Tabi, doğası gereği, ünite testleri, bir insan tarafından değil, makine tarafından yapılır. Bu nedenle, birçok insan otomatik testlerin birim testlerine eşit olduğu konusunda yanlış izlenim altındadır . Ancak bu doğru değil: birim testleri sadece çok küçük otomatik testlerdir.

Şimdi, ekstra küçük otomatik testlerin değeri nedir? Bunun avantajı, test sisteminin daha kesin hedeflenmesini sağlayan ve hata ayıklamaya yardımcı olan bir yazılım sisteminin bileşenlerini yalıtımlı olarak test etmeleridir . Ancak ünite testi aslında yüksek kaliteli testler anlamına gelmez . Yazılım, daha ince detay düzeyindeki yazılımı kaplamasından dolayı genellikle daha yüksek kalite testlerine yol açar. Ancak, sadece komple bir sistemin davranışını test etmek mümkündür, kompozit parçalarını değil, yine de tamamen test etmek mümkündür.

Ancak% 100 ünite test kapsamı ile bile, bir sistem hala tam olarak test edilemeyebilir. Çünkü tek tek bileşenler mükemmel şekilde yalıtılmış halde çalışabilir, ancak birlikte kullanıldığında hala başarısız olabilirler. Bu nedenle, ünite testi, oldukça faydalı olmasına rağmen , yazılımın beklendiği gibi çalışmasını sağlamak için yeterli değildir . Aslında, birçok geliştirici otomatik entegrasyon testleri, otomatik fonksiyonel testler ve manuel testler ile birim testlerini tamamlar.

Birim testlerinde değer göremiyorsanız, belki de en iyi başlamanın yolu farklı bir otomatik test türünü kullanmaktır. Bir web ortamında, Selenium gibi bir tarayıcı otomasyon test aracı kullanmak, nispeten küçük bir yatırım için genellikle büyük bir kazanç sağlayacaktır. Parmaklarınızı suya batırdıktan sonra, otomatikleştirilmiş testlerin ne kadar yararlı olduğunu görebileceksiniz. Ve otomatikleştirilmiş testler yaptıktan sonra, birim testi çok daha mantıklıdır çünkü büyük entegrasyon veya uçtan uca testlerden daha hızlı geri dönüş sağlar çünkü şu anda üzerinde çalışmakta olduğunuz bileşen üzerinde testleri hedefleyebilirsiniz.

TL; DR: henüz ünite testi için endişelenmeyin . İlk önce yazılımınızı test etmekten endişe edin.


Birim testleri de insanlar tarafından yazılmış ve yanlış olabilir.
Seun Osewa

41

Değişir

Bu, yazılım geliştirmeye gelince çokça göreceğiniz bir cevaptır, ancak birim testlerinin kullanışlılığı gerçekten ne kadar iyi yazıldığına bağlıdır. Regresyon testi için uygulamanın işlevselliğini kontrol eden nominal sayıda birim testi oldukça yararlı olabilir; bununla birlikte, işlevlerin geri dönüşünü kontrol eden basit testlerin bir kısmı oldukça işe yaramaz ve yanlış bir güvenlik hissi sağlar çünkü uygulama "çok sayıda birim testine sahiptir".

Ayrıca, geliştirici olarak geçirdiğiniz zaman değerlidir ve birim testleri yazmaya harcanan zaman yeni özellikler yazmaya harcanan zaman değildir. Yine, bu, ünite testleri yazmamanız gerektiği anlamına gelmez, ancak her ortak fonksiyonun ünite testine ihtiyacı var mı? Cevabın hayır olduğunu söyleyebilirim. Kullanıcı girişi doğrulaması yapan kod birim testine ihtiyaç duyuyor mu? Oldukça muhtemel, uygulamalarda yaygın bir başarısızlık noktasıdır.

Bu, deneyimin devreye girdiği alanlardan biridir, zamanla uygulamanın ünite testinden yararlanabilecek kısımlarını tanıyacaksınız, ancak o noktaya ulaşmadan önce bir süre kalacaktır.


Bu iyi bir nokta. SUT değerini yakalayan iyi testlerin nasıl yazılacağını bilmek zorundasınız.
Andy,

3
Bu temelde birim testleri nasıl yapmam gerektiğini öğretti - ilk önce en önemli / kırılabilir durumları kapsayan testleri yaz ve sonra varsayımların yanlış çıktığında daha fazla test ekle (bir şeyin "asla başarısız olamayacağını" düşündüm, ama yaptı) .
Brendan Long,

38

Üniversite dersleri için yapılan projeler, işinizde yazacağınız iş uygulamalarından büyük ölçüde farklılık gösterir. Aradaki fark ömürdür. Üniversite projesi ne kadar süreyle "yaşıyor"? Çoğu durumda, ilk kod satırını yazdığınızda başlar ve işaretinizi aldığınızda biter. Bunu söyleyebilirsin, etkili bir şekilde sadece uygulama zamanı için yaşar. “Bırakma” genellikle “ölümüne” eşittir.

İş için yapılan yazılımlar, üniversite projesinin bu serbest bırakma noktasını aşıyor ve iş ihtiyaç duyduğu sürece yaşamayı sürdürüyor. Bu çok uzun . Para hakkında konuşurken, hiç kimse "daha serin ve düzgün bir kod" için kırılmış bir kuruş harcamaz. 25 yıl önce C’de yazılan yazılım hala çalışıyorsa ve yeterince iyi ise (işletme sahibinin ihtiyaçları tarafından anlaşıldığı gibi), sürdürülmesini beklemelisiniz (yeni özellikler eklemek, eskilerini geliştirmek - kaynak kodunu değiştirmek ).

Çok önemli bir noktaya geldik - gerileme . Çalıştığım yerde iki uygulamayı tutan iki ekibimiz var; birincisi, 5-6 yıl önce çok az kod testi kapsamı * ile yazdı ve ikincisi, ilk testin tam gelişmiş test paketi (ünite, entegrasyon ve başka ne değil) ile daha yeni bir sürümü . Her iki takımın da manuel (insan) test uzmanları var. İlk takım için yeni, oldukça temel bir özellik tanıtmanın ne kadar sürdüğünü bilmek ister misiniz? 3 ila 4 hafta. Bu sürenin yarısı "her şeyin hala çalışıp çalışmadığını kontrol etmek". Bu, manuel testçiler için yoğun bir zamandır. Telefonlar çalıyor, insanlar üzülüyor, bir şey yine bozuldu. İkinci takım genellikle 3 günden daha kısa sürede bu tür meselelerle ilgilenir.

Hiçbir şekilde ünite testlerinin kod hatalarınızı eğilimli, doğru ya da bulabileceğiniz diğer süslü sözcükler haline getirdiğini söylemiyorum. Her ikisi de böcekleri sihirli bir şekilde ortadan kaldırmaz. Ancak, diğer otomatik yazılım test yöntemleri ile birleştirildiğinde, uygulamalarınızı, diğerlerinden daha fazla sürdürülebilir hale getirir. Bu büyük bir kazanç.

Ve sonuncusu ama en önemlisi, Brian'ın yorumunu yaptığını düşünüyorum.

(...) kodun sizin için tasarladığınız şeyi yaptığına ve yarın da bugün yaptığı şeyi yapmaya devam ettiğine dair kendinize olan güveninizi (veya ... gerekir).

Çünkü bugün ve yarın arasında, birisi çok önemli rapor üretici kodunun çökmesine neden olacak küçük değişiklikler yapabilir . Testler, müşteriniz sizin tarafınızdan biraz önce yapmadan önce bunu farketme ihtimalinizi artırın.

* Yavaş yavaş kod üssüne gittikçe daha fazla test yapıyorlar, ancak hepimiz bu şeylerin nasıl göründüğünü biliyoruz.


10
Software_Regression'a bağlanmak için +1000. Kolejler ünite testlerini tam anlamıyla inancınız dışında yapmanız gereken bir şey olarak ortaya koyar, bunu önlemek ve kontrol etmek için bir hastalık olduğunu ve bu hastalığın regresyon olarak adlandırıldığını ayrıntılı olarak açıklamadan . (o halde, regresyon testlerinin birim testlerden çok farklı bir problemi var, çünkü onu iyi açıklayan tek okudum bu kitabın ücretsiz örneği ).
ZJR

25

ASP.NET web için sıkça yapılan bir şeyi sınamak için birim testleri yazıyor ve öyleyse: "dinamik ortam" sorununu nasıl çözerim?

Sık sık yapılmaz. UI öğeleriyle çalışmak, birim testlerinin iyi olduğu anlamına gelmez, çünkü programlı olarak doğru şeylerin ekranda doğru yerlerde olduğunu doğrulamak için harika bir yol yoktur.

Birim testleri yazmaya başlamamı tavsiye eder misiniz? Gerçek uygulamada bana yardımcı olabileceğini düşünüyorum, ama sonra yine beni yavaşlatıyor gibi hissediyorum.

Varsa, evet. Belirli vakaların tekrarlanabilir bir şekilde doğrulanmasında çok yardımcı olabilirler. Sorunlu değişikliklere karşı 'sürtünme' ve daha iyi değişiklikler yaparken güvenli olmayan davranma gibi davranırlar.

Unutulmaması gereken bir şey , genellikle sizi yavaşlatacak olmasıdır.

Tamamdır.

Şimdi biraz zaman harcamak (eğer iyi yapılırsa) ileride size zaman kazandıracak, çünkü bazı böcekleri yakalarlar, bazı böceklerin tekrarlanmasını önler ve kodda çürümeyi engellemek için diğer iyileştirmeleri yaparken biraz daha rahat olmanıza izin verir.


8
Aslında sorunun kullanım durumunu yanıtlayan +1! Diğer herkes "birim testi" bölümüne atladı ve "ASP.NET web formları" bölümünü
unuttu

1
Bu, büyük bir cevap ve daha fazla önem kazanmayı hak ediyor, bunun nedeni, soruları ele almış olmanız ve geliştiriciyi yavaşlatmaya değer verdiğiniz ve her hatanın yakalanacağı veya önleneceğine dair söz vermediğiniz için dürüst olmanız gerektiğidir; Son derece doğru.
Mantorok

11

Sadece CS dereceyle mezun oldum ve şu anda küçük bir .NET geliştiricisi olarak bir işim var (C # ve genellikle ASP.NET, web formları - ASP.NET MVC değil). Hala üniversitedeyken, birim sınama konusu ele alındı, ancak bunun faydalarını hiç görmedim.

Çünkü hiç büyük programlama yapmadın.

Ne yapması gerektiğini anlıyorum - bir kod bloğu olup olmadığını belirlemek> kullanıma uygun - ancak daha önce hiç bir birim testi yazmak zorunda kalmamıştım. (ne de .. hiç ihtiyacım olmadı mı?)

Birim testleri yazmak, kodunuzu test edilebilir, iyi belgelenmiş ve güvenilir bir zihinsel yapıya uymaya zorlar. İddia ettiğinden çok daha fazlası.

-Benim testlerin sıklıkla "alaycı" yazarak yapıldığını okudum. Bu kavramı anlasam da, tamamen dinamik olan web siteleri için nasıl alay yazmam gerektiğini ve neredeyse her şeyin bir veritabanından gelen verilere bağlı olduğunu anlayamıyorum.

veritabanı erişimini, iyi tanımlanmış, sabit kodlanmış verilerle dolu model sınıflarını döndüren sahte sınıfla alay edin. veya bir test veritabanını fikstür verileriyle doldurun ve oradan çalışın.

- Birim testleri yazmaya başlamamı tavsiye eder misiniz?

tabi lan. Önce Beck'in "Test Odaklı Gelişimini" okuyun .

Gerçek uygulamada bana yardımcı olabileceğini düşünüyorum, ama sonra yine beni yavaşlatıyor gibi hissediyorum.

Şimdi seni yavaşlatıyor. Ancak gün yerine saatlerce hata ayıklamak zorunda kaldığınızda fikrinizi değiştirirsiniz.

Herhangi bir tavsiye takdir edilecektir :)

Ölçek. Güven Bana. Maalesef aynı zamanda bir yönetim politikası da olmalı, ancak zaman kazandıran bir şey. Testler kalıyor, oradalar, şimdi ve gelecekte. Platformu değiştirip testleri yürüttüğünüzde ve hala çalışıyorlarsa, eşyalarınızın beklendiği gibi çalıştığını biliyorsunuzdur .


8

Düzenleme: Elbette TDD yanlısı / con dogpile katıldı ve 1 numaralı soruyu atladım:

1 - ASP.net web formlarında birim testlerini uygulamak:

Her şeyden önce, onları MVC ile gitmelerini sağlayabileceğinizi düşünüyorsanız, kuduz bir mağara gibi onun için savaşın. Bir ön uç / UI dev olarak, .net MVC .net'ten nefret etmeme son vermeme yardımcı oldu. Böylece, şimdiye kadar karşılaştığım her Java web çözümünden nefret etmeye daha iyi konsantre olabilirim. Birim testleri sorunlu çünkü web formları sunucu ile müşteri tarafı arasındaki çizgileri gerçekten bulanıklaştırıyor. Birim testi yapmaya çalıştığımda, veri manipülasyonuna odaklanacağım ve (umarım) web formlarının başlık altında sizin için kullanıcı girişinin normalleşmesini ele alacağını farz ediyorum.

2 - İlk olarak birim testlerinin değerli olup olmadığı hakkında:

Tamam, tam açıklama:

  • Ben çoğunlukla kendi kendime öğrendim. Örgün eğitimim, bir JavaScript, bir PHP ve bir C # sınıfına ve kendi kişisel OOP prensipleri çalışmasına ve Tasarım Desenleri gibi şeyler okumaktan hoşlanıyor.

Ancak,

  • Genellikle istemci tarafı ağ için yazıyorum ve bunun gerçek programlama kısmı, dinamik yazma, birinci sınıf fonksiyonlar ve nesne değişkenliği açısından en hızlı ve en gevşek dillerden biri.

Bu, aynı derleyici veya sanal makine için yazmıyorum anlamına gelir. Üç dilin 4-20 farklı yorumunu yapıyorum (evet, ikisi sadece yalnızca bildirimsel olmakla kalmayıp aynı zamanda bazen farklı şekillerde çalıştığım UI'nin temel fiziksel alanını belirlemek için) bugün olduğundan çok daha çeşitli. Ve hayır, sadece tek kullanımlık uygulamalar için JQuery işlerine takılan bir çocuk değilim. Çok sayıda UI öğesi karmaşıklığı ile oldukça karmaşık şeylerin oluşturulmasına ve korunmasına yardımcı oluyorum.

Yani, evet, burada birkaç tweaks için burada ve tasarım becerileriniz tam bir saçmalıksa veya 1-2 kalitedeki problemlerde büyük miktarlarda vasat devs atıyorsanız, büyük bir hata dizisi oluşturmak için birçok fırsat var.

TDD'nin sizin için yapması gereken şey hakkındaki anlayışım, testlerin sizi tasarımı daha dikkatli düşünmeye ve gereksinimlere odaklanmaya zorlama konusunda gerçekten daha fazla olması gerektiğidir. Yeterince adil, ancak buradaki sorun, yapmanız gereken şeyi, bir arayüze tasarım yapan, incelikle fakat temelde farklı olan bir arayüze ilişkin testler için tasarladığı şeydir. Benim aramdaki fark, annenin anlamını tahmin etmek zorunda kalmayacağı net bir resim çizmek ve tüm sayfayı gerçekten hızlı bir şekilde yeşil ile doldurmak arasındadır, böylece masadaki boya kalemi tokatlayan ve bağıran ilk çocuk olabilirsiniz "bitti! " Proses ve tasarıma göre sonuçlara öncelik vererek, temel olarak, ilk etapta sorunlarınızın özünde olan çöp kodunun sürekli uygulanmasını teşvik ediyorsunuz.

Ve sonra elbette ki “gerçek olmayan nokta” ama sık sık övgüde bulunan yan testler, regresyon hatalarını saptamanıza yardımcı olmak için ünite testlerinin kendileri için de yanlıştır. TDD'nin savunucuları, bunun aslında amaç mı yoksa sadece şık bir yan etki mi olduğu konusunda biraz isteksiz olmaya meyillidirler çünkü IMO'yu çok iyi biliyorlar ya da en azından bunun sizin için böceklerin yokluğunu tespit etmek için yeterli olmadığını düşünüyorlar. Kod, özellikle JavaScript gibi daha dinamik bir dilde, uzun bir bağımlılık zincirinde olası her senaryoyu bile tahmin edebileceğinizi varsaymak aptallıktır.

JS'de otomatik test yapmak için bir yer var, ancak zamanınızın çok daha iyi kullanılması, bir başkasıyla temasa geçen kodunuzun her bir birisine bir birim testi eklemek yerine, bir demetiniz olmadığından emin olmaktır. İşi çoğaltan veya kullanım amacı orada ilk başta orada anlamsal olarak belirsiz olan çöp nesneleri. DRY prensibine uyuyorsunuz. Yapma değeri belirginleştiğinde (bir dakika önce değil), yeniden kullanım / taşınabilirlik için şeyleri soyutlarsınız. Çubuk prensibinden çok bir havuçtan sonra bir şeyler yapmanın tutarlı süreçlerini ve yöntemlerini belirlersiniz (örneğin, yanlış bir şekilde yapmak istemeyi zahmet etmek için eşyalarınızı doğru şekilde kullanmak çok kolaydır). Ve her şeyin aşkı ve barı sevgisi için, hiçbir zaman yeniden kodlama aracı olarak devasa basamaklı miras planına karşı anti-kalıplara düşkün olmaz.

Yukarıdakilerin hepsi kodumdaki teşhis edilmesi zor hataları ciddi bir şekilde azaltmamda bana yardımcı oldu ve sizden daha iyi söyleyebilecek bir şeyi olmayan bir tarayıcı setine sahip bir geliştirici olarak gelen biri için bunun büyük bir öncelik olduğuna güvenebilirsiniz. " Belirtilmemiş bir dosyada bu hayali satır numarasında 'Object' türünde bir nesne ile ilgili bir sorun var. " (Tanrım, IE6'ye teşekkür ederim) TDD, benim çalışma alanımda bu şeyleri cesaretlendirmezdi. A ve B noktalarının arasında çalıştığı sürece gerçekten önemli olmadığı süreç boyunca odağı% 100 sonuçlara kaydırır. Eşyalarınızın okunaklı, taşınabilir ve ilk etapta çok fazla kafa karıştırıcı kırılmadan değiştirilmesi kolay olduğundan emin olmak için daha iyi uygulanacak bir zaman kaybıdır.

Belki de kök saldığım paradigma hakkında aşırı derecede ustaca davranıyorum, ama bence, ilk etapta doğru yapmak, sizin veya diğer herkes için ne zaman olduğunuz için takım yanlış yapar. Ve hiçbir şey sizi, sadece bir şeyleri hayata geçirme konusunda tasarım düşünmeye zorlamamalıdır. Tasarım her programcının garip sunağı olmalı. Sizi doğru olanı yapmaya “zorlayan” veya sizi kendinizden koruyan her şey, IMO şişeleri için ayrılan aynı şüpheyle görülmelidir. Modern BT'de yılan yağı ve genel gelişme, eğer henüz farkında değilseniz, sıvı ton tarafından satılmaktadır.


1
Çok fazla birim testi yapıyorum. Onlar olmadan kod yazmayacağım. Ama senin duygularına katılıyorum. Testler gerektiğini kılavuz değil, sürücü gelişimini. Bir problem hakkında dikkatlice düşünmeyi otomatikleştiremezsiniz.
FizzyTea

Otomatik sınama konusunda hiçbir sorunum yok. Ancak, her kavşaktaki toptan alımlar benim için bir süreçten çok panik gibi gözüküyor. Tasarım için zamandan tasarruf etmek ve kontrol etmediğiniz çeşitli şeylerle etkileşime girme ihtimalinizin olduğu noktalarda test ve onaylamayı otomatikleştirmek, nasıl tercih ettiğimdir.
Erik Reppen

5

Tecrübelerime göre, onlarla başladığınızda ve onlarla kaldığınızda , yani Test Odaklı Gelişme gibi , birim testleri gerçekten çok faydalıdır . İşte nedeni:

  • Birim testleri, ne yaptığınızı ve bunu yapan kodu yazmadan önce ne aldığınızı doğrulamak için sizi düşünmeye zorlar . Bir TDD senaryosunda, önce testi yazın. Böylece yazmak üzere olduğunuz kodun ne yapması gerektiğini ve daha sonra kodu yazarak "yeşil" yaptığınız "kırmızı" bir sınama yazmak için başarılı bir şekilde yaptığını nasıl doğrulayabileceğinizi bilmek zorundasınız. Bunu geçmek. Bu, çoğu durumda sizi, bu testi geçmek üzere yazmak üzere olduğunuz algoritma hakkında biraz daha fazla düşünmeye zorlar; bu, mantık hatalarını ve "köşe davalarını" azalttığından her zaman iyi bir şeydir. Testi yazarken, “bunun nasıl başarısız olabileceğini ” ve “ burada neyi test etmiyorum ” diye düşünüyorsunuz, bu da daha sağlam bir algoritmaya yol açıyor.

  • Birim testleri, yazmak üzere olduğunuz kodun nasıl tüketileceğini düşünmenize zorlar . TDD'yi öğrenmeden önce, bir şekilde çalışacak bir bağımlılık bekleyen kod yazdığım ÇOK zamanlar oldu ve daha sonra tamamen farklı bir şekilde çalışan bir meslektaşım tarafından yazılmış bir bağımlılık verildi. TDD ile bu hala mümkün olsa da, yazdığınız ünite testi sizi yazdığınız nesneyi nasıl kullanmak istediğinizi düşünmeye zorlar, çünkü söz konusu nesnenin örnek bir kullanımıdır. Daha sonra nesneyi, tüketilmesi kolay bir şekilde ve böylece gerekirse uyarlamak için yazacaksınız (önceden tanımlanmış arayüzlere programlama yapmak TDD gerektirmeyen bu soruna daha iyi bir genel çözüm olsa da).

  • Birim testleri "test ederek kodlamanızı" sağlar . ReSharper gibi bir refactoring aracı, izin verirseniz en iyi arkadaşınız olabilir. Bir testte kullanımı tanımlarken, yeni işlevlerin iskeletini tanımlamak için kullanabilirsiniz.

    Örneğin, yeni bir MyClass nesnesi oluşturmanız gerektiğini söyleyin. Bir MyClass örneği oluşturarak başlayın. ReSharper, "Ancak MyClass mevcut değil!" "Öyleyse yarat" dedin, Alt + Enter tuşlarına basarak. Ve sizlere sınıf tanımınızı verin. Bir sonraki test kod satırında MyMethod metodunu çağırırsınız. ReSharper, "Ama bu yok!" Diyor. "Öyleyse oluştur", bir Alt + Enter tuşuyla tekrarlayın. Birkaç tuşa basarak, yeni kodunuzun "iskeletini" tanımladınız. Kullanımı ortadan kaldırmaya devam ettiğinizde, IDE bir şeyin ne zaman uymadığını size söyleyecektir ve genellikle çözüm, IDE'nin veya fişe takılan bir aracın nasıl tamir edileceğini bilmesi kadar kolaydır.

    Daha aşırı örnekler "Triple-A" modeline uygundur; "Düzen, Hareket, Assert". Her şeyi ayarlayın, test ettiğiniz gerçek mantığı uygulayın ve ardından mantığın doğru olduğunu onaylayın. Bu şekilde kodlama yaparak, çözümü teste kodlamak çok doğaldır; daha sonra, birkaç tuşa basarak, bu mantığı çıkarabilir ve üretim kodunda kullanılabileceği bir yere koyabilir, ardından testte mantığın yeni konumuna işaret eden küçük değişiklikler yapabilirsiniz. Bu şekilde yapmak, kodu modüler, yeniden kullanımı kolay bir şekilde yapmanıza zorlar, çünkü test ettiğiniz birimlerin hala erişilebilir olması gerekir.

  • Birim testleri, aklınıza gelebilecek tüm manuel testlerden daha hızlıdır. Daha büyük projeler için, çok hızlı bir şekilde karşılanan bir nokta var; burada birim testinin genel gider süresi, manuel olarak test edilmek üzere harcanan zamanı azaltarak, kendisi için ödeme yapmaya başlar. Her zaman az önce yazdığınız kodu çalıştırmanız gerekir. Geleneksel olarak, el ile yaptınız, büyük bir program başlatarak, davranışı değiştirdiğiniz durumu ayarlamak için kullanıcı arayüzünde gezinerek ve ardından sonuçları kullanıcı arayüzünde veya üretilen veri biçiminde tekrar doğrulayarak. Kod TDDed ise, sadece birim testlerini çalıştırırsınız. İyi birim testleri yazıyorsanız, ikinci seçenek öncekinden daha hızlı olacaktır.

  • Birim testleri regresyonu yakalar . Yine, girdiğim TDD'yi öğrendiğimden, bir kod parçasına yapılan cerrahi bir değişiklik olduğunu düşündüğüm, değişikliğin rapor edilen durumda hatalı bir davranışı (veya yeni istenen bir davranışı ürettiğini) doğruladığını doğrulamadan önce birçok kez oldu. , ve yalnızca, değişikliğin aynı kod bloğunu tekrar kullanmaya başlayan tamamen farklı bir modülde başka bir köşe kasasını kırdığını bulmak için onu kontrol etti. Bir TDDed projesinde, yapmak üzere olduğum bir değişikliği doğrulamak için bir test yazabilirim, değişikliği yapabilirim, sonra tam paketi çalıştırabilirim ve kodun diğer tüm kullanımları TDDed ise ve değişikliğim bir şeyi bozduysa, bu testler için diğer şeyler başarısız olacak ve ben araştırabilirim.

    Geliştiriciler, potansiyel bir değişiklikten etkilenebilecek tüm kod satırlarını manuel olarak bulup test etmek zorunda kalırlarsa, hiçbir zaman bir şey olmazdı, çünkü bir değişimin etkisini belirleme maliyeti değişikliği mümkün kılar. En azından hiçbir şey KATI olmaz ve böylece kolayca korunur, çünkü hiçbir zaman birden fazla yerde kullanılabilecek hiçbir şeye dokunmaya cesaret edemezsiniz; bunun yerine, bu dava için kendi benzer-ama-birleştirici-küçük-değişiklik çözümünüzü alırsınız, SRP'yi ve muhtemelen OCP'yi ihlal eder ve kod tabanınızı yavaş yavaş bir patchwork yorganına çevirirsiniz.

  • Birim testler mimariyi tipik olarak avantajlı bir şekilde şekillendirir . Birim testleri, başka herhangi bir mantıktan izole edilmiş olarak yapılan testlerdir. Kodunuzu test ünitesine edebilmek için, o zaman, bu şekilde kod yazmak gerekir Eğer canizole et. Gevşek bağlanma ve bağımlılık enjeksiyonu gibi iyi tasarım kararları, böylece TDD sürecinden doğal olarak ayrılır; bağımlılıkların enjekte edilmesi gerekir; böylece bir testte, "yan etkiler" oluşturmadan test edilen durum için girdi ya da işleme üreten bir "alay" ya da "saplama" enjekte edebilirsiniz. TDD'nin “ilk kullanım” zihniyeti genellikle, gevşek bağlamanın özü olan “arayüzlere kodlama” ya yol açar. Bu iyi tasarım ilkeleri daha sonra büyük bir kodbaz kütlesi adaptasyonuna ihtiyaç duyulmaksızın bütün bir sınıfı değiştirmek gibi üretimde değişiklik yapmanızı sağlar.

  • Birim testleri göstermek kod yerine, işe yaradığını kanıtlayan kod eserler . İlk bakışta bir dezavantaj olduğunu düşünebilirsiniz; elbette kanıt gösteriden daha iyidir? Teori harika; hesaplamalı ve algoritmik teori işimizin temelidir. Ama, bir doğruluğundan matematiksel kanıtı algoritmanın olduğu değil doğruluğunun kanıtıdır uygulanması . Bir matematiksel kanıt sadece algoritmaya bağlı kodun doğru olması gerektiğini gösterir . Bir birim test aslında yazılı kod yapacağını düşündü yapar ve bu kanıt böylece olduğunu gösterir ise doğru. Bu genel olarak teorik bir kanıtdan çok daha değerlidir.

Şimdi, tüm bunlar birimin test edilmesinin dezavantajları var:

  • Her şeyi test edemezsin. Sisteminizi, bir ünite testi kapsamına girmeyen LOC sayısını en aza indirmek için yapılandırabilirsiniz, ancak sistemin test edilemeyen belirli alanları olacak. Veri erişim katmanınız, başka bir kod tarafından kullanıldığında alay edilebilir, ancak veri erişim katmanının kendisi çok fazla yan etki içerir ve genellikle bir Depo veya DAO'nun çoğu (çoğu) birim testini yapmak uygun değildir. Benzer şekilde, dosyaları kullanan, ağ bağlantılarını düzenleyen kodlar vb. Yerleşik yan etkilere sahiptir ve bunu yapan kod satırını test edemezsiniz. UI öğeleri genellikle birim testinden geçirilemez; olay işleyicileri gibi kod bağlama yöntemlerini test edebilir, test kurucularını ünite edebilir ve işleyicilerin takılı olduğunu doğrulayabilirsiniz, ancak bir kullanıcının fareyi belirli bir grafik eleman üzerinde tıklayıp işleyicinin çağrılmasının izlenmesi için kod yerine geçmeyen bir şey yoktur. Neyin test edilebileceği ve yeterince test edilemeyeceği arasındaki bu sınırlara ulaşmak “kum havuzunun kenarını kazımak” olarak adlandırılır; Bu noktadan sonra, davranışı doğrulamak için entegrasyon testleri, otomatik kabul testleri ve manuel test kullanmakla sınırlandırılırsınız.

  • Birim testinin birçok avantajı TDD olmadan uygulanmaz. Kod yazmak, sonra kodu kullanan testleri yazmak mükemmel bir şekilde mümkündür. Hala “birim testler” dır, ancak ilk önce kod yazarak, "ilk önce test" geliştirilmesinin doğasında var olan avantajların çoğunu kaybedersiniz: kodun mutlaka kolayca test edilebilecek, hatta üretimde kullanılabilecek şekilde tasarlanması gerekmez ; testi yazarken ve neyi düşünmediğinizi düşünmek için doğada "çift kontrol" düşünme sürecine sahip değilsiniz; test ederek kod yazmazsınız; ve kod yazarsanız, manuel olarak test edin ve çalıştığını görün, sonra hatalı olan bir ünite testini kodlayın, hangisi yanlış, kod veya test? Başlıca avantajlarınız, regresyonun önlenmesi (daha önce testlerinden geçen kodun başarısız olduğu durumlarda uyarı verilecek) ve manuel teste karşı yüksek hızlı doğrulamadır. TDD kaybı

  • Birim testi bir ek yük sunar . Oldukça basit, yazdığınız kodu test etmek için kod yazıyorsunuz. Bu mutlaka bir geliştirme projesinin toplam LOC'sini artıracaktır ve evet, testler için LOC, gerçek proje için LOC'yi aşabilir. Naif geliştiriciler ve geliştiriciler bu durumlara bakacak ve testlerin zaman kaybı olduğunu söyleyecek.

  • Birim testi disiplin gerektirir. Kod tabanını yeterli şekilde uygulayacak testler yazmalısınız (iyi kod kapsamı), düzenli olarak çalıştırmalısınız (bir değişiklik yaptığınız zamanki gibi, tam süit çalıştırılmalı) ve her şeyi "yeşil" tutmalısınız ( tüm testler geçiyor). İşler koptuğunda, beklentileri karşılamayan kodu düzelterek ya da testlerin beklentilerini güncelleyerek bunları düzeltmeniz gerekir. Eğer testleri değiştirirseniz, "neden" diye sormalı ve kendinize çok yakından bakmalısınız; mevcut davranışla eşleşmek için başarısız olan iddiaları basitçe değiştirmek ya da başarısız olan testleri kaldırmak inanılmaz derecede caziptir; Ancak, bu testler gereksinimlere dayanmalıdır ve bu ikisi eşleşmediğinde bir sorun yaşarsınız. Bu şeyler yapılmazsa,

  • Birim testi daha fazla ekipman gerektirir. Yukarıdaki disipline duyulan ihtiyacın olağan çözümü ve insanların doğal olarak tembel ve sıkışma eğilimi göstermesi, birim testleri gerçekleştiren, hesaplayan, TeamCity, CruiseControl, vb. kod kapsamı ölçütleri ve "üçlü-C" (kodlama kurallarına uygunluk, la FxCop) gibi başka denetimler de vardır. Kurulum botu için donanım makul bir performans sergilemelidir (aksi takdirde ortalama takımın yapacağı kod giriş hızına uymayacaktır) ve bottaki giriş prosedürleri güncel tutulmalıdır (eğer yeni bir birim test kütüphanesi oluşturulur, birim testlerini çalıştıran derleme komut dosyaları bu kütüphaneye bakmak için değiştirilmelidir). Bu göründüğünden daha az iş, ancak tipik olarak, takımdaki çeşitli yapı süreçlerinin nitrit kumluğunun nasıl çalıştığını bilen (ve dolayısıyla onları komut dosyalarında otomatik hale getirip, söz konusu komut dosyalarını koruyabilen) bilen birkaç kişi için bazı teknik uzmanlık gerektirir. Ayrıca, yapı "bozulduğunda" dikkat edilmesi ve yeni bir şeyi kontrol etmeden önce yapının bozulmasına (doğru) neden olanı düzeltmek için disiplini gerektirir.

  • Birim testi, kodun ideal olmayan bir şekilde tasarlanmasına zorlayabilir . TDD tipik olarak kodun modülerliği ve yeniden kullanılabilirliği için iyidir, ancak kodun uygun erişilebilirliğine zarar verebilir. Üretim kütüphanelerine yerleştirilen nesneler ve üyeler, doğrudan birim testleri tarafından kullanılıyorlarsa, özel veya dahili olamazlar. Bu, şimdi bir nesneyi gören diğer kodlayıcıların kütüphanede bulunan başka bir şeyi kullanmaları gerektiğinde kullanmaya çalıştıklarında sorunlara neden olabilir. Kod incelemeleri bu konuda yardımcı olabilir, ancak bir sorun olabilir.

  • Birim testi genellikle "hızlı uygulama geliştirme" kodlama stillerini yasaklar. Birim testleri yazıyorsanız, "hızlı ve gevşek" kodlamıyorsunuz. Bu genellikle iyi bir şeydir, ancak kontrolünüzün dışından dayatılan bir son tarihin altındayken veya çok küçük kapsamlı bir değişiklik uyguluyorsanız ve paydaş (veya patronunuz) tüm bu zorluğun neden sadece olmak zorunda olduğunu merak ediyordur. bir kod satırını değiştirmek, sadece uygun birim test takımını yazmak ve bakım yapmak mümkün olmayabilir. Çevik süreçler, genellikle geliştiricilere zaman gereksinimlerinde söz hakkı vererek bu konuda yardımcı olur; Unutmayın, tüm satış elemanlarının yapması gereken "evet yapabiliriz" demek ve süreç, "hayır yapamayız" diyen ve aslında dikkat edilmeyen "işi yapması gereken insanları içermiyorsa, komisyon kontrolünü alıyorlar." Ancak, herkesin Çevik ve Çevik'in kendi sınırlamaları yoktur.


4

Ünite testleri doğru kullanıldığında faydalıdır; mantığınızla ilgili çeşitli problemler var.

“Gelişirken çok sayıda deneme yanılma geçiriyorum” dedi Kevin.

Programlamaya tesadüfen bakın. Bir kodun ne yapması gerektiğini anlamak ve daha sonra bunu bir birim testiyle yaptığını kanıtlamak daha iyidir. Bir kodun sadece çalıştığını varsaymayın, çünkü programı çalıştırdığınızda UI kırılmaz!

s writing unit tests for ASP.NET web forms something that is done often

İnsanların web formlarını ne sıklıkta test ettiklerini söyleyecek istatistiksel verilerim yok. Sorun değil. UI'nin test edilmesi zordur ve Birim Testleri de bir UI'ye bağlanmamalıdır. Mantığınızı test edilebilecek sınıf kitaplıklarına, katmanlara ayırın. Kullanıcı arabirimini arka uç mantığından ayrı olarak test edin.

So, question number 2: Would you guys advise me to start writing unit tests?

Evet. Onlara alışınca, seni hızlandırırlar. Bakım, ilk geliştirme aşamasından çok daha fazla zaman alıcı ve maliyetlidir. İlk testlerde ve hata onarımlarında bile ünite testlerinde bakım büyük ölçüde desteklenir.


Sayfaların farklı senaryolarda başarıyla yüklenip yüklenmediğini test etmek için aspx sayfalarında testler yapabilen test çerçeveleri vardır. Bu yeterince iyi olmayabilir, ama hiç yoktan iyidir.
Awe

4

Pratik düzeyde Ünite testleri çok önemli bir nedenden ötürü son derece yararlı olabilir : Bir kerede bir bit kodunu test edebilirsiniz.

Bir dizi karmaşık adım dizisi yazdığınızda ve sonunda hata ayıkladığınızda, birçok hata bulma eğilimindesiniz ve işlem daha zordur çünkü işlem boyunca daha ilerlersiniz. Visual Studio'da hızlı bir test oluşturabilir, biraz değiştirebilir ve SADECE bu testi çalıştırabilirsiniz . Daha sonra, örneğin bu yöntemi çağıran bir yöntemin buna güvenebileceğini biliyorsunuz. Böylece güven artar.

Birim testleri programınızın doğru olduğunu kanıtlamaz! : Birim testleri hassas koddaki gerilemeleri kontrol eder ve yazdığınız yeni yöntemleri test etmenizi sağlar.

Ünite testleri ön uçları sınama amaçlı değildir : Bir ünite testini, kodunuzun yerine getirmesi gereken bir koşul değil, yazdığınız yeni bir yöntemi veya bir şeyi test etmek için oluşturduğunuz küçük proje olarak düşünün.

Ünite testi işbirlikçi ortamlar için harikadır : Eğer benim için tamamen farklı bir teknoloji kullanan bir meslektaşıma, örneğin iOS'tan çağırdığı bir yöntem sunmak zorunda kalırsam, hızlı bir şekilde bir testi test edebilirim. istediği yöntem a) Doğru verileri yeniden başlatır b) Özelliklerine göre performans gösterir c) Kötü bir darboğaz yok.


"Ünite testleri ön uçları sınama amaçlı değil" kim söylüyor? Ben sorgulamıyorum. Bilmek isterdim çünkü birçok insan yanlış bir fikre sahip görünüyor ve bu kadar etkili olmayan TDD-savunucusu-kaynak-sopasıyla ilgili sopayı kimlerle boğmak istiyorum.
Erik Reppen

Benim de dahil olduğum bazı insanlar, ilk testler ile karşılaştığında bu yanılgıya sahipti, ben de bunu temizliyorum. Neden sana meydan okuyormuşum gibi hissettiğini bilmiyorum, aslında sana tamamen katılıyorum.
Tjaart

4

Dokunulmamış gibi görünen bir şey, farklı kod türlerini test etmenin karmaşıklığıdır.

Basit girdi ve çıktılara sahip işlerle uğraşırken, genellikle birim testi yapmak kolaydır ve testler test edilen kodun son durumları göz önüne alınarak seçilirse, size doğru olduklarına büyük bir güven verecektir. Böyle bir kod için test yazmamak deli olur. (Kütüphanelere giren çoğu kodun bu kriterleri karşıladığını unutmayın.)

Bununla birlikte, diğer durumlarda, kodun karmaşık temel verilerle (genellikle bir veritabanı olmak zorunda değil) olması ya da çok karmaşık çıktı verileri ürettiği için (genellikle bir veritabanı olmak zorunda değildir) test etmek için büyük alaylar yapmak zorunda kalırsınız. oldukça aşırı bir örnek için oyun seviyesine bir tohum değeri) ve birim testi neredeyse o kadar kullanışlı değil. Test vakalarınızdaki her şeyi örtmek genellikle bir hayaldir ve bir hata bulduğunuzda, neredeyse her zaman hiç düşünmediğiniz bir durumdur ve bu nedenle zaten bir test yapamazsınız.

Gümüş mermi yoktur, gümüş mermi olarak gösterilen hiçbir şey, savunucularının iddia ettiği kadar iyi değildir, ancak bu yararsız olduğu anlamına gelmez.


4

ASP.NET Web formları uygulaması için birim testleri yazmak yaygın değildir ve başarılması çok zordur. Ancak, projenin onu atlaması gerektiği anlamına gelmez.

Birim testleri, corner stoneskritik görev uygulamalarıdır ve temel işlevselliğin beklendiği gibi gerçekleştirdiği güvenilirliği ve rahatlığı sağlar.

Aslında , web form geliştirme işleminde kullanılabilecek bir ASP.NET MVP deseni ile birim testini çok daha kolay bir şekilde yapabilirsiniz. Endişelerin ayrılığını getirecek ve ability to write essential unit tests.

Bakılması yararlı olabilecek bazı referanslar:


2
+1 Birim testleri yapıp yapmamanız önemli değil, MVP, Web Formlarıyla (belki de WinForms de) çalışmanın yoludur.
simoraman

3

Ünite testlerinin amacı, sistem içinde bir şeyi kırabileceğiniz korkusu olmadan kodunuzu (yeniden düzenleme, iyileştirme vb.) Güvenle değiştirmenize olanak sağlamaktır. Bu, kod değişikliğinizin tüm etkilerini gerçekten bilmiyorsanız (gevşek bağlantıya rağmen), büyük uygulamalar için çok faydalı olduğunu kanıtlar.


6
Korkusuz sahte bir güvenlik hissidir.
Coder

Belki "daha az korku" daha iyi bir cümledir, ancak cevap hala büyük ölçüde doğrudur.
Brendan Long

1
@Coder Testler yeniden yapılanmadan sonra geçerse, koddaki iyileştirmelerin uygulamanın davranış şeklini değiştirmediğinden emin olabilirsiniz (kabaca konuşursanız, yeni hatalar eklemediniz, ancak bu kesin olarak doğru değil çünkü başaramazsınız. % 100 test kapsamı).
m3th0dman

2

Benim deneyimim, evet , birim testlerinin faydalı olması.

Birim Testi, yazdığınız kodun bölümlerini ayırmak ve bunların yalıtılmış olarak çalışmasını sağlamakla ilgilidir. Bu izolasyon gerçekten test ettiğiniz nesne ile konuşmak için sahte veya alaycı nesneler yaratmayı içerebilir veya içermeyebilir. Nesnenizin mimarisine çok bağlıdır.

Birim testi çeşitli avantajlar sağlar:

Öncelikle, bu test ettiğiniz birimlerin sizin, geliştiricinin, çalışması gerektiğini düşündüğü şekilde çalışmasını sağlar. Bu göründüğünden daha az olmasına rağmen: mutlaka nesnenin doğru çalıştığını söylemez; Sadece nasıl çalışması gerektiğini düşündüğünüzü çalışıyorsa, birim test etmeden gerekli olan deneme yanılma yönteminden çok daha güçlü bir ifadedir.

Ek olarak, birimlerin sizin, geliştiricinin de çalışması gerektiğini düşündüğü şekilde çalışmaya devam etmesini sağlar . Yazılım değişiklikleri ve bu beklenmedik şekillerde birimleri etkileyebilir.

Başka yan etkisi test üniteleri anlamına gelir ki bunu izole bir şekilde. Bu genellikle, somut sınıflardan ziyade arayüzlere programlamaya başladığınız, eşleşmeyi azalttığınız ve uyumu arttıracağınız anlamına gelir: iyi tasarımın tüm ortak özellikleri. Evet: sadece kod Birimlerinizi sağlayarak sahip doğal olarak kod tasarımını artıracak birim testleri.

Ancak...

Birim Testi, testin sonu değildir. Diğer test türleri hala gereklidir. Örneğin, birimlerin çalışmalarını beklediğiniz şekilde çalıştığını gösterseniz bile, her bir birimin onunla konuşan birimlerin çalışmasını beklediği gibi çalıştığını göstermeniz gerekir. Başka bir deyişle, bileşenleriniz birbiriyle doğru bir şekilde bütünleşiyor mu?


1

Test edilecek az sayıda katmana sahip basit uygulamalar için (Ana pencere -> alt menü), belki de değişiklikleri kontrol etmek için çalıştırmayı derlemek tamamdır.

Test ettiğiniz sayfayı 30 dakika boyunca kullanabilmeniz için navigasyonun sürdüğü daha büyük uygulamalar için bu çok pahalı olur.


1

Buna yeni bir taraf eklemek istiyorum (aslında, oldukça eski): ünite testleri, kodunuz iyi tasarlanmışsa , bu yararlı değildir .

Programcıların çoğunun artık program tasarımı yapmadığını biliyorum, hala yapıyorum ve birim testlerini TDD kültürüne uymak için oldukça zaman alan bir ihtiyaç olarak buldum, ancak şu ana kadar sadece 1-2 çocuk tanıdım Kodumdaki binlerce test satırında hatalar var - sadece yazdıklarım değil, aynı zamanda resmi test uzmanlarının yazdıkları.

Sanırım artık program tasarımını da yapmayacaksınız - şu anki insanlar sizi yapmamanız için bir kalıba baskı yapacak - ama belki de ünite testinin tasarıma kıyasla çok çok düşük verimli bir yöntem olduğunu hatırlamakta fayda var.

Bu bir dijsktraian argümanıdır: birim testi ancak çalıştırılacak kadar ayrıntılı bir programa karşı çalıştırılabilir.

Kodunuzu yazmadan önce akış çizelgeleri / durum / eylem diyagramları, sıra diyagramları, nesne stokları (ve son ve en az, sınıf diyagramları) çizerseniz, sadece etrafta dolaşarak potansiyel olarak tehdit edici hataları giderebilirsiniz Hatlarını ve isimlerini kontrol ediyorum.

Günümüzde sınıf diyagramları, yüzlerce, bazen binlerce sınıfı içeren koddan üretilir ve tamamen kullanılamaz durumdadır - 15'ten fazla eleman içeren herhangi bir şey, insanın tanınmasının ötesindedir.

Hangi 10 + -5 sınıfının önemli olduğunu veya şu anda ne yaptığınızı bilmeniz ve kodunuzu birden fazla bakış açısıyla kontrol edebilmeniz gerekir, her bir şema bakmakta olduğunuz bakış açılarını TAMAMEN olarak gösterir ve binlerce hatayı öldürürsünüz kağıtta.

  • Türlerin karşılanıp karşılanmadığını dinamik bir kodda kontrol etme (yalnızca akış / akış şemasındaki giriş / çıkış türlerini gösterip bunları bir kurşun kalemle veya farklı bir renkle bağlayarak)
  • tüm durumların kontrol edilip edilmediğini kontrol etme (koşullarınızın tamlığını kontrol ederek),
  • Her şeyin sonlandığından emin olmak için çizgilerin izlenmesi (her akış şeması matematiksel olarak düşünmek için tam olarak tanımlanmış bir sonlu durum otomatı olmalıdır)
  • belirli bileşenlerin birbirleriyle ilgisi olmamasını sağlamak (tüm bağımlılıklarını çıkararak) (güvenlik için iyi)
  • bağımlılıkları ilişkilendirmeye dönüştürerek kodu basitleştirme (bağımlılıklar üye yöntemlerinin kullandığı sınıflardan gelir)
  • adları denetleme, genel önekleri arama, eş anlamlıları silme vb.

çok daha kolay var ...

Ayrıca, başvurularımın daha kullanışlı olduğunu, doğrudan kullanım durumlarından geliyorlarsa ... kullanım durumları iyi yazılmışsa (ACTOR fiil konusu, Maintainer bankamatik açmak istiyor) ... öğrendim.

Kod 95% +% kod toplama yaptım. Tabii ki bazen birim testleri yapıyorum, esp. hesaplamalardaki sınır kontrolleri için, ancak yeniden yapılanmalar için bile ünite testlerini kullanmadığım için ciddi gerilemelere (ciddi: 24 saat içinde silinmiyor) henüz cevap veremedim.

Bazen 3-4 gün boyunca tek bir kod satırı bile çizemiyorum, sadece çiziyorum. Sonra bir günde 1500-2000 satır yazarım. Ertesi gün, çoğunlukla üretime hazırlar. Bazen birim testleri (% 80 + kapsama alanıyla) yazılır, bazen (ek olarak) test uzmanlarından bunu denemeleri istenir, her seferinde, bazı kişilerden inceleyerek incelemeleri istenir.

Bu birim testlerini bir şey bulan için henüz görmedim.

Tasarım düşüncesinin TDD'nin yerine geçmesini isterdim ... ama TDD çok daha kolay, bir balyozla birlikte gitmek gibi ... düşünmek için tasarım yapmak gerekiyor ve çoğu zaman klavyeden uzaktasınız.


Sanırım klavyede tasarlayabilirsin. Ancak, kodu planlamak ve organize etmek, yekpare işlevler olabilecek sınıflardaki girdilerden çıktıya geçmekten ziyade daha fazla düşünce gerektirir.
Erik Reppen

İnan bana, yekpare fonksiyonlar bir A4 (veya ABD Mektubu) kağıdına uymuyor. Bazen tembel olduğumda klavyede "tasarım" yapıyorum, ancak bu aynı kalitede değil. Ne zaman ciddi bir gelişme göstersem UML ile tasarım yapıyorum. Bunları çizerken, kendinize ve başkalarına çok sınırlı ama yine de yapılandırılmış bir şekilde neler olduğunu ve her bakış açısıyla kodu açıklayabildiğiniz zaman anlatmaya çalışıyorsunuz. içinde ve aniden tüm hatalarınız en çok yazım hataları oluyor ...
Aadaam
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.