Test odaklı geliştirme (TDD) testleri her zaman birim testleri midir?


41

Teste dayalı gelişmeyi şu ana kadar anlıyorum ki, başarısız (kırmızı) bir birim testiniz olduğunda sadece verimli kod yazmanıza izin verilir. Buna dayanarak, teste dayalı yaklaşımın diğer test türlerine de uygulanıp uygulanamayacağı sorusu var.


6
Birbirinin içine yerleştirilmiş birden fazla farklı kırmızı / yeşil / refactor seviyesi kullanmak nadir değildir. Örneğin, kabul / davranış testlerini yazarken, kabul testinin 'yeşil' aşamasının, birim testlerinde birden fazla kırmızı / yeşil / refactor yineleme içerdiği durumlarda, kırmızı / yeşil / refactor'u takip edebilirsiniz.
Sean Burton,

1
Başlık, sorunun içeriğiyle eşleşmiyor. "Testler daima birim testler " başlığı (cevap: hayır, birim testlerden başka testler olabilir), "Önce testi yazmalı mıyım?"
AnoE

@Hayır İçeriğin ilk cümlesi sadece bir tanıtım cümlesidir. Saniye cümlesi, testin önce yazılıp yazılmayacağını sormaz, ancak TDD yaklaşımı TDD dışındaki diğer test yöntemlerinde kullanılabilir mi?
user1364368

@ user1364368, soruyu bir miktar yeniden düzenlemek için çekinmeyin, en azından ilk okumadaki niyetiniz ve en çok oy alan soru hakkında kafam karıştı, her iki cümleniz de ele alındığında ilk olarak belirgin bir şekilde başlar.
AnoE

@Hayır Asıl sorunun ne olduğunu netleştirmek için ikinci cümlenin başlangıcını değiştirdim.
user1364368

Yanıtlar:


27

Tüm TDD'nin senden istediği, başarısız bir test yazman, daha sonra şifreni geçmesi için değiştirmen.

Genellikle "birim testleri" küçük ve hızlıdır ve kodunuzun bir bölümünü yalıtımlı olarak test edin. Hızlı oldukları için kırmızı / yeşil / refactor döngüsünü de hızlı yapar. Bununla birlikte, sadece izolasyondaki test parçalarından muzdariptirler. Bu yüzden başka testlere de ihtiyacınız var (entegrasyon, kabul vb.). Aynı ilkeleri takip etmek hala iyi bir uygulamadır: başarısız bir test yazın, ardından çalışmasını sağlamak için kodu değiştirin. Sadece genellikle daha yavaş olduklarını unutmayın, bu nedenle kırmızı / yeşil / refactor döngü süresini etkileyebilir.


59

Kırmızı yeşil refactor döngüsü çok sağlam bir prensip üzerine kuruludur:

Yalnızca hem başarılı hem de başarısız gördüğünüz testlere güvenin.

Evet, aynı zamanda otomatik entegrasyon testleriyle de çalışır. Ayrıca manuel testler. Heck, araba aküsü test cihazları üzerinde çalışıyor. Test bu şekilde yapılır.

Bazıları birim testlerinin, test edilebilecek en küçük şeyi kapsadığını düşünüyor. Bazıları test edilmesi hızlı olan her şeyi düşünür. TDD, sadece kırmızı yeşil refactor döngüsünden daha fazlasıdır, ancak bu bölüm çok özel bir test setine sahiptir: Bir değişiklik koleksiyonu göndermeden önce bir kez ideal olarak yapacağınız testler değildir. Her değişiklik yaptığınızda yapacağınız testler. Bana göre, bunlar sizin birim testleriniz.


1
Ayrıca , bir hatanın meydana geldiğini test ederken negatif testlerin önemli olmasının nedenlerinden biri de budur : diğer her şeyin işe yarayacağından emin olmak istersiniz, bu nedenle iki test (bir tanesi tam beklenen hatayı üretir, diğeri hatayı üretmez) elde etmek istersiniz. birbirleri , gelecekte bu kırmızı / yeşil durumun devam edeceği güveninin artmasına yardımcı olmaktadır .
Matthieu M.

12

Ancak, sınamaya dayalı yaklaşımın diğer sınama biçimlerine de uygulanıp uygulanamayacağını merak ediyorum.

Evet ve bunu yapan iyi bilinen bir yaklaşım Davranış odaklı gelişimdir . BDD'deki resmi spesifikasyondan üretilen testlere "birim testleri" adı verilebilir, ancak tipik olarak gerçek TDD'deki kadar düşük seviyede olmayacaklardır, muhtemelen "kabul testleri" terimine daha iyi uyacaklardır.


8

Teste dayalı gelişmeyi şu ana kadar anlıyorum ki, başarısız (kırmızı) bir birim testiniz olduğunda sadece verimli kod yazmanıza izin verilir.

Hayır. Testin mesajını değiştirmek için yalnızca mümkün olan en basit kodu yazmanıza izin verilir. Ne tür bir test hakkında hiçbir şey söylemez.

Aslında, bir kabul kriteri için başarısız (kırmızı) bir kabul testi yazarak başlayacaksınız, daha kesin olarak, başarısız olabilecek en basit kabul testini yazıyorsunuz; daha sonra testi yaparsınız, başarısız olduğunu izlersiniz ve doğru nedenle başarısız olduğunu doğrulayın. Daha sonra, bu kabul kriterinin bir işlevselliği için başarısız bir fonksiyonel test yazarsınız, yine başarısız olabilecek, çalıştırabilecek, başarısız olabileceğini izleyen ve doğru nedenden dolayı başarısız olduğunu doğrulayan en basit fonksiyonel testi yazarsınız. Daha sonra başarısız bir ünite testi yazarsın, muhtemelen başarısız olabilecek en basit ünite testidir, başarısız olduğunu izler, doğru nedenden dolayı başarısız olduğunu doğrularsın.

Şimdi , hata mesajını değiştirebilecek en basit üretim kodunu yazıyorsunuz. Testi tekrar çalıştırın, hata mesajının değiştiğini, doğru yöne değiştiğini ve kodun mesajı doğru nedenle değiştirdiğini doğrulayın. (İdeal olarak, hata mesajı şimdiye kadar gitmiş olmalı ve test geçmeli, ancak daha sık sık, testi bir seferde geçmeye çalışmak yerine mesajı değiştirmek için küçük adımlar atmak daha iyidir - nedeni budur neden test çerçeveleri geliştiricileri hata mesajları için bu kadar çaba harcıyorlar?)

Birim testini geçtiğinizde, üretim kodunuzu testlerinizin koruması altında yeniden değerlendirirsiniz. (Şu anda, kabul testinin ve işlevsel testin hala başarısız olduğunu, ancak sorun değil, çünkü yalnızca ünite testlerinin kapsadığı ayrı üniteleri yeniden değerlendiriyorsunuz.)

Şimdi bir sonraki ünite testini yaratır ve fonksiyonel test de geçene kadar yukarıdakileri tekrarlar. İşlevsel testin koruması altında, artık birden fazla birimde yeniden düzenleme yapabilirsiniz.

Bu orta döngü artık kabul testi geçene kadar tekrar eder; bu noktada şimdi tüm sistemde yeniden yapılanma yapabilirsiniz.

Şimdi, bir sonraki kabul kriterini seçersiniz ve dış döngü yeniden başlar.

TDD'nin "keşfi" Kent Beck ("mucit" terimini beğenmiyor, insanların bunu başından beri yaptığını söylüyor, sadece bir isim verdi ve bunun hakkında bir kitap yazdı) fotoğrafçılıktan bir benzetme kullanıyor ve buna "yakınlaştırma ve uzaklaştırma" denir.

Not: Her zaman üç test seviyesine ihtiyacınız yoktur. Belki, bazen daha fazlasına ihtiyacınız vardır. Daha sık, daha azına ihtiyacınız var. Eğer işlevsellik parçalarınız küçükse ve fonksiyonel testleriniz hızlıysa, o zaman olmadan (veya daha az birim testiyle) yapabilirsiniz. Genellikle, yalnızca kabul testlerine ve ünite testlerine ihtiyacınız vardır. Ya da, kabul kriterleri böylece kabul testleri o ince taneli olan olan fonksiyonel testler.

Kent Beck, hızlı, küçük ve odaklanmış bir fonksiyonel testi varsa, önce birim testlerini yazacağını, birim testlerinin kodu sürmesine izin vereceğini ve sonra da kodunu kapsayan birim testlerini tekrar sileceğini (bazılarını) sileceğini söylüyor. hızlı fonksiyonel test tarafından kapsanmaktadır. Unutmayın: Test kodu aynı zamanda bakımı ve yeniden bakımı yapılması gereken koddur, ne kadar az olursa, o kadar iyi!

Ancak, sınamaya dayalı yaklaşımın diğer sınama biçimlerine de uygulanıp uygulanamayacağını merak ediyorum.

TDD'yi gerçekten testlere uygulamıyorsunuz. Tüm geliştirme sürecinize uygularsınız. Test Destekli Gelişimin "yönlendirilen" kısmı bu anlama geliyor: tüm gelişiminiz testler tarafından yönlendiriliyor. Testler sadece yazdığınız kodu değil aynı zamanda hangi kodu yazacağınızı, sonra hangi kodu yazacağınızı da belirler. Tasarımınızı yönlendirirler. İşin bitince sana söylerler. Daha sonra ne üzerinde çalışacağınızı söylerler. Size kodunuzdaki tasarım kusurlarını anlatıyorlar (testlerin yazılması zor olduğunda).

Keith Braithwaite dediği bir egzersiz yarattı bunu yürekten olursa TDD Farklı . Bu, sıkı bir şekilde izlemeniz gereken ve sizi TDD'yi daha titizlikle uygulamak için yönlendirmek için tasarlanan bir dizi kuraldan ( Bob Amca Martin'in TDD'nin Üç Kuralları'na dayanır , ancak daha katıdır) oluşur. Çift programlamasında en iyi şekilde çalışır (çiftiniz kuralları ihlal etmediğinizden emin olmanızı sağlar) ve bir eğitmen.

Kurallar:

  1. Tam olarak bir yeni test yazın, çözüm yönünde işaret edebilecek en küçük testi yazın.
  2. Başarısız bakın; derleme hataları, başarısızlıklar olarak sayılır.
  3. Test yönteminde bulabileceğiniz en az uygulama kodunu yazarak testi (1) 'den başarılı yapın .
  4. Yinelemeyi gidermek için Refactor ve tasarımın iyileştirilmesi için gerektiği şekilde. Bu hareketleri kullanma konusunda kesin olun:
    1. yeni bir yöntem istiyorsan - yeniden yapılanma zamanına kadar bekle, sonra… bunlardan birini yaparak yeni (test dışı) yöntemler yarat:
      • tercih edilen: Test sınıfında yeni bir yöntem oluşturmak için (3) 'e göre oluşturulan uygulama kodunda Ayıklama Yöntemi yapın veya
      • Yapmanız gerekiyorsa: Uygulama kodunu (3) uyarınca mevcut bir uygulama yöntemine taşımak
    2. yeni bir sınıf istiyorsan - yeniden toparlanma zamanına kadar bekle, sonra… bir Move Yöntemi için bir hedef sağlamak ve başka bir sebep olmadan test dışı sınıflar oluşturmak
    3. Hammadde Yöntemi'ni kullanarak, uygulama sınıflarını yöntemlerle doldurma

Bu kurallar TDD'yi uygulamak içindir. Bunlar aslında üretimde TDD yapmak anlamına gelmezler (hiçbir şey denemenizi engellemese de). Sinir bozucu hissedebilirler, çünkü bazen gerçek bir ilerleme kaydetmeden binlerce ufacık küçük adım atarsınız.


2

TDD, geleneksel Yazılım Test Topluluğunun "birim test" dediği şeyle sınırlı değildir. Bu çok yaygın yanlış anlaşılma, Kent Beck'in TDD pratiğini anlatırken "birim" terimindeki talihsiz aşırı yüklenme sonucudur. "Birim testi" ile neyi kastettiği, tecrit edilmiş bir sınavdı. Diğer testlere bağlı değildir. Her test, ihtiyacı olan durumu ayarlamalı ve yapıldığında her türlü temizliği yapmalıdır. Bu anlamda TDD anlamında bir birim testi bir birimdir. Kendini içeriyor. Kendi başına çalışabilir veya herhangi bir sırada başka bir birim test ile birlikte çalıştırılabilir.

Referans : "Örnek Olarak Test Odaklı Geliştirme", Kent Beck

Kent Beck, ne demek istediğini Bölüm 32'deki "birim testi" ile açıklıyor - TDD Mastering


1

Kitap okumamıştım, ne de "standart" TDD uygulamalarını her zaman tamamen takip etmiyorum, fakat aklımda TDD felsefesinin asıl amacı, tamamen katılıyorum, ilk önce başarısını tanımlamanız gerekiyor. . Bu, tasarımın her aşamasında, "Bu projenin amacı nedir?" Den önemlidir. "Bu küçük yöntemin girdileri ve çıktıları ne olmalıdır?"

Bu başarı tanımını yapmanın birçok yolu vardır. Potansiyel olarak birçok kenar durumu olan düşük seviyeli yöntemler için kullanışlı bir yöntem, kodları test yazmaktır. Bazı soyutlama seviyeleri için, modülün amacı veya herhangi bir şey hakkında kısa bir not yazmak, hatta her şeyin mantıklı olduğundan ve içinde olduğundan emin olmak için sadece zihinsel olarak kendinizi kontrol etmeniz (veya bir iş arkadaşınıza sormanız) yararlı olabilir. mantıksal yer. Bazen kodda bir entegrasyon testini tanımlamak yararlı olur (ve elbette bunu otomatikleştirmek için yardımcı olur) ve bazen tüm sistemlerin birlikte çalıştığından emin olmak için kullanabileceğiniz makul bir hızlı test planını tanımlamakta yardımcı olur. bekliyorlar.

Ancak, kullandığınız belirli teknikler veya araçlar ne olursa olsun, benim düşünceme göre TDD felsefesinden uzaklaşmanın anahtarı, başarının tanımlanmasının önce gerçekleşmesidir. Aksi taktirde, dart fırlatıyor ve sonra boğa gözünü karaya geldiği her yere boyarsınız.


1

Teste Dayalı Gelişme konuşmasında : Bu, Steve Freeman'ın TDD'nin büyük resminin aşağıdaki slaydını gösterdiği anlamına gelmiyordu (aşağıdaki resme bakın). Bu, " Arızalı ünite testi yaz" ile takip edilen " Arızalı bir uçtan uca test yazma" adımını içerir . (Yakınlaştırmak için tıklayın, sağ üstte)

Dolayısıyla, TDD'de testler her zaman birim testleri değildir.

Ve evet, size ilk ünite testini yazmadan önce başarısız olan daha üst seviye bir uçtan uca testle başlayabilirsiniz (ve belki de gerekir). Bu test, ulaşmak istediğiniz davranışı açıklar. Bu, test piramidinin daha fazla seviyesinde kapsama oluşturur . Adrian Sutton, LMAX'ın uçtan uca testlerin büyük ve değerli bir rol oynayabileceğini gösteren deneyimini açıklıyor .

görüntü tanımını buraya girin


-1

Hayır, basit bir pratik nedenden ötürü, diğer test türlerine uygulanamaz: diğer tür testlerin yürütülmesi çok uzun sürüyor.

Tipik TDD döngüsü: başarısız test, uygulama, refactor kodu yazma. Aradaki adımlar testlerin yapılması ve gerçekleştirilmesidir ve bunların yıldırım hızında olması gerekir. Olmazlarsa, insanlar basamakları atlamaya başlarlar ve artık TDD yapmıyorsunuzdur.


1
Bu yanlıştır: programa ve teste (ve dile) bağlı olarak, uçtan uca entegrasyon testleri 3 saniyeden daha kısa sürede kolayca yapılabilir. İyi tasarlanmış olsa bile, uçtan uca bir test takımı çok az bir sürede çalıştırılabilir. Yani "yapamam" oldukça güçlü.
Jonathan Cast,

@jcast Bu kadar hızlı olan hiçbir şey görmedim. Önceki projemdeki fonksiyonel testlerim 30 saniye sürdü ve bu hızlı. Entegrasyon daha uzun. Benim durumumda, başka hiçbir şeyin anlamı yoktu. Ayrıca, birim testleri her tür testten en hızlı olanıdır - bu nedenle bunların kullanımı mantıklıdır.
BЈовић
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.