Bir birim testini nasıl birim test edersiniz? [kapalı]


89

MVCStoreFront Uygulamasında Rob Connerys web yayınlarını izliyordum ve onun en sıradan şeyleri bile birim test ettiğini fark ettim, örneğin:

public Decimal DiscountPrice
{
   get
   {
       return this.Price - this.Discount;
   }
}

Şöyle bir test olacaktı:

[TestMethod]
public void Test_DiscountPrice
{
    Product p = new Product();
    p.Price = 100;
    p.Discount = 20;
    Assert.IsEqual(p.DiscountPrice,80);
}

Ben tamamen birim testi için çalışıyorum, bazen bu test ilk geliştirme biçiminin gerçekten faydalı olup olmadığını merak ediyorum, örneğin gerçek bir süreçte kodunuzun 3-4 katmanı var (İş İsteği, Gereksinimler Belgesi, Mimari Belgesi) , burada gerçek tanımlanmış iş kuralı (İndirim Fiyatı Fiyat - İndirimdir) yanlış tanımlanabilir.

Durum buysa, birim testinizin sizin için hiçbir anlamı yoktur.

Ek olarak, birim testiniz başka bir başarısızlık noktasıdır:

[TestMethod]
public void Test_DiscountPrice
{
    Product p = new Product();
    p.Price = 100;
    p.Discount = 20;
    Assert.IsEqual(p.DiscountPrice,90);
}

Şimdi test kusurlu. Açıkçası basit bir testte, önemli değil, ancak karmaşık bir iş kuralını test ettiğimizi varsayalım. Burada ne kazanıyoruz?

Bakım geliştiricilerin bakımını yaparken, uygulamanın ömrünü iki yıl ileri sarın. Şimdi işletme kuralını değiştirir ve test tekrar bozulur, daha sonra bazı çaylak geliştiriciler testi yanlış bir şekilde düzeltir ... şimdi başka bir başarısızlık noktamız var.

Tek gördüğüm, gerçek bir geri dönüşü olmayan daha olası başarısızlık noktaları, indirim fiyatı yanlışsa, test ekibi yine de sorunu bulacak, birim testi nasıl herhangi bir işi kurtardı?

Burada neyi özlüyorum? Lütfen bana TDD'yi sevmeyi öğret, çünkü şimdiye kadar onu yararlı olarak kabul etmekte zorlanıyorum. Ben de istiyorum çünkü ilerici kalmak istiyorum ama bu bana mantıklı gelmiyor.

DÜZENLEME: Birkaç kişi testin spesifikasyonu uygulamaya yardımcı olduğundan bahsetti. Spesifikasyonların da çoğu zaman yanlış olduğu benim deneyimim oldu, ancak belki de spesifikasyonların spesifikasyon yazmaması gereken kişiler tarafından yazıldığı bir organizasyonda çalışmaya mahkumum.


5
birçok durumda birim test olan Spec ve dokümantasyon da!
Steven

32
... ve sonra birim, birim testinin birim testini test eder ... peki ya birim ^ 4 testi ve birim ^ 5 testi ... aaaaaaaaahhhhhhhhh!
dacracot

14
Hiçbir test türü sizi yanlış spesifikasyondan kurtarmaz.
Bill the Lizard

4
Bir el çırpma sesini duyan var mı?
gnovice

9
Bence uygun alıntı "Kaplumbağalar tamamen aşağılar."
Quinn Taylor

Yanıtlar:


63

Birincisi, test etmek güvenlik gibidir - buna sahip olduğunuzdan asla% 100 emin olamazsınız, ancak her katman daha fazla güven ve kalan sorunları daha kolay düzeltmek için bir çerçeve ekler.

İkincisi, testleri daha sonra test edilebilecek alt yordamlara ayırabilirsiniz. 20 benzer testiniz olduğunda, bir (test edilmiş) alt rutin yapmak, ana testinizin, alt rutinin 20 basit çağrısı olduğu anlamına gelir ve bu da doğru olma olasılığı çok daha yüksektir.

Üçüncüsü, bazıları TDD'nin bu endişeye hitap ettiğini iddia edebilir . Yani, sadece 20 test yazarsanız ve geçerlerse, aslında herhangi bir şeyi test ettiklerinden tamamen emin olamazsınız. Ancak, yazdığınız her test başarısız olursa ve sonra düzeltirseniz , kodunuzu gerçekten test ettiğinden çok daha emin olursunuz. IMHO bu ileri geri, değdiğinden daha fazla zaman alır, ancak endişenizi gidermeye çalışan bir süreçtir.


2
Şeytanları savunmak için, ek katmanları olası başarısızlık noktaları olarak görüyorum, bu benim için güveni artırmıyor. Gerçek işimde, yüksek düzeyde dağıtılmış bir SOA işletmesinde birçok ekiple çalışıyorum. Bu ekiplerin her biri, katmanları başarısız olursa projeyi tehlikeye atabilir.
FlySwat

2
Bu nedenle, her katmanı ayrı ayrı test etmek için sahte nesneler kullanıyorsunuz.
Toon Krijthe

10
Harika, bu yüzden testim IMockedComplexObject kullanarak geçecek ama gerçekte bir ComplexObject'i gerçek dünyada kullandığımda başarısız oluyor ... Yine hiçbir şey kazanmadım.
FlySwat

16
@Jonathan - hayır, ComplexObject arayüzünü geliştirdiğinizi ve bu arayüze karşı yeterince test ettiğinizi varsayarak, kodunuzun çalıştığına dair güven kazandınız. En kötüsü, ComplexObject anlayışınızın beklediğiniz gibi olmadığı bilgisini kazandınız.
tvanfosson

9
@FlySwat: IMockedComplexObject hakkındaki yorumunuza cevaben, Cwash'ın başka bir cevapla ilgili yorumundan alıntı yapıyorum: "Test etmeye çalıştığınız şeyle alay etmiyorsunuz, test etmeye çalışmadığınız şeyle alay ediyorsunuz."
Brian

39

Yanlış olan bir testin üretim kodunuzu bozması olası değildir. En azından hiç test yapmamaktan daha kötü değil. Yani bu bir "başarısızlık noktası" değildir: ürünün gerçekten çalışması için testlerin doğru olması gerekmez. Çalışmak üzere imzalanmadan önce doğru olmaları gerekebilir, ancak bozuk testleri düzeltme süreci uygulama kodunuzu tehlikeye atmaz.

Testleri, hatta bunun gibi önemsiz testleri bile, kodun ne yapması gerektiği konusunda ikinci bir görüş olarak düşünebilirsiniz. Bir görüş test, diğeri ise uygulama. Kabul etmezlerse, bir sorununuz olduğunu bilirsiniz ve daha yakından bakarsınız.

Gelecekte biri aynı arayüzü sıfırdan uygulamak isterse de yararlıdır. İndirimin ne anlama geldiğini bilmek için ilk uygulamayı okumaları gerekmemelidir ve testler, sahip olabileceğiniz arayüzün herhangi bir yazılı açıklamasının kesin bir yedeklemesi olarak işlev görür.

Bununla birlikte, zamanla ticaret yapıyorsunuz. Bu önemsiz testleri atlayarak kazandığınız zamanı kullanarak yazdığınız başka testler varsa, belki daha değerli olabilirler. Bu, test kurulumunuza ve uygulamanın doğasına bağlıdır. İndirim uygulama için önemliyse, bu yöntemdeki hataları yine de işlevsel testte yakalayacaksınız. Tüm birim testlerinin yaptığı, uygulamanın birbirine entegre edilmesini beklemek yerine, bu birimi test ettiğiniz noktada, hatanın yeri hemen belli olduğunda yakalamanıza izin verir ve hatanın konumu daha az belirgin olabilir .

Bu arada, şahsen ben test senaryosunda fiyat olarak 100 kullanmazdım (daha doğrusu, eğer yaptıysam o zaman başka bir fiyatla başka bir test eklerdim). Bunun nedeni, gelecekte birisinin İndirim'in bir yüzde olması gerektiğini düşünmesidir. Bunun gibi önemsiz testlerin bir amacı, spesifikasyonu okurken hataların düzeltilmesini sağlamaktır.

[Düzenleme ile ilgili olarak: Yanlış bir spesifikasyonun bir başarısızlık noktası olmasının kaçınılmaz olduğunu düşünüyorum. Uygulamanın ne yapması gerektiğini bilmiyorsanız, o zaman muhtemelen yapmayacaktır. Ancak şartnameyi yansıtacak testler yazmak bu sorunu büyütmez, yalnızca çözemez. Yani yeni başarısızlık noktaları eklemiyorsunuz, sadece waffle dokümantasyonu yerine koddaki mevcut hataları temsil ediyorsunuz .]


4
Yanlış bir test, kırılmış kodun doğaya girmesine neden olur. Başarısızlığın ortaya çıktığı yer burasıdır. Yanlış bir güven duygusu sağlar.
FlySwat

9
Bu doğru, ancak test yapılmaması da bozuk kodun çıkmasına izin verir. Hata, kod birim testini geçerse bunun doğru olması gerektiğini düşünmektir - kariyerimde oldukça erken bir zamanda bundan kurtulmuştum. Yani bozuk bir birim testi, kırılmış kodun doğaya dağılmasına izin vermez, sadece entegrasyon testine girmesine izin verir.
Steve Jessop

7
Ayrıca, yanlış bir test bile, uygulamadan farklı hatalar içerdiği sürece bozuk kodu yakalayabilir. Demek istediğim, testlerin kesinlikle doğru olması gerekmiyor, bunlar dikkatinizi ilgi alanlarına çekmek için oradalar.
Steve Jessop

2
çok ilginç cevap.
Peter

22

Tek gördüğüm, gerçek bir geri dönüşü olmayan daha olası başarısızlık noktaları, indirim fiyatı yanlışsa, test ekibi yine de sorunu bulacak, birim testi nasıl herhangi bir işi kurtardı?

Birim testinin gerçekten işi kurtarması gerekmiyor, hataları bulmanıza ve önlemenize yardımcı olması gerekiyor. Bu daha çok iş, ama doğru iş. Kodunuzu en düşük ayrıntı düzeyinde düşünmek ve belirli bir girdi kümesi için beklenen koşullar altında çalıştığını kanıtlayan test senaryoları yazmaktır. Değişkenleri izole eder, böylece bir hata kendini gösterdiğinde doğru yere bakarak zaman kazanabilirsiniz . Onun tasarrufu Eğer yolda bir değişiklik yapmak zorunda tekrar tekrar kullanabilirsiniz böylece testlerin o paketi.

Ben şahsen metodolojilerin çoğunun, kargo kült yazılım mühendisliğinden , buna TDD dahil, ancak birim testinin avantajlarından yararlanmak için katı TDD'ye bağlı kalmak zorunda değilsiniz. İyi parçaları saklayın ve az fayda sağlayan parçaları atın.

Son olarak, " Bir birim testini nasıl birim test edersiniz? " Başlıklı başlıklı sorunuzun yanıtı, buna gerek olmaması gerektiğidir. Her birim testi beyin ölümü kadar basit olmalıdır. Belirli bir girdiye sahip bir yöntemi çağırın ve onu beklenen çıktıyla karşılaştırın. Bir yöntemin belirtimi değişirse, o yöntem için bazı birim testlerinin de değişmesi gerekeceğini bekleyebilirsiniz. Bu kadar düşük bir ayrıntı düzeyinde birim testi yapmanızın nedenlerinden biri budur, bu nedenle yalnızca bazıları birim testlerinin değişmesi gerekir. Bir gereksinimdeki tek bir değişiklik için birçok farklı yöntem için yapılan testlerin değiştiğini fark ederseniz, yeterince ince bir ayrıntı düzeyinde test etmiyor olabilirsiniz.


"Belirli bir girdiye sahip bir yöntemi çağırın ve onu beklenen çıktıyla karşılaştırın." ama ya çıktı karmaşık bir türse ... bir XML belgesi gibi. Sadece "==" yapamazsınız, belirli bir kod karşılaştırması yazmanız gerekecek ve belki karşılaştırma yönteminiz hatalı olabilir ??
andy

@andy: Karşılaştırma yönteminizi ayrı ayrı test etmelisiniz. İyice test ettikten sonra, diğer testlerde çalıştığına güvenebilirsiniz.
Bill the Lizard

harika, teşekkürler Bill. Yeni bir yerde çalışmaya başladım ve Unit Testing ile ilk kez. Prensipte işe yaradığını düşünüyorum ve gerçekten yararlı olduğu yerlerde Cruise Control kullanıyoruz, ancak büyük testler eski kodla aynı kaderi paylaşıyor gibi görünüyor ... Bundan emin değilim ....
andy

11

Birim testleri vardır, böylece birimleriniz (yöntemler) beklediğiniz şeyi yapar. Testi yazmak, sizi kodu yazmadan önce ne beklediğiniz hakkında düşünmeye zorlar . Yapmadan önce düşünmek her zaman iyi bir fikirdir.

Birim testleri iş kurallarını yansıtmalıdır. Kabul edilirse, kodda hatalar olabilir, ancak önce testi yazmak, herhangi bir kod yazılmadan önce iş kuralı perspektifinden yazmanıza izin verir. Sonradan testi Yazma, bence, sen çünkü açıkladığınız hataya yol olasılığı daha yüksektir biliyoruz niyet doğru değil - bu ve cazip kod uygular sadece uygulama doğru olduğundan emin olmak için nasıl.

Ayrıca, birim testleri, yazmanız gereken testlerin yalnızca bir biçimidir ve en düşük olanıdır. Entegrasyon testleri ve kabul testleri de, sistemin beklenen şekilde çalıştığından emin olmak için mümkünse müşteri tarafından yazılmalıdır. Bu test sırasında hatalar bulursanız, işlevsellikteki değişikliği test ederek düzgün çalışmasını sağlamak için geri dönün ve birim testleri yazın (başarısız olanlar), ardından testi geçmesi için kodunuzu değiştirin. Artık hata düzeltmelerinizi yakalayan regresyon testleriniz var.

[DÜZENLE]

TDD yaparken bulduğum başka bir şey. Neredeyse varsayılan olarak iyi tasarımı zorlar. Bunun nedeni, yüksek oranda bağlı tasarımların tek başına birim testi yapmasının neredeyse imkansız olmasıdır. Tasarımınızı geliştirecek ve birleştirmeyi azaltacak tüm modellerin - arayüzlerin, kontrolün ters çevrilmesinin ve bağımlılık enjeksiyonunun - test edilebilir kod için gerçekten önemli olduğunu anlamak için TDD'yi kullanmak çok uzun sürmez.


Belki de sorunum burada yatıyor. Bir iş kuralı için algoritmayı, sonucu görselleştirebildiğimden daha düşük bir şekilde görselleştirebiliyorum, bu yüzden kodun kendisini uygulamakta sorun yaşamıyorum, ancak kuralın gereksiz olduğunu görüyorum. Belki de ben öyle düşünüyorum.
FlySwat

Birim testinde yaptığınız tam olarak budur. Bu algoritmayı parçalara ayırın ve her parçayı kontrol edin. Tipik olarak, birim testimde beklentiyi zaten yazdığım için kodumun kendi kendine yazdığını buluyorum.
tvanfosson

Mock, test alanında aşırı yüklenmiş bir terimdir. Test etmeye çalıştığınız şeyle dalga geçmezsiniz, test etmeye çalışmadığınız şeyle alay edersiniz ... İş kuralınız için testi yazarken onu çağıran bir kod yaratırsınız - hiç de alay etmezsiniz .
cwash

@cwash - Yorumunuzun cevabıma nasıl uygulanacağından emin değilim. Alay etmekten bahsetmedim ... ve gözleminize katılıyorum.
tvanfosson

@tvanfosson - Son yorumum @FlySwat'e yanıt olarak oldu "... kuralı gereksiz olarak alay etmek." Üzgünüm belirtmeyi unuttum.
51'de cwash

10

Bir test nasıl test edilir ? Mutasyon testi , şahsen şaşırtıcı derecede iyi sonuçlar elde etmek için kullandığım değerli bir tekniktir. Daha fazla ayrıntı için bağlantılı makaleyi okuyun ve daha fazla akademik referansa bağlantılar, ancak genel olarak, kaynak kodunuzu değiştirerek (örneğin "x + = 1" i "x - = 1" olarak değiştirerek) "testlerinizi test eder" ve sonra Testlerinizi yeniden çalıştırarak en az bir testin başarısız olmasını sağlayın. Test başarısızlığına neden olmayan mutasyonlar daha sonra incelenmek üzere işaretlenir.

Kapsamlı görünen bir dizi test ile% 100 hat ve şube kapsamına nasıl sahip olabileceğinize şaşıracaksınız, ancak yine de herhangi bir test şikayet etmeden kaynağınızdaki bir satırı temelden değiştirebilir veya hatta yorum yapabilirsiniz. Çoğu zaman bu, tüm sınır durumlarını kapsayacak şekilde doğru girdilerle test etmemekle ilgilidir, bazen daha inceliklidir, ancak her durumda, ne kadarının çıktığından etkilendim.


1
Henüz duymadığım +1 ilginç konsept
Wim Coenen

9

Test Odaklı Geliştirme (TDD) uygularken, kişi başarısızlıkla başlar testle . Gereksiz görünebilecek bu adım, aslında birim testinin bir şeyi test ettiğini doğrulamak için burada. Aslında, test asla başarısız olmazsa, hiçbir değeri yoktur ve daha da kötüsü, hiçbir şeyi kanıtlamayan olumlu bir sonuca güveneceğiniz için yanlış güvene yol açar.

Bu süreci sıkı bir şekilde takip ederken, tüm '' birimler '', en sıradan bile olsa, birim testlerinin yaptığı güvenlik ağı tarafından korunur.

Assert.IsEqual(p.DiscountPrice,90);

Testin bu yönde gelişmesinin bir nedeni yok - ya da mantığınızda bir şey eksik. Fiyat 100 ve indirim 20 olduğunda, indirimli fiyat 80'dir. Bu bir değişmez gibidir.

Şimdi, yazılımınızın yüzdeye dayalı başka bir tür indirimi desteklemesi gerektiğini düşünün, belki de satın alınan hacme bağlı olarak, Product :: DiscountPrice () yönteminiz daha karmaşık hale gelebilir. Ve bu değişiklikleri uygulamaya koymanın, başlangıçta sahip olduğumuz basit indirim kuralını ihlal etmesi mümkündür. Ardından, gerilemeyi hemen algılayacak olan bu testin değerini göreceksiniz.


Kırmızı - Yeşil - Yeniden Düzenleyici - bu, TDD sürecinin özünü hatırlamak içindir.

Kırmızı , bir test başarısız olduğunda JUnit kırmızı çubuğunu ifade eder.

Yeşil , tüm testler başarılı olduğunda JUnit ilerleme çubuğunun rengidir.

Refactor yeşil koşulda: Herhangi dupliation kaldırmak, okunabilirliği artırmak.


Şimdi, "kodun üzerindeki 3-4 katman" hakkındaki fikrinize değinmek gerekirse, bu, geliştirme sürecinin çevik olduğu zaman değil, geleneksel (şelale benzeri) bir süreç için geçerlidir. Ve çevik, TDD'nin geldiği dünyadır; TDD, eXtreme Programlamanın temel taşıdır .

Çevik, duvardan atılan gereksinim belgelerinden ziyade doğrudan iletişimle ilgilidir.


8

Her ne kadar ben birim testi için olduğum halde, bazen bu test ilk geliştirme biçiminin gerçekten faydalı olup olmadığını merak ediyorum ...

Bunun gibi küçük, önemsiz testler kod tabanınız için "kömür madenindeki kanarya" olabilir ve çok geç olmadan tehlikeyi uyarır. Önemsiz testler etrafta dolaşmak için kullanışlıdır çünkü etkileşimleri doğru yapmanıza yardımcı olurlar.

Örneğin, aşina olmadığınız bir API'yi nasıl kullanacağınızı araştırmak için uygulanan önemsiz bir testi düşünün. Bu testin API'yi "gerçekten" kullanan kodda yaptığınız şeyle herhangi bir ilgisi varsa, bu testi etrafta tutmak yararlıdır. API yeni bir sürüm yayınladığında ve yükseltmeniz gerektiğinde. Artık, API'nin regresyonları yakalamak için kullanabileceğiniz çalıştırılabilir bir biçimde kaydedilmiş olarak nasıl davranmasını beklediğinizle ilgili varsayımlarınız var.

... [I] Gerçek bir süreç yok, kodunuzun (İş Talebi, Gereksinimler Belgesi, Mimari Belgesi) üzerinde 3-4 katman var, burada gerçek tanımlanmış iş kuralı (İndirimli Fiyat, Fiyattır - İndirim) yanlış tanımlanabilir. Durum buysa, birim testinizin sizin için hiçbir anlamı yoktur.

Yıllardır testler yazmadan kod yazıyorsanız, herhangi bir değer olduğu sizin için hemen açık olmayabilir. Ancak, çalışmanın en iyi yolunun "erken yayınla, sık sık yayınla" veya "çeviklik" olduğu zihniyetindeyseniz, hızlı / sürekli yayılma yeteneği istiyorsanız, o zaman testinizin kesinlikle bir anlamı vardır. Bunu yapmanın tek yolu, kodda yaptığınız her değişikliği bir testle meşrulaştırmaktır. Test ne kadar küçük olursa olsun, yeşil bir test paketiniz olduğunda teorik olarak konuşlandırmaya hazırsınız. Ayrıca bkz. "Sürekli üretim" ve "kalıcı beta".

Bu zihniyette olmak için "önce test" olmanız da gerekmez, ancak bu genellikle oraya ulaşmanın en etkili yoludur. TDD yaptığınızda, kendinizi iki ila üç dakikalık küçük Red Green Refactor döngüsüne kilitlersiniz. Hiçbir noktada durup ayrılamaz ve ellerinizde hata ayıklamak ve bir araya getirmek için bir saat sürecek tam bir karmaşa yaşayamazsınız.

Ek olarak, birim testiniz başka bir başarısızlık noktasıdır ...

Başarılı bir test, sistemdeki bir arızayı gösteren testtir. Başarısız bir test, testin mantığında veya sisteminizin mantığındaki bir hata konusunda sizi uyaracaktır. Testlerinizin amacı, kodunuzu kırmak veya bir senaryonun işe yaradığını kanıtlamaktır.

Koddan sonra testler yazıyorsanız, "kötü" bir test yazma riskiyle karşılaşırsınız çünkü testinizin gerçekten çalıştığını görmek için hem bozuk hem de çalışır durumda olduğunu görmeniz gerekir. Koddan sonra testler yazarken, bu, testin başarısız olduğunu görmek için "tuzağı kurmanız" ve koda bir hata eklemeniz gerektiği anlamına gelir. Çoğu geliştirici bu konuda sadece tedirgin değil, aynı zamanda bunun zaman kaybı olduğunu da iddia ediyor.

Burada ne kazanıyoruz?

İşleri bu şekilde yapmanın kesinlikle bir faydası var. Michael Feathers, "eski kodu" "denenmemiş kod" olarak tanımlar. Bu yaklaşımı uyguladığınızda, kod tabanınızda yaptığınız her değişikliği meşrulaştırırsınız. Test kullanmamaktan daha titizdir, ancak büyük bir kod tabanını korumak söz konusu olduğunda, kendi masrafını çıkarır.

Tüylerden bahsetmişken, bununla ilgili incelemeniz gereken iki harika kaynak var:

Bunların her ikisi de bu tür uygulamaların ve disiplinlerin "Yeşil Alan" olmayan projelerde nasıl çalıştırılacağını açıklıyor. Sıkıca bağlanmış bileşenler, fiziksel bağlantılı bağımlılıklar ve üzerinde kontrol sahibi olmadığınız şeyler etrafında testler yazmak için teknikler sağlarlar. Her şey "dikiş" bulmak ve bunların etrafında test yapmakla ilgili.

[I] İndirimli fiyat yanlışsa, test ekibi sorunu yine de bulacaktır, birim testi nasıl bir çalışmayı kaydetti?

Bunun gibi alışkanlıklar bir yatırım gibidir. İade anında gerçekleşmez; zamanla oluşurlar. Test etmemenin alternatifi, esasen gerilemeleri yakalayamama, entegrasyon hataları korkusu olmadan kod sunamama veya tasarım kararlarını yönlendirememe borcunu almaktır. Güzel olan, kod tabanınıza yapılan her değişikliği meşrulaştırmanızdır.

Burada neyi özlüyorum? Lütfen bana TDD'yi sevmeyi öğret, çünkü şimdiye kadar onu yararlı olarak kabul etmekte zorlanıyorum. Ben de istiyorum çünkü ilerici kalmak istiyorum ama bu bana mantıklı gelmiyor.

Profesyonel bir sorumluluk olarak bakıyorum. Ulaşmak için ideal. Ama takip etmesi çok zor ve sıkıcı. Bunu önemsiyor ve test edilmemiş bir kod üretmemeniz gerektiğini düşünüyorsanız, iyi test alışkanlıklarını öğrenmek için irade gücünü bulabileceksiniz. Şu anda çok yaptığım bir şey (diğerleri gibi), kendime herhangi bir test yapmadan kod yazmak için bir saat timebox ve sonra onu çöpe atacak disipline sahip olmak. Bu savurgan görünebilir, ama gerçekten değil. Bu egzersiz bir şirketin fiziksel malzemelerine mal olmayacak. Sorunu anlamama ve kodu hem daha kaliteli hem de test edilebilir olacak şekilde nasıl yazacağımı anlamama yardımcı oldu.

Nihayetinde tavsiyem, eğer gerçekten iyi olma arzunuz yoksa, o zaman hiç yapmayın. Devam ettirilmeyen, iyi performans göstermeyen vb. Kötü testler, hiç test yaptırmamaktan daha kötü olabilir. Kendi başınıza öğrenmek zordur ve muhtemelen sevmeyeceksiniz, ancak bunu yapma arzunuz yoksa veya bunda yeterince değer göremiyorsanız öğrenmek neredeyse imkansız olacaktır. zaman yatırımını garanti eder.

Birkaç kişi, testin şartnamenin uygulanmasına yardımcı olduğundan bahsetti. Benim tecrübelerime göre teknik özelliklerin de yanlış olduğu, çoğu zaman ...

Bir geliştiricinin klavyesi, kauçuğun yolla buluştuğu yerdir. Spesifikasyon yanlışsa ve üzerindeki bayrağı kaldırmazsanız, bunun için suçlanmanız çok muhtemeldir. Ya da en azından kodunuz olacaktır. Testte yer alan disiplin ve titizliğe uymak zordur. Hiç de kolay değil. Pratik yapmak, çok öğrenmek ve birçok hata yapmak gerekir. Ama sonunda karşılığını veriyor. Hızlı tempolu, hızla değişen bir projede, sizi yavaşlatsa da, geceleri uyumanın tek yolu budur.

Burada düşünülmesi gereken başka bir şey de, temelde testle aynı olan tekniklerin geçmişte işe yaradığı kanıtlanmış olmasıdır: "temiz oda" ve "sözleşmeye göre tasarım" her ikisi de aynı tür "meta" kod yapılarını üretme eğilimindedir. testler yapar ve bunları farklı noktalarda uygular. Bu tekniklerin hiçbiri sihirli değnek değildir ve titizlik, pazara sunma süresi açısından sunabileceğiniz özellikler kapsamında sonuçta size mal olmayacaktır. Ama konu bu değil. Bu, sunduğunuz şeyi sürdürebilmekle ilgilidir. Ve bu çoğu proje için çok önemli.


7

Birim testi, çift girişli defter tutmaya çok benzer şekilde çalışır. Aynı şeyi (iş kuralı) iki farklı şekilde ifade edersiniz (üretim kodunuzda programlanmış kurallar olarak ve testlerinizde basit, temsili örnekler olarak). Her ikisinde de aynı hatayı yapmanız çok düşük bir ihtimaldir , bu yüzden ikisi de birbirleriyle aynı fikirdeyse, yanlış anlamanız pek olası değildir.

Test nasıl çabaya değer olacak? Deneyimlerime göre, en azından test odaklı geliştirme yaparken en az dört şekilde:

  • iyi ayrıştırılmış bir tasarım oluşturmanıza yardımcı olur. Yalnızca iyi ayrıştırılmış kodu birim test edebilirsiniz;
  • ne zaman bitirdiğinizi belirlemenize yardımcı olur. Testlerde gerekli davranışı belirtmek zorunda olmak, gerçekte ihtiyacınız olmayan işlevselliği oluşturmamaya ve işlevselliğin ne zaman tamamlandığını belirlemenize yardımcı olur;
  • size yeniden düzenlemeler için bir güvenlik ağı sağlar, bu da kodu değişikliklere çok daha uygun hale getirir; ve
  • size çok fazla hata ayıklama süresi kazandırır, bu da korkunç derecede maliyetlidir (geleneksel olarak geliştiricilerin zamanlarının% 80'ini hata ayıklamak için harcadıklarını duydum).

5

Çoğu birim testi, varsayımları test eder. Bu durumda, indirimli fiyat, fiyat eksi indirim olmalıdır. Varsayımlarınız yanlışsa, bahse girerim kodunuz da yanlıştır. Ve aptalca bir hata yaparsanız, test başarısız olur ve onu düzeltirsiniz.

Kurallar değişirse, test başarısız olur ve bu iyi bir şeydir. Yani bu durumda testi de değiştirmeniz gerekiyor.

Genel bir kural olarak, bir test hemen başarısız olursa (ve ilk test tasarımını kullanmazsanız), ya test ya da kod yanlıştır (ya da kötü bir gün geçiriyorsanız her ikisi de). Soruna neden olan kodu düzeltmek ve testi yeniden çalıştırmak için sağduyu kullanırsınız (ve spesifikasyonlara göre).

Jason'ın dediği gibi, test güvenliktir. Ve evet, bazen hatalı testler nedeniyle fazladan iş çıkarırlar. Ancak çoğu zaman büyük zaman kazandırırlar. (Ve testi bozan adamı cezalandırmak için mükemmel bir fırsata sahipsiniz (biz kauçuk tavuktan bahsediyoruz)).


4

Yapabileceğiniz her şeyi test edin. Metreyi ayağa çevirmeyi unutmak gibi önemsiz hataların bile çok pahalı yan etkileri olabilir. Bir test yazın, kontrol etmesi için kodu yazın, geçmesini sağlayın, devam edin. Gelecekte bir noktada birisinin indirim kodunu değiştirebileceğini kim bilebilir. Bir test sorunu tespit edebilir.


Bu düşüncelerimin hiçbirine hitap etmiyor. TDD'nin temel mantrasını anlıyorum ... Faydasını görmüyorum.
FlySwat

4

Birim testleri ve üretim kodunu simbiyotik bir ilişki olarak görüyorum. Basitçe söylemek gerekirse: biri diğerini test eder. Ve her ikisi de geliştiriciyi test eder.


3

Hatalar geliştirme döngüsü boyunca yaşadıkça, kusurları düzeltme maliyetinin (katlanarak) arttığını unutmayın. Evet, test ekibi kusuru yakalayabilir, ancak (genellikle) arızayı bu noktadan izole etmek ve düzeltmek, bir birim testinin başarısız olmasına kıyasla daha fazla çalışma gerektirir ve eğer siz bu sorunu düzeltirken diğer kusurları ortaya çıkarmak daha kolay olacaktır. çalıştırılacak birim testleri yok.

Genelde önemsiz bir örnekten daha fazlasıyla görmek daha kolaydır ... ve önemsiz örneklerle, eğer birim testini bir şekilde bozarsanız, onu inceleyen kişi testteki hatayı veya koddaki hatayı yakalayacaktır veya her ikisi de. ( İnceleniyorlar , değil mi?) Tvanfosson'un belirttiği gibi , birim testi SQA planının yalnızca bir parçasıdır.

Bir anlamda birim testleri sigortadır. Her kusuru yakalayacağınızın garantisi yoktur ve bazen onlara çok fazla kaynak harcıyormuşsunuz gibi görünebilir, ancak düzeltebileceğiniz kusurları yakaladıklarında çok daha az harcarsınız hiç test yaptırmamış olsaydın ve tüm kusurları gidermek zorunda kalırdın.


3

Demek istediğini anlıyorum, ama açıkça abartılmış.

Argümanınız temelde şudur: Testler başarısızlığı ortaya çıkarır. Bu nedenle testler kötüdür / zaman kaybıdır.

Bu bazı durumlarda doğru olsa da, çoğunluk pek sayılmaz.

TDD şunu varsayar: Daha Fazla Test = Daha Az Hata.

Testlerin, tanıtmaktan çok başarısızlık noktalarını yakalama olasılığı daha yüksektir .


1

Daha da fazla otomasyon burada yardımcı olabilir! Evet, birim testleri yazmak çok iş gerektirebilir, bu yüzden size yardımcı olması için bazı araçlar kullanın. Microsoft'tan Pex gibi bir şeye bir göz atın, .Net kullanıyorsanız, kodunuzu inceleyerek sizin için otomatik olarak birim test paketleri oluşturacaktır. Kodunuz aracılığıyla tüm yolları kapsamaya çalışan, iyi bir kapsama alanı sağlayan testler bulacaktır.

Elbette, sadece kodunuza bakarak aslında ne yapmaya çalıştığınızı bilemez, bu yüzden doğru olup olmadığını bilemez. Ancak, sizin için ilginç test durumları oluşturacak ve daha sonra bunları inceleyebilir ve beklediğiniz gibi davranıp davranmadığını görebilirsiniz.

Daha sonra daha ileri gidip parametreleştirilmiş birim testleri yazarsanız (bunları sözleşmeler olarak düşünebilirsiniz, gerçekten) bunlardan belirli test durumları üretecek ve bu sefer bir şeylerin yanlış olup olmadığını anlayabilecektir çünkü testlerinizdeki iddialarınız başarısız olacaktır.


1

Bu soruya yanıt vermenin iyi bir yolunu biraz düşündüm ve bilimsel yönteme paralel bir şekilde çizmek istiyorum. IMO, bu soruyu yeniden ifade edebilirsin, "Bir deneyi nasıl denersiniz?"

Deneyler, fiziksel evren hakkındaki ampirik varsayımları (hipotezleri) doğrular. Birim testleri, çağırdıkları kodun durumu veya davranışı hakkındaki varsayımları test edecektir. Bir deneyin geçerliliği hakkında konuşabiliriz, ancak bunun nedeni, sayısız başka deney aracılığıyla bir şeyin uymadığını biliyoruz. Hem yok yakınsak geçerliliği ve ampirik kanıtlar . Bir deneyin geçerliliğini test etmek veya doğrulamak için yeni bir deney tasarlamıyoruz, ancak tamamen yeni bir deney tasarlayabiliriz .

Dolayısıyla , deneylerde olduğu gibi , bir birim testinin geçerliliğini, bir birim testini geçip geçmemesine bağlı olarak tanımlamıyoruz. Diğer birim testleri ile birlikte, test ettiği sistem hakkında yaptığımız varsayımları açıklar. Ayrıca, deneyler gibi, test ettiğimiz şeyden olabildiğince fazla karmaşıklığı gidermeye çalışırız. "Olabildiğince basit, ama daha basit değil."

Deneylerden farklı olarak , testlerimizin yalnızca yakınsak geçerlilik dışında geçerli olduğunu doğrulamak için bir numara yapıyoruz. Teste yakalanması gerektiğini bildiğimiz bir hatayı akıllıca ekleyebilir ve testin gerçekten başarısız olup olmadığını görebiliriz. (Keşke bunu gerçek dünyada yapabilseydik, bu yakınsak geçerlilik şeyine çok daha az güvenirdik!) Bunu yapmanın daha etkili bir yolu, uygulamadan önce testinizin başarısız olmasını izlemektir ( Kırmızı, Yeşil, Refactor'daki kırmızı adım ).


1

Test yazarken doğru paradigmayı kullanmanız gerekir.

  1. Önce testlerinizi yazarak başlayın.
  2. Başlamakta başarısız olduklarından emin olun.
  3. Geçmelerini sağlayın.
  4. Kodunuzu kontrol etmeden önce kod incelemesi (testlerin gözden geçirildiğinden emin olun.)

Her zaman emin olamazsınız, ancak genel testleri iyileştirirler.


0

Kodunuzu test etmeseniz bile, üretimde kesinlikle kullanıcılarınız tarafından test edilecektir. Kullanıcılar yazılımınızı çökertmeye ve kritik olmayan hataları bile bulmaya çalışırken çok yaratıcıdırlar.

Üretimdeki hataları düzeltmek, geliştirme aşamasındaki sorunları çözmekten çok daha maliyetlidir. Bir yan etki olarak, müşteri çıkışı nedeniyle gelir kaybedeceksiniz. 1 kızgın müşteri için kaybedilen veya kazanılmayan 11 müşteriye güvenebilirsiniz.

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.