it-swarm.asia

TDD ve Verimlilik

Mevcut projemde (C++ 'da bir oyun), geliştirme sırasında% 100 Test Driven Development kullanmaya karar verdim.

Kod kalitesi açısından, bu harika oldu. Kodum hiç bu kadar iyi tasarlanmış ya da hatasız olmamıştı. Bir yıl önce projenin başlangıcında yazdığım kodu görüntülerken rahatsız etmiyorum ve sadece daha kolay test edilebilir olmak için değil, aynı zamanda uygulanması ve kullanımı daha basit olmak için işleri nasıl yapılandıracağım konusunda çok daha iyi bir fikir kazandım. .

Ancak ... projeye başladığımdan bu yana bir yıl geçti. Ancak boş zamanlarımda bunun üzerinde çalışabiliyorum, ama TDD hala alışkın olduğumdan çok beni yavaşlatıyor. Yavaş gelişme hızının zamanla daha iyi hale geldiğini okudum ve kesinlikle testleri eskisinden çok daha kolay düşünüyorum, ama bir yıldır buradayım ve hala bir salyangoz hızında çalışıyorum.

İşe ihtiyaç duyan bir sonraki adımı her düşündüğümde, her seferinde durmam ve gerçek kodu yazmama izin vermek için nasıl bir test yazacağımı düşünmem gerekiyor. Bazen tam olarak hangi kodu yazmak istediğimi bilerek, saatlerce sıkışıp kalacağım, ancak testleri tamamen kapatacak kadar ince bir şekilde nasıl parçalayacağımı bilmiyorum. Diğer zamanlarda, hızlıca bir düzine test düşüneceğim ve yazmak için birkaç dakika sürecek küçük bir gerçek kod parçasını kapsamak için bir saat yazma testleri yapacağım.

Ya da, oyundaki belirli bir varlığı ve yaratılış ve kullanımının tüm yönlerini kapsamak için 50. testi bitirdikten sonra, yapılacaklar listeme bakıyorum ve kodlanacak bir sonraki varlığı görüyorum ve yazma düşüncesinde dehşet içinde Uygulamak için 50 benzer test daha.

Geçen yılın ilerleyişine baktığımda, "lanet projenin bitirilmesi" uğruna TDD'den vazgeçmeyi düşündüğüm noktaya geldi. Ancak, onunla birlikte gelen kod kalitesini vazgeçmek için sabırsızlanıyorum bir şey değil. Korkarım ki, testler yazmayı bırakırsam, kodu bu kadar modüler ve test edilebilir yapma alışkanlığından çıkaracağım.

Belki de bu kadar yavaş olmak için yanlış bir şey mi yapıyorum? Faydaları tamamen kaybetmeden üretkenliği hızlandıran alternatifler var mı? TAD? Daha az test kapsamı? Diğer insanlar tüm üretkenliği ve motivasyonu öldürmeden TDD'den nasıl kurtulur?

136
Nairou

Deneyiminizi paylaşmanız ve endişelerinizi dile getirmeniz için teşekkür ederek başlayayım ... söylemem gereken nadir değil.

  • Zaman/Verimlilik: Yazma testleri, test yazmamaktan daha yavaştır. Eğer bunu buna dahil ederseniz, kabul ediyorum. Bununla birlikte, TDD olmayan bir yaklaşımı uyguladığınız paralel bir çaba çalıştırırsanız, olasılıkla break-tespit-debug-and-fix mevcut kodu harcadığınız zamanın sizi net negatif haline getirme olasılığıdır. Benim için TDD, kod güvenimden ödün vermeden gidebileceğim en hızlısı. Metodunuzda değer katmayan şeyler bulursanız, bunları ortadan kaldırın.
  • Test sayısı: N şeyi kodlarsanız, N şeyi test etmeniz gerekir. Kent Beck'in satırlarından birini yorumlamak için "Yalnızca çalışmasını istiyorsanız test edin."
  • Saatlerce takılıp kalıyorum: Ben de (bazen ve çizgiyi durdurmadan önce> 20 dakika değil) yapıyorum .. Tasarımın biraz çalışmaya ihtiyacı olduğunu söyleyen sadece kodunuz. Test, SUT sınıfınız için başka bir istemcidir. Bir test türünüzü kullanmakta zorlanıyorsa, üretim istemcileriniz de şanslı olacaktır.
  • Benzer testler tedium: Bunun bir karşı-tezgâh yazabilmem için daha fazla içeriğe ihtiyacı var. Yani, Dur ve benzerliği düşün. Bu testleri bir şekilde veriye yönlendirebilir misiniz? Baz tipine karşı testler yazmak mümkün müdür? O zaman sadece her bir türeve karşı aynı test setini çalıştırmanız gerekir. Testlerinizi dinleyin. Doğru tür tembel olun ve tediumdan kaçınmanın bir yolunu bulup bulamayacağınızı görün.
  • Daha sonra ne yapmanız gerektiğini (test/spec) düşünmeyi bırakmak kötü bir şey değildir. Aksine, "doğru olanı" inşa etmeniz önerilir. Genellikle bunu nasıl test edeceğimi düşünemezsem, genellikle uygulamayı da düşünemiyorum. Oraya gelene kadar uygulama fikirlerini boşaltmak iyi bir fikir olabilir ... belki daha basit bir çözüm YAGNI-ish önleyici bir tasarım tarafından gölgede bırakılabilir.

Ve bu beni son sorguya getiriyor: Nasıl daha iyi olabilirim? (Veya An) cevabım Okuma, Yansıtma ve Uygulama.

örneğin. Geç kaldım

  • ritmimin RG [Ref] RG [Ref] RG [Ref] 'u yansıtıp yansıtmadığı veya RRRRGRRef olup olmadığı.
  • Kırmızı/Derleme Hatası durumunda harcanan zaman yüzdesi.
  • Kırmızı/Kırık yapılar durumunda mı kaldım?
78
Gishu

Yüzde 100 test kapsamına ihtiyacınız yoktur. Pragmatik olun.

34
Alistair

TDD hala beni oldukça yavaşlatıyor

Bu aslında yanlış.

TDD olmadan, çoğunlukla çalışan ve gelecek yıl "test" ve hataların çoğunu (ancak hepsini değil) düzeltmek için birkaç hafta kod yazarak geçirirsiniz.

TDD ile, gerçekten işe yarayan bir yıl kod yazarak geçirirsiniz. Ardından birkaç hafta boyunca son entegrasyon testi yaparsınız.

Geçen süre muhtemelen aynı olacak. TDD yazılımı önemli ölçüde daha iyi kalitede olacaktır.

23
S.Lott

Ya da, oyundaki belirli bir varlığı ve yaratılış ve kullanımının tüm yönlerini kapsamak için 50. testi bitirdikten sonra, yapılacaklar listeme bakıyorum ve kodlanacak bir sonraki varlığı görüyorum ve yazma düşüncesinde dehşet içinde Uygulamak için 50 benzer test daha.

Bu, TDD'nin "Refactor" adımını ne kadar takip ettiğinizi merak ediyor.

Tüm testleriniz geçtiğinde, bu kodu yeniden düzenleme ve çoğaltmayı kaldırma zamanıdır. İnsanlar genellikle bunu hatırlasa da bazen çoğaltmayı kaldırmak ve işleri basitleştirmek için bunun da testlerini yeniden düzenleme zamanı olduğunu unuturlar.

Kodun yeniden kullanılmasını sağlamak için bir araya gelen iki varlığınız varsa, testlerini de birleştirmeyi düşünün. Gerçekten sadece kodunuzda artan farklılıklar test etmeniz gerekir. Testlerinizde düzenli olarak bakım yapmıyorsanız, bunlar hızlı bir şekilde hantal olabilir.

TDD hakkında yardımcı olabilecek birkaç felsefi nokta:

  • Bir testin nasıl yazılacağını anlayamadığınızda, kapsamlı test yazma deneyimlerine rağmen, bu kesinlikle bir kod kokus. Kodunuz bir şekilde modülerlikten yoksundur, bu da küçük, basit testlerin yazılmasını zorlaştırır.
  • TDD kullanırken biraz kod eklenmesi mükemmel bir şekilde kabul edilebilir. Nasıl göründüğüne dair bir fikir edinmek için kodu yazın, ardından kodu silin ve testlerle başlayın.
  • Son derece katı TDD uygulamayı bir egzersiz şekli olarak görüyorum. İlk başladığınızda, kesinlikle her seferinde bir test yazın ve devam etmeden önce testi geçmek için en basit kodu yazın. Bununla birlikte, uygulama ile daha rahat hale geldiğinizde bu gerekli değildir. Yazdığım her olası kod yolu için bir birim testim yok, ama deneyim sayesinde bir birim testiyle neyin test edilmesi gerektiğini ve neyin fonksiyonel veya entegrasyon testiyle kapsanabileceğini seçebiliyorum Bunun yerine. TDD'yi bir yıldır sıkı bir şekilde uygularsanız, bu noktaya da yakın olduğunuzu hayal ediyorum.

EDIT: Birim testi felsefesi konusunda, bunun okumanız için ilginç olabileceğini düşünüyorum: Testivus Yol

Ve çok pratik olmasa da, daha pratik bir nokta:

  • Geliştirme diliniz olarak C++ 'dan bahsediyorsunuz. JUnit ve Mockito gibi mükemmel kütüphaneleri kullanarak TDD'yi Java'da kapsamlı bir şekilde uyguladım. Ancak, mevcut kütüphanelerin (özellikle alaycı çerçeveler) eksikliği nedeniyle C++ TDD çok sinir bozucu buldum. Bu nokta mevcut durumunuzda size çok yardımcı olmasa da, umarım TDD'yi tamamen terk etmeden önce bunu dikkate alırsınız.
20
jaustin

Çok ilginç bir soru.

Dikkat edilmesi gereken önemli olan, C++ 'nın çok kolay bir şekilde test edilememesidir ve genel olarak oyun oynamak da TDD için çok kötü bir adaydır. OpenGL/DirectX'in X sürücüsü ile üçgen kırmızı, Y sürücüsü ile sarı üçgen çizip çizmediğini test edemezsiniz. Eğer yumru harita normal vektör gölgelendirici dönüştükten sonra çevrilmez. Ayrıca kırpma sorunlarını farklı hassasiyetlere sahip sürücü sürümleri üzerinde de test edemezsiniz. Yanlış aramalar nedeniyle tanımlanmamış çizim davranışı, yalnızca doğru kod incelemesi ve eldeki SDK ile de test edilebilir. Ses de kötü bir aday. Oyunlar için yine oldukça önemli olan çoklu iş parçacığı, birim testi için neredeyse işe yaramaz. Bu yüzden zor.

Temelde oyun bir sürü GUI, ses ve iş parçacığıdır. GUI, WM_ gönderebileceğiniz standart bileşenlerle bile birim testi zor.

Test edebileceğiniz şey, model yükleme sınıfları, doku yükleme sınıfları, matris kütüphaneleri ve bazı kodlardır, bu çok fazla kod değildir ve genellikle ilk projenizse, çok sık tekrar kullanılamaz. Ayrıca, tescilli formatlarda paketlenmiştir, bu nedenle modifikasyon araçlarını serbest bırakmadığınız sürece 3. taraf girdilerin çok farklı olabileceği pek olası değildir.

Sonra tekrar, TDD gurusu ya da evangelist değilim, bu yüzden hepsini bir tane tuzla alın.

Muhtemelen ana çekirdek bileşenleri için bazı testler yazarım (örneğin matris kütüphanesi, görüntü kütüphanesi). Her işlevdeki beklenmedik girişlere bir grup abort() ekleyin. Ve en önemlisi, kolay kırılmayan dirençli/esnek kodlara odaklanın.

Tek bir hata ile ilgili olarak, C++, RAII ve iyi bir tasarımın akıllıca kullanılması onları önlemek için uzun bir yol kat ediyor.

Eğer oyunu serbest bırakmak istiyorsanız temelde sadece temelleri kapsayacak çok şey var. TDD'nin yardım edip etmeyeceğinden emin değilim.

10
Coder

Diğer cevaplara katılıyorum, ama aynı zamanda çok önemli bir nokta eklemek istiyorum: Maliyetleri yeniden düzenleme !!

İyi yazılmış birim testleri ile kodunuzun güvenli bir şekilde yeniden yazılmasını sağlayabilirsiniz. İlk olarak, iyi yazılmış birim testleri, kodunuzun amacına ilişkin mükemmel belgeler sağlar. İkincisi, yeniden düzenlemenizin talihsiz yan etkileri mevcut test takımına takılır. Böylece, eski kodunuzun varsayımlarının yeni kodunuz için de geçerli olduğunu garanti ettiniz.

6
Morten

Diğer insanlar tüm üretkenliği ve motivasyonu öldürmeden TDD'den nasıl kurtulur?

Bu benim tecrübelerimden tamamen farklı. İnanılmaz derecede akıllısınız ve hata olmadan kod yazıyorsunuz (örneğin, bir hata ile kapalı) veya kodunuzun, programınızın çalışmasını engelleyen hatalara sahip olduğunu ve aslında bitmediğini fark etmiyorsunuz.

TDD sizin (ve benim!) Hata yaptığınızı bilmek için tevazu sahibi olmakla ilgilidir.

Benim için birim testler yazmak, baştan TDD kullanılarak yapılan projeler için daha düşük hata ayıklama süresinde kaydedildi.

Eğer hata yapmazsanız belki TDD benim için olduğu kadar önemli değil!

4
Tom

Sadece birkaç sözüm var:

  1. Test etmeye çalışıyorsunuz gibi görünüyor her şey. Muhtemelen, sadece belirli bir kod/yöntemin yüksek riskli ve Edge vakalarını yapmamalısınız. Eminim 80/20 kuralı burada geçerlidir: Kodunuzun veya kapsanmayan durumların son% 20'si için% 80 yazma testleri harcıyorsunuz.

  2. Öncelik. Çevik yazılım geliştirmeye katılın ve bir ay içinde piyasaya sürmek için gerçekten yapmanız gerekenlerin bir listesini yapın. Sonra bırakın, aynen böyle. Bu özelliklerin önceliği hakkında düşünmenizi sağlayacaktır. Evet, karakterinizin bir geri dönüş yapabilmesi harika olurdu, ancak iş değeri var mı?

TDD iyidir, ancak yalnızca% 100 test kapsamı hedeflemezseniz ve gerçek iş değeri üretmenizi engellemiyorsa (yani özellikler, oyununuza bir şeyler katan şeyler) değil.

3
Cthulhu

Evet, testler ve kod yazmak sadece kod yazmaktan daha uzun sürebilir - ancak kod ve ilgili birim testleri (TDD kullanarak) yazmak, kod yazmaktan ve daha sonra hata ayıklamaktan çok daha tahmin edilebilir.

Hata ayıklama, tüm geliştirme sürecini çok daha öngörülebilir ve sonunda muhtemelen daha hızlı hale getiren TDD kullanıldığında neredeyse ortadan kalkar.

Sürekli yeniden düzenleme - kapsamlı birim test paketi olmadan ciddi bir yeniden düzenleme yapmak imkansızdır. Bu birim test tabanlı güvenlik ağını oluşturmanın en etkili yolu TDD sırasındadır. İyi düzenlenmiş kod, kodu koruyan tasarımcının/ekibin genel verimliliğini önemli ölçüde artırır.

1
ratkok

Oyununuzun kapsamını daraltmayı düşünün ve birisinin oynayabileceği veya serbest bıraktığınız yere götürün. Oyununuzu serbest bırakmak için çok uzun süre beklemek zorunda kalmadan test standartlarınızı korumak sizi motive etmek için bir orta yol olabilir. Kullanıcılarınızdan gelen geri bildirimler uzun vadede fayda sağlayabilir ve testleriniz eklemeler ve değişiklikler konusunda kendinizi rahat hissetmenizi sağlar.

0
JeffO