it-swarm.asia

TDD neden çalışır?

Test odaklı geliştirme (TDD) bu günlerde büyük. Sık sık burada Programmers SE ve diğer mekanlarda çok çeşitli sorunlara bir çözüm olarak önerildiğini görüyorum. Neden işe yaradığını merak ediyorum.

Mühendislik açısından beni iki nedenden dolayı şaşırtıyor:

  1. "Yazma testi + geçene kadar refactor" yaklaşımı inanılmaz derecede mühendislik karşıtı görünüyor. Örneğin inşaat mühendisleri köprü yapımında bu yaklaşımı veya arabaları için araba tasarımcılarını kullansaydı, köprülerini veya arabalarını çok yüksek maliyetle yeniden şekillendireceklerdi ve sonuç, iyi düşünülmüş bir mimariye sahip olmayan yamalı bir karışıklık olurdu. . "Geçene kadar refaktör" kılavuzu genellikle mimari tasarımı unutmak ve sınava uymak için ne gerekiyorsa ; diğer bir deyişle, kullanıcı yerine test gereksinimi belirler. Bu durumda, sonuçlarda iyi "şeyleri" nasıl garanti edebiliriz, yani sadece doğru değil aynı zamanda genişletilebilir, sağlam, kullanımı kolay, güvenilir, güvenli, güvenli, vb. Nihai sonuç? Mimari genellikle bunu yapar.
  2. Test, bir sistemin çalıştığını garanti edemez; sadece olmadığını gösterebilir. Başka bir deyişle, test, bir sistemin bir testten geçememesi durumunda hata içerdiğini gösterebilir, ancak tüm testleri geçen bir sistem, bunları başarısız olan bir sistemden daha güvenli değildir. Test kapsamı, test kalitesi ve diğer faktörler burada çok önemlidir. "Tüm yeşil" sonuçların birçok kişiye ürettiği yanlış güvenli duygular sivil ve havacılık endüstrilerinde son derece tehlikeli olarak rapor edilmiştir, çünkü "sistem iyi" anlamına geldiğinde "sistem iyi" anlamına geldiğinde yorumlanabilir "test stratejimiz olarak". Genellikle, test stratejisi kontrol edilmez. Ya da testleri kim test ediyor?

Özetle, TDD'deki "tahrikli" bit hakkında "test" bitinden daha fazla endişeliyim. Test mükemmel bir şekilde tamam; elde edemediğim şey, tasarımı yaparak onu sürmektir.

Yazılım mühendisliğinde TDD'nin neden iyi bir uygulama olduğunu ve yukarıda açıkladığım sorunların yazılım durumunda neden alakalı (ya da yeterince ilgili değil) nedenlerini içeren cevapları görmek istiyorum. Teşekkür ederim.

93
CesarGon

Bence burada bir yanılgı var. Yazılım tasarımında tasarım ürüne çok yakındır. İnşaat mühendisliğinde, mimaride, tasarım gerçek üründen ayrılır: tasarımı tutan, daha sonra bitmiş ürün haline getirilen ve büyük miktarlarda zaman ve çaba ile ayrılan taslaklar vardır.

TDD tasarımı test ediyor. Ancak her araba tasarımı ve bina tasarımı da test edilir. İnşaat teknikleri önce gerçek bir binaya yerleştirilmeden önce hesaplanır, daha sonra daha küçük ölçekte test edilir, daha sonra daha büyük ölçekte test edilir. Örneğin H-kirişlerini ve yükü icat ettiklerinde, bunun ilk deneme köprüsünü inşa etmeden önce denendiğinden ve tekrar denendiğinden emin oldular.

Otomobil tasarımları da prototipler tasarlanarak test edilir ve evet, kesinlikle doğru olmayan şeyleri beklentileri karşılayana kadar ayarlayarak. Bu sürecin bir kısmı daha yavaş, çünkü dediğin gibi, ürünle çok fazla uğraşamazsın. Ancak bir otomobilin her yeniden tasarımı, eskilerinden öğrenilen deneyimlere dayanır ve her binanın arkasında, alan, ışık, yalıtım, güç vb. Önemi hakkında yaklaşık binlerce temel temel vardır. Hem binalarda ayrıntılar değiştirilir ve geliştirilir. ve yenileri için yeniden tasarımlarda.

Ayrıca, parçalar test edilir. Belki de yazılımla tam olarak aynı tarzda değildir, ancak mekanik parçalar (tekerlekler, ateşleyiciler, kablolar) genellikle ölçülür ve boyutların doğru olduğunu, herhangi bir anormallik görülmeyecek, vb. ölçülürse, kırık olanları tespit etmek için tuğlalara dokunurlar, aslında bazı yapılandırmalarda veya diğerlerinde test edilebilirler veya gerçekten test etmek için büyük bir grubun sınırlı bir temsilini çizerler.

Bunların hepsi TDD ile yerine koyabileceğiniz şeyler.

Ve gerçekten, test etmek bir garanti değildir. Programlar patlar, arabalar bozulur ve binalar rüzgar eserken komik şeyler yapmaya başlar. Ama ... 'güvenlik' boole bir soru değil. Her şeyi dahil edemeseniz bile, olasılıkların% 99'unu kapsayabilmek, sadece% 50'sini kapsamaktan daha iyidir. Test etmemek ve daha sonra çeliği bulmak iyi yerleşmedi ve kırılgan ve kırıcı ilk kırıldığında sadece ana yapınızı koyduğunuzda basit bir para israfı. Binaya hâlâ zarar verebilecek başka endişeler olması, kolayca önlenebilir bir kusurun tasarımınızı düşürmesine izin vermeyi daha az aptal yapmaz.

TDD uygulamasına gelince, bu bir dengeleme meselesidir. Bunu bir şekilde yapmanın maliyeti (örneğin, test etmemek ve daha sonra parçaları daha sonra almak), başka bir yolla yapmanın maliyeti. Her zaman bir dengedir. Ancak diğer tasarım süreçlerinin test ve TDD'nin yerinde olmadığını düşünmeyin.

66
Inca

IMO, TDD'nin başarı öykülerinin çoğu sahte ve sadece pazarlama amaçlı. Bununla çok az başarı olabilir, ancak sadece küçük uygulamalar için. TDD ilkelerinin kullanıldığı büyük bir gümüş ışık uygulaması üzerinde çalışıyorum. Uygulamanın yüzlerce testi var ama hala kararlı değil. Uygulamanın çeşitli bölümleri karmaşık kullanıcı etkileşimleri nedeniyle test edilemez. Çok sayıda alay ve anlaşılması zor kodlarla sonuçlanan testler.

Başlangıçta TDD'yi denediğimizde her şey iyi görünüyor. Bir çok test yazabildim ve bir birim test için zor olan parçaları alay ettim. Yeterli miktarda koda sahip olduğunuzda ve arayüz değişikliği gerektiğinde vidalanmış olursunuz. Birçok testin düzeltilmesi gerekiyor ve koddaki gerçek değişiklikten daha fazla test yazacaksınız.

Peter Norvig İşyerinde Kodlayıcılar kitabında TDD hakkındaki görüşünü açıklıyor.

Seibel: Tasarımı yönlendirmek için testler kullanma fikri ne olacak?

Norvig: Testleri tasarımın değil hataları düzeltmenin bir yolu olarak görüyorum. “Eh, yaptığınız ilk şey, sonunda doğru cevabı aldığımı söyleyen bir test yazmak” diyen bu aşırı yaklaşım ve sonra onu çalıştırıp başarısız olduğunu görüyorsunuz ve sonra “Ne yapacağım Sırada ne var? ”- bu bana bir şey tasarlamanın doğru yolu gibi görünmüyor. Sadece çözüm o kadar basit olsaydı, mantıklı gelebilirdi. Bence ilk önce bunu düşünmelisin. “Parçalar neler? Bazılarının ne olduğunu öğreninceye kadar parçalar için nasıl test yazabilirim? ” Ve sonra, bunu yaptıktan sonra, bu parçaların her biri için testler yapmak ve birbirleriyle ve sınır vakalarıyla nasıl etkileşime girdiklerini iyi anlamak iyi bir disiplindir. Bunların hepsinin testleri olmalı. Ancak, “Bu test başarısız oldu” diyerek tüm tasarımı sürdüğünüzü sanmıyorum.

26
Navaneeth K N

Test Odaklı Tasarım aşağıdaki nedenlerle benim için çalışıyor:

Şartnamenin çalıştırılabilir bir şeklidir.

Bu, test durumlarından görebileceğiniz anlamına gelir:

  1. [~ # ~] [~ # ~] tam olarak çağrılan kod, beklenen sonuçlar doğrudan test senaryolarında olduğu için spesifikasyonu doldurur. Görsel inceleme (test senaryolarının geçmesini beklemektedir) derhal "oh, bu test, bu durum söz konusu olan faturaşirketini çağırmanın BU sonuca sahip olması gerektiğini kontrol eder".
  2. [~ # ~] nasıl [~ # ~] kod çağrılmalıdır. Testleri yapmak için gereken gerçek adımlar, herhangi bir harici iskele olmadan doğrudan belirlenir (veritabanları alay edilir, vb.).

Görünümü önce dışarıdan yazarsınız.

Sıklıkla kod, önce sorunu çözeceğiniz şekilde yazılır ve daha sonra az önce yazdığınız kodun nasıl çağrılacağını düşünürsünüz. Bu sık sık garip bir arayüz verir, çünkü "sadece bir bayrak eklemek" vb. Daha kolaydır. "Bunu yapmamız gerektiğini düşünerek testislerin bu şekilde görünmesini" öneriyoruz. Kod, arama arayüzüne göre yazılacak, aksi takdirde daha iyi bir modülerlik verecektir.

Bu genellikle daha az açıklayıcı dokümantasyon gerektiren daha temiz kodlarla sonuçlanır.

Daha hızlı iş yapıyorsun

Çalıştırılabilir formda belirtime sahip olduğunuzdan, tam test paketi geçtiğinde işiniz tamamlanır. İşleri daha ayrıntılı bir düzeyde açıklığa kavuştururken daha fazla test ekleyebilirsiniz, ancak temel bir ilke olarak ilerlemenin ne zaman ve bittiğinde çok net ve görünür bir göstergeye sahipsiniz.

Bu, işin ne zaman gerekli olup olmadığını söyleyebileceğiniz anlamına gelir (bir testi geçmeye yardımcı olur), daha az yapmanız gerekir.

Üzerinde düşünenler için yararlı olabilir, bir sonraki kütüphane rutininiz için TDD kullanmanızı tavsiye ederim. Yavaşça çalıştırılabilir bir şartname ayarlayın ve kodun testleri geçmesini sağlayın. Tamamlandığında, çalıştırılabilir özellik kitaplığı nasıl çağırdığını görmek isteyen herkes tarafından kullanılabilir.

Son Çalışma

"Vaka çalışmalarının sonuçları, dört ürünün serbest bırakma öncesi kusur yoğunluğunun TDD uygulamasını kullanmayan benzer projelere göre% 40 ile% 90 arasında azaldığını göstermektedir. Subjektif olarak ekipler, TDD'yi kabul ettikten sonra ilk geliştirme zamanı. " ~ 4 Endüstriyel Ekibin Sonuçları ve Deneyimleri

25
user1249

Yazılım oluşturma süreci, kodu yazma işlemi değildir. Hiçbir yazılım projesi ilk olarak 'geniş kapsam' planı olmadan başlamamalıdır. Tıpkı bir nehrin iki kıyısını köprüleme projesi için önce böyle bir plan gerekiyor.

TDD yaklaşımı (çoğunlukla) birim testi ile ilgilidir - en azından insanlar bunu düşünmeye eğilimlidir - bu, yazılım kodunun en düşük seviyeli bitlerini oluşturur. Tüm özellikler ve davranışlar zaten tanımlandığında ve aslında neyi başarmak istediğimizi biliyoruz.

Yapı mühendisliğinde biraz şöyle görünür:

“Bu iki metal parçasını birbirine bağlıyoruz ve bağlantının kesme kuvvetlerini x sırasıyla sürdürmesi gerekiyor. Bunu yapmak için en iyi bağlantı yöntemini test edelim '

Yazılımın bir bütün olarak çalışıp çalışmadığını test etmek için kullanılabilirlik testleri, entegrasyon testleri ve kabul testleri gibi başka testler de tasarlıyoruz. Bunlar da kodun yazılması ile ilgili fiili çalışma başlamadan önce tanımlanmalı ve birim testleri yeşil olduktan sonra yapılmalıdır.

Bkz. V Modeli: http://en.wikipedia.org/wiki/V-Model_%28software_development%29

Bir köprü için nasıl çalışacağını görelim:

  1. Yerel bir hükümet köprü inşa eden bir şirkete şunları söylüyor: "Bu iki noktayı birleştirmek için bir köprüye ihtiyacımız var. Köprü saatte n miktarda trafiğe izin verebilmeli ve 21 Aralık 2012 için hazır olmalıdır." Kabul testi: Şirket bu testi geçemezse tam (veya herhangi bir) para alamaz.

  2. Şirketin yönetimi proje çizelgesine karar verir. Her ekip için çalışma ekipleri ve hedefler belirlediler. Takımlar bu hedeflere ulaşmayacaksa - köprü zamanında inşa edilmeyecektir. Bununla birlikte - burada bir miktar esneklik var. Ekiplerden birinin bazı sorunları varsa, şirket gereksinimleri değiştirerek, taşeronları değiştirerek, daha fazla kişi işe alarak vb. Böylece tüm projenin hala 1. maddede belirlenen hedefe ulaşmasını telafi edebilir.

  3. Belirli köprü bileşenlerini tasarlamaktan sorumlu bir ekip içinde, yukarıda verdiğim örnekte olduğu gibi görünüyor. Bazen çözüm açıktır, çünkü köprüler inşa etmek hakkında geniş bir bilgi birikimimiz vardır (bu, yazılım geliştirmede iyi test edilmiş bir kütüphane kullanmak gibidir - sadece reklamı yapıldığı varsayılır). Bazen birkaç tasarım oluşturmanız ve en iyisini seçmek için test etmeniz gerekir. Yine de, bileşenin test edildiği kriterler önceden bilinmektedir.

19
Mchl

Bence TDD çalışıyor çünkü

  • Genelde herhangi bir spesifikasyon veya gereksinim kapsamına girmeyen bir hassasiyet düzeyinde uygulamaya karar vermeden önce ünitenin ne yapmasını istediğinizi tanımlamanıza zorlar.
  • Kodunuzu doğal olarak yeniden kullanılabilir hale getirir, çünkü hem testlerde hem de üretim senaryolarında kullanmanız gerekir
  • Daha iyi tasarımlara yol açmaya neden olan parçaları test etmek için daha küçük istekli olarak kod yazmanızı teşvik eder

Özellikle yükselttiğiniz noktalarda

  • Kod tuğla veya çelikten daha yumuşaktır, bu nedenle değiştirmek daha ucuzdur. Davranışın değişmediğinden emin olmak için testleriniz varsa daha ucuzdur
  • TDD, tasarım yapmamak için bir bahane değildir - genel olarak yüksek düzeyde bir mimari hala tavsiye edilir, çok fazla ayrıntı ile değil. Büyük Yukarı Ön Tasarım önerilmez, ancak yeterli tasarım yapılması teşvik edilir
  • TDD, bir sistemin çalışacağını garanti edemez, ancak aksi takdirde gözden kaçırılacak olan çok sayıda küçük hatanın kaymasını önler. Ayrıca, genellikle daha iyi faktörlü kodu teşvik ettiği için, buplak olma olasılığının daha az olması genellikle daha kolaydır
18
Gavin Clarke

TL; DR

Programlama hala bir tasarım faaliyetidir, inşaat değildir. Birim testleri, kodun yaptıklarını yaptığını doğrular, yararlı bir şey yapmaz. Test hataları gerçek değerdir, çünkü hataları erken yakalamanızı sağlarlar.

Kod Tasarımdır

PPP "Bob Amca" nın 7. Bölümünde doğrudan bu konuyu anlatıyor. Bölümün çok erken saatlerinde, Jack Reeves tarafından kodun tasarım olduğunu önerdiği bir mükemmel makale 'a atıfta bulunur (bağlantı, konuyla ilgili makalelerinin üçünü de toplayan bir sayfaya gider).

Bu argümanla ilgili ilginç olan şey, inşaatın çok pahalı bir faaliyet olduğu diğer mühendislik disiplinlerinden farklı olarak, yazılımın yapımının nispeten ücretsiz olmasıdır (IDE Yazma kodunu bir inşaat faaliyeti yerine bir tasarım faaliyeti olarak görüyorsanız, kırmızı-yeşil-refactor döngüsü temel olarak tasarımda bir alıştırmadır.Tasarımlar, testler, bunları karşılayacak kod ve yeni kodu mevcut sisteme entegre edin.

Şartname olarak TDD

TDD için yazdığınız birim testleri, spesifikasyonun anladığınız gibi doğrudan çevirisidir. Spesifikasyonunuzu minimum düzeyde karşılayan kod yazarak (testlerinizin yeşile dönmesini sağlar), yazdığınız tüm kodlar belirli bir amaç için oradadır. Bu amacın karşılanıp karşılanmadığı tekrarlanabilir bir testle doğrulanır.

Testleri İşlevselliğe Yazma

Birim testinde yaygın bir hata, koddan sonra testleri yazdığınızda, kodun ne yaptığını test ettiğini görürsünüz. Başka bir deyişle, bunun gibi testler göreceksiniz

public class PersonTest:Test
{
   [Test]
   TestNameProperty()
   {
      var person=new Person();
      person.Name="John Doe";
      Assert.AreEqual("John Doe", person.Name);
   }
}

Sanırım bu kod yararlı olabilir (birinin basit bir özellik ile müstehcen bir şey yapmadığından emin olun). Bir spesifikasyonu doğrulamaya hizmet etmez. Söylediğiniz gibi, bu tür testleri yazmak sizi o kadar ileri götürür.

Yeşil İyiyken Değer Kırmızı Renkte Beklenmedik bir test hatası aldığımda TDD'de ilk gerçek "aha" anımı yaşadım. Yaptığım bir çerçeve için yaptığım testler grubum vardı. Yeni bir özellik ekleyerek, bunun için bir test yazdım. Sonra testi geçmek için kod yazdı. Derleyin, test edin ... yeni testte yeşil var. Ama başka bir testte de kırmızı olmasını beklemediğim bir kırmızı var.

Başarısızlığa baktığımda rahat bir nefes alıyorum çünkü o testi yerinde olmasaydı bu hatayı oldukça uzun süre yakalayacağımdan şüpheliyim. Ve sahip olmak çok kötü bir hata oldu. Neyse ki, sınava girdim ve hatayı düzeltmek için ne yapmam gerektiğini söyledi. Test olmadan, sistemimi inşa etmeye devam ederdim (bu koda bağlı diğer modülleri enfekte eden hata ile) ve hatanın keşfedildiği zaman, düzgün bir şekilde düzeltmek için büyük bir görev olurdu.

TDD'nin asıl yararı, pervasız terk ile değişiklik yapmamıza izin vermesidir. Programlama için bir güvenlik ağı gibi. Bir trapez sanatçısı bir hata yapar ve düşerse ne olacağını düşünün. Ağ ile bu utanç verici bir hatadır. Olmadan, bu bir trajedi. Aynı şekilde, TDD sizi başlı hataları proje öldürme felaketlerine dönüştürmekten kurtarıyor.

16
Michael Brown

Test Odaklı Geliştirmeyi savunan, hatta Test Odaklı Tasarım (farklılar) diyen kimseyi bulamazsınız. Öyleyse buna saman adam diyelim ve yapılsın.

Testlerin zaman ve çaba kaybı olduğunu söyleyen TDD'den hoşlanmayan veya etkilenmeyen kimseyi bulamayacaksınız. Testler uygulamaları kanıtlamasa da, hata bulmada oldukça faydalıdır.

Bu iki şeyle birlikte, her iki taraf da yazılım üzerinde gerçekten test yapmak konusunda farklı bir şey yapmıyor. Her ikisi de test yapıyor. Hem mümkün olduğunca çok hata bulmak için testte RELY, hem de bir yazılım programının çalıştığını doğrulamak için testler kullanır ve o zaman keşfedilebilir. Yarım ipucuna sahip hiç kimse test yapmadan yazılım satmaz ve yarım ipucuna sahip hiç kimse testin sattıkları kodu tamamen hatasız hale getireceğini düşünmez.

Yani, TDD ile TDD değil arasındaki fark testlerin yapılmasından ibaret değildir. Fark, testler yazıldığında ortaya çıkar. TDD testlerinde yazılım ÖNCE yazılır. TDD'de olmayan testler yazılımdan sonra veya yazılımla birlikte yazılır.

İkincisi ile ilgili olarak gördüğüm sorun, testin daha sonra istenen sonucu veya spesifikasyondan daha fazla yazılan yazılımı hedefleme eğiliminde olmasıdır. Test ekibi geliştirme ekibinden ayrı olsa bile, test ekibi yazılıma bakma, onunla oynama ve onu hedefleyen testler yazma eğilimindedir.

Proje başarısı okuyanlar tarafından tekrar tekrar fark edilen bir şey, bir müşterinin ne sıklıkta ne istediğini ortaya koyması, kalkınma insanları kaçması ve bir şeyler yazması ve müşteriye "bitti" diyerek geri gelmesidir. müşterinin ne istediğini tamamen ve tamamen DEĞİLDİR. "Ama bütün testleri geçiyor ..."

TDD'nin amacı bu "dairesel argümanı" kırmak ve yazılımın kendisi olmayan yazılımı test eden testlere temel oluşturmaktır. Testler, "müşterinin" istediği davranışı hedeflemek için yazılmıştır. Yazılım daha sonra bu testleri geçmek için yazılır.

TDD, bölüm olsa da bu sorunu ele almak için tasarlanmış çözümdür. Attığın tek adım bu değil. Yapmanız gereken diğer şeyler, daha fazla müşteri geri bildirimi ve daha sık olduğundan emin olmaktır.

Benim tecrübelerime göre, TDD'nin başarıyla uygulanması çok zor bir şey. Bir ürün bulunmadan önce testlerin yazılması zordur, çünkü birçok otomatik test, otomasyon yazılımının düzgün çalışmasını sağlamak için oynamak için bir şeyler gerektirir. Bunu yapmak için birim testine alışkın olmayan geliştiricilere sahip olmak da zordur. Defalarca ekibimdeki insanlara İLK testleri yazmasını söyledim. Asla bir tane yapmadım. Sonunda, zaman kısıtlamaları ve siyaset tüm çabaları yok etti, böylece artık birim testleri bile yapmıyoruz. Bu, elbette, kaçınılmaz olarak, tasarımın yanlışlıkla ve ciddi bir şekilde birleştirilmesine yol açar, böylece istesek bile, şimdi uygulanması oldukça pahalıya mal olur. THD'den kaçınmak, TDD'nin nihayetinde geliştiriciler için sağladığı şeydir.

11
Edward Strange

Önce tasarım

TDD değil tasarımı atlamak için bir bahane. Hemen çevik kodlamaya başlayabildikleri için "çevik" bandwagonda birçok sıçrama gördüm. Gerçek çeviklik, kodlama işlemini şelale sürecine ilham veren (diğer alan) mühendislik iyi uygulamalarından çok daha hızlı hale getirecektir.

Ama erken test edin

Testin tasarımı sürdürdüğünü söylediğinde, testlerin tasarım aşamasında çok erken, tamamlanmadan çok önce kullanılabileceği anlamına gelir. Bu testleri yapmak, gri alanlara meydan okuyarak ve ürün tamamlanmadan çok önce gerçek dünyayla karşılaştırarak tasarımınızı güçlü bir şekilde etkileyecektir. sizi sık sık tasarıma geri dönmeye ve bunu hesaba katmak için ayarlamaya zorlar.

Test ve tasarım ... bir ve aynı

Kanımca TDD, testin doğrulanması için sonunda yapılan bir şey yerine integral tasarımın bir parçası olmasını sağlar. TDD'yi giderek daha fazla kullanmaya başladığınızda, sisteminizi tasarlarken nasıl yok edeceğinizi/bozacağınızı düşünürsünüz. Şahsen ben her zaman ilk olarak testlerimi yapmam. Tabii ki bir arayüz üzerinde bariz (birim) testler yapıyorum ama gerçek kazanımlar, bu tasarımın kırılabileceği yeni ve yaratıcı bir yol düşündüğümde yarattığım entegrasyon ve spesifikasyon testlerinden geliyor. Bir yolu düşündüğümde, bunun için bir test kodlarım ve ne olduğunu görüyorum. Bazen sonuçla yaşayabilirim, bu durumda testi ana yapının bir parçası olmayan ayrı bir projede taşıyorum (başarısız olmaya devam edeceği için).

O zaman şovu kim yürütüyor?

TDD'de buradaki sürüş, testlerinizin tasarımınızı o kadar güçlü bir şekilde etkilediği anlamına gelir; Ancak bu konuda durur ve endişelerinizi anlıyorum, biraz korkutucu ... şovu kim yönlendiriyor?

SIZ sürüş yapıyorsunuz, testler değil. Testler var, böylece siz ilerledikçe, yarattığınız şeye iyi bir güven duyuyorsunuz, böylece daha sağlam bir zemine dayandığını bilmenizi sağlar.

testler sağlam olduğu sürece katı

Kesinlikle, dolayısıyla TDD'de sürülüyor. Testler her şeyi yönlendiriyor o kadar da değil, ama bir şeyleri nasıl yaptığınız, sisteminizi nasıl tasarladığınız ve düşündüğünüz üzerinde çok derin bir etkiye sahip olacaklar, düşünce sürecinizin büyük bir kısmını testlere ve karşılığında devredeceksiniz tasarımınız üzerinde derin bir etkisi olacaktır.

evet ama bunu benim köprü th ile yaparsam ....

orada dur ... yazılım mühendisliği, diğer mühendislik uygulamalarından ÇOK farklı. Aslında yazılım mühendisliğinin edebiyatla çok daha fazla ortak yanı vardır. Bir bitmiş kitap alabilir, ondan 4 bölüm rip ans onları kitapta geri sopa yerine iki yeni bölüm yazmak ve hala iyi bir kitap var. İyi testler ve yazılımlar ile sisteminizin herhangi bir bölümünü kopyalayabilir ve bir başkasıyla değiştirebilirsiniz ve bunu yapmanın maliyeti ilk etapta yarattığından çok daha yüksek değildir. Aslında, testlerinizi yaptıysanız ve tasarımınızı yeterince etkilemelerine izin verdiyseniz, ilk etapta onu oluşturmaktan çok daha ucuz olabilir, çünkü bu değiştirmenin testlerin kapsamını bozmayacağına dair belirli bir güven seviyeniz olacaktır.

Sooo iyi ise nasıl olur her zaman işe yaramaz?

Çünkü test etmek binadan çok farklı bir zihniyet gerektirir. Herkes geri dönüp geçemez, aslında bazı insanlar sadece kendi yarattıkları şeyi yok etmek için akıllarını ayarlayamadıkları için uygun testler yapamazlar. Bu, çok az test içeren projeler veya hedef metriklere ulaşmak için yeterli testler verecektir (kod kapsamı akla gelir). Yol testlerini ve istisna testlerini mutlu edecekler, ancak köşe vakalarını ve sınır koşullarını unutacaklar.

Diğerleri, tasarımın kısmen veya tamamen yapılmasını gerektiren testlere güveneceklerdir. Bunu yapan her üye birbiri ile bütünleşir. Tasarım her şeyden önce bir iletişim aracıdır, yerde olduğumuzu söylemek için yere koyduğumuz kazıklar, kapıların ve pencerelerin nerede olduğunu söyleyen eskizler. Bu olmadan, yazılım, ne kadar test yaptığınıza bakılmaksızın mahkumdur. Entegrasyon ve birleşme her zaman acı verici olacak ve en yüksek soyutlama seviyelerinde testlerden yoksun olacaklardır.

Bu takımlar TDD gidilecek yol olmayabilir.

9
Newtopian

TDD ile test edilmesi kolay veya hızlı olmayan kod yazma eğiliminde değilsiniz. Bu küçük bir şey gibi görünebilir, ancak hataları yeniden test etmenin, test etmenin, testlerle çoğaltmanın ve düzeltmeleri doğrulamanın ne kadar kolay olduğunu etkilediğinden, bir proje üzerinde derin bir etkisi olabilir.

Projelerdeki yeni bir geliştiricinin, testler tarafından desteklenen daha iyi faktörlü koda sahip olduğunuzda hız kazanması da daha kolaydır.

7
Alb

TDD'yi o kadar çok uygulamasam da, bunu çok düşünüyorum. Kod kalitesi ile takip eden TDD arasında pozitif (güçlü?) Bir korelasyon var gibi görünüyor.

1) İlk olarak, bunun (öncelikle) TDD'nin koda "daha iyi kalite" eklemesi (bunun gibi) nedeniyle olmaması, TDD'nin en kötü kısımları ve alışkanlıkları ayıklamaya yardımcı olması ve dolaylı olarak kaliteyi arttırması gibi.

Testin kendilerinin olmadığını bile savunuyorum - bu testlerin yazılması sürecidir. Kötü bir kod için test yazmak zordur, ya da tam tersi. Ve programlama sırasında bunu kafanın arkasında tutmak, çok kötü kodu ortadan kaldırır.

2) Başka bir bakış açısı (bu felsefi hale geliyor) ustanın zihinsel alışkanlıklarını takip etmektir. Onun "dışsal alışkanlıklarını" takip ederek usta olmayı öğrenemezsiniz (uzun sakal iyidir), içsel düşünme yollarını öğrenmelisiniz ve bu zor. Ve bir şekilde (acemi) programcılar TDD'yi takip eder, düşünme biçimlerini ustanınkine daha yakın hale getirir.

5
Maglob

"Yazma testi + geçene kadar refactor" yaklaşımı inanılmaz derecede mühendislik karşıtı görünüyor.

Hem yeniden düzenleme hem de TDD hakkında yanlış bir fikriniz var gibi görünüyor.

Kod yeniden düzenleme , yazılımın işlevsiz özelliklerinden bazılarını iyileştirmek için bir bilgisayar programının kaynak kodunu harici işlev davranışını değiştirmeden değiştirme işlemidir.

Böylece refactor kodu geçene kadar kodlayamazsınız.

Ve TDD, özellikle birim testi (ki diğer testler benim için oldukça makul göründüğü için temel iyileştirmeyi düşünüyorum), bir bileşeni çalışana kadar yeniden tasarlamakla ilgili değil. Bir bileşen tasarlamak ve bileşen tasarlandığı gibi çalışana kadar uygulama üzerinde çalışmakla ilgilidir.

Ayrıca, birim testin test birimler olduğunu anlamak da önemlidir. Her zaman sıfırdan çok şey yazma eğilimi nedeniyle, bu tür birimleri test etmek önemlidir. Bir inşaat mühendisi kullandığı ünitelerin özelliklerini (farklı malzemeler) zaten biliyor ve çalışmalarını bekleyebilir. Bunlar genellikle yazılım mühendisleri için geçerli olmayan iki şeydir ve birimleri kullanmadan önce test etmek çok pro-mühendisliktir, çünkü test edilmiş, yüksek kaliteli bileşenler kullanmak anlamına gelir.
Bir inşaat mühendisi, bir stadyumu örtmek için bir çatı yapmak için yeni bir lif dokusu kullanma fikrine sahip olsaydı, bir birim olarak test etmesini, yani gerekli özellikleri (örneğin ağırlık, geçirgenlik, stabilite) tanımlamasını beklersiniz. vb.) ve daha sonra bunları karşılayana kadar test edin ve hassaslaştırın.

İşte bu yüzden TDD çalışıyor. Çünkü test edilmiş birimlerin yazılımını oluşturursanız, çok daha iyi çalışır, bunları birbirine bağladığınızda ve eğer yapmazsanız, testlerinizin iyi bir kapsama sahip olduğunu varsayarak sorunun tutkal kodunuzda olmasını bekleyebilirsiniz.

düzenleme:
Yeniden düzenleme, şu anlama gelir: hayır işlevsellik değişikliği. Birim testi yazmanın bir noktası, yeniden düzenleme işleminin kodu kırmamasını sağlamaktır. Dolayısıyla TDD, yeniden düzenlemenin yan etkileri olmadığını garanti etmeyi amaçlamaktadır.
Taneciklik bir perspektif konusu değildir, çünkü dediğim gibi, birim taneciklerin tam olarak tanımlandığı sistemleri değil, test birimlerini test eder.

TDD iyi mimariyi teşvik eder. Tüm birimleriniz için teknik özellikleri tanımlamanızı ve uygulamanızı gerektirir; bu da onları uygulama öncesinde tasarlamaya zorlar; bu da düşündüğünüzün aksine. TDD, ayrı ayrı test edilebilen ve böylece tamamen ayrılan birimlerin oluşturulmasını belirler.
TDD, spagetti koduna bir yazılım testi attığım ve makarnayı geçene kadar karıştırdığım anlamına gelmiyor.

İnşaat mühendisliğine aykırı olarak, yazılım mühendisliğinde bir proje genellikle sürekli olarak gelişir. İnşaat mühendisliğinde, A konumunda x ton taşıyabilen ve saatte n araç için yeterince geniş bir köprü inşa etme gereksiniminiz vardır.
Yazılım mühendisliğinde, müşteri temelde herhangi bir noktada (muhtemelen tamamlandıktan sonra) karar verebilir, iki katına çıkmış bir köprü istiyor ve en yakın otoyolla bağlantı kurmasını istiyor ve bir kaldırma olmasını istiyor çünkü kısa süre önce şirketi yelkenli gemi kullanmaya başladı.
Yazılım mühendisleri tasarımları değiştirmekle görevlendirildi . Tasarımları kusurlu olduğu için değil, bu modus operandi olduğu için. Yazılım iyi tasarlanmışsa, tüm düşük seviye bileşenleri yeniden yazmak zorunda kalmadan yüksek seviyede yeniden tasarlanabilir.

TDD, bireysel olarak test edilmiş, birbirinden ayrıştırılmış bileşenlere sahip yazılım oluşturmakla ilgilidir. İyi yürütülmüş, gereksinimlerdeki değişikliklere, olmadan daha hızlı ve daha güvenli bir şekilde yanıt vermenize yardımcı olacaktır.

TDD, geliştirme sürecine gereksinimler ekler, ancak başka herhangi bir kalite güvence yöntemini yasaklamaz. TDD, resmi doğrulama ile aynı güvenliği sağlamaz, ancak daha sonra, resmi doğrulama, son derece pahalı ve sistem düzeyinde kullanılması imkansızdır. Ve yine de, isterseniz, ikisini de birleştirebilirsiniz.

TDD ayrıca sistem seviyesinde yapılan birim testleri dışındaki testleri de kapsar. Bunları açıklamak kolay ama uygulanması zor ve ölçülmesi zor buluyorum. Ayrıca, oldukça makul. Gereksinimlerini kesinlikle görsem de, onlara fikir olarak gerçekten değer vermiyorum.

Sonunda, hiçbir araç aslında bir sorunu çözmez. Araçlar yalnızca sorun çözmeyi kolaylaştırır. Şunu sorabilirsiniz: Bir keski harika mimariyle bana nasıl yardımcı olacak? Düz duvarlar yapmayı planlıyorsanız, düz tuğlalar yardımcı olur. Ve evet, bu aracı bir aptala verirseniz, muhtemelen sonunda ayağından çarpacaktır, ancak acemilere yanlış güvenlik sağladığı bir TDD kusuru olmadığı sürece, bu keski hatası değildir, iyi testler yazmayanlar.
Sonuç olarak, TDD'nin TDD'den çok daha iyi çalıştığını söyleyebiliriz.

3
back2dos

Sanırım ilk noktaya yanlış açıdan yaklaşıyorsunuz.

Teorik bir bakış açısından, bir şeyin başarısızlık noktalarını kontrol ederek işe yaradığını kanıtlıyoruz. Kullanılan yöntem budur. Bir şeyin işlevsel olduğunu kanıtlamanın başka birçok yolu olabilir, ancak TDD, biraz akıllıca yaklaşımının basitliğinden dolayı kendini kurmuştur: eğer kırılmazsa çalışır.

Uygulamada, bu açık bir şekilde şu anlama gelir: şimdi bir sonraki şeye geçebiliriz (tüm tahminleri karşılamak için TDD'yi başarıyla uyguladıktan sonra). TDD'ye bu perspektiften yaklaşırsanız, o zaman "yazma testleri + geçene kadar refactor" ile ilgili değil, daha çok bunu tamamladıktan sonra, şimdi bir sonraki özelliğe şu an en çok odaklanıyorum önemli şey .

Bunun inşaat mühendisliği için nasıl geçerli olduğunu düşünün. 150000 kişilik bir kitleye ev sahipliği yapacak bir stadyum inşa ediyoruz. Stadyumun yapısal bütünlüğünün sağlam olduğunu kanıtladıktan sonra, önce güvenlik. Artık lavabolar, yemek standları, koltuklar vb. Gibi hemen önem kazanan diğer konulara odaklanabiliriz ... izleyicinin deneyimini daha keyifli hale getirebiliriz. Bu, TDD'de çok daha fazlası olduğu için aşırı basitleştirmedir, ancak en önemlisi, hem yeni hem de heyecan verici özelliklere odaklanmanız ve aynı zamanda bütünlüğü korumanız durumunda mümkün olan en iyi kullanıcı deneyimini yapmamanızdır. Her iki durumda da yarım yol alırsınız. Yani, nasıl birçok tuvaleti tam olarak nasıl bilebilirsiniz ve 150000 kişi için nereye yerleştirmelisiniz? Stadyumların kendi yaşamımda çöktüğünü nadiren gördüm, ancak birçok kez yarı zamanlı sırada beklemek zorunda kaldım. Bu, lavabo probleminin tartışmasız daha karmaşık olduğunu ve mühendislerin güvenlik için daha az zaman harcayabilecekleri takdirde, nihayet lavabo sorununu çözebileceklerini söylüyor.

İkinci noktanız önemsizdir, çünkü mutlakların aptal bir çaba olduğu ve Hank Moody'nin var olmadıklarını söylediğinden (ama bunun için bir referans bulamadığımı) zaten kabul etmiştik.

2
Filip Dupanović

'Kullanıcı yerine testi belirler' demeyi sevmiyorum. Sanırım TDD'de sadece birim test etmeyi düşünürken, entegrasyon testini de kapsıyor.

Yazılımın temelini oluşturan kütüphaneleri test etmenin yanı sıra, kullanıcılarınızın yazılım/web sitesi/ne olursa olsun etkileşimlerini kapsayan testleri yazın. Bunlar doğrudan kullanıcılardan gelir ve salatalık (http://cukes.info) gibi kütüphaneler, kullanıcılarınızın testleri kendileri doğal dilde yazmalarına bile izin verebilir.

TDD ayrıca kod esnekliğini de teşvik eder - sonsuza dek bir şeyin mimarisini tasarlamak için harcarsanız, gerekirse daha sonra bu değişiklikleri yapmak inanılmaz derecede zor olacaktır. Birkaç test yazarak başlayın, ardından bu testleri geçen küçük bir kod yazın. Daha fazla test ekleyin, daha fazla kod ekleyin. Kodu kökten değiştirmeniz gerekirse, testleriniz devam eder.

Ve köprülerden ve arabalardan farklı olarak, tek bir yazılım ömrü boyunca büyük değişikliklere uğrayabilir ve testleri ilk kez yazmadan karmaşık yeniden düzenleme yapmak sadece sormak sorun için.

2
sevenseacat

Hataların ne kadar erken bulunduğunu kabul ederseniz, bunları düzeltmenin maliyeti o kadar az olur, o zaman bu sadece TDD'yi değerli kılar.

1
SnoopDougieDoug

Yazılım mühendisliğinde TDD, uygulamalardaki hata işlemenin yanı sıra günlük tutma ve tanılamanın yanı sıra (hata işlemenin bir parçası olmasına rağmen) iyi bir uygulamadır.

TDD, yazılım geliştirmeyi deneme yanılma kodlamasına indirgeyen bir araç olarak kullanılmaz. Ancak yine de, çoğu programcı çalışma günlüğü günlüklerine bakar, hata ayıklayıcıdaki istisnaları izler veya geliştirme günlerinde uygulamayı gün boyunca kodlama/derleme/çalıştırmadan oluşan diğer başarısızlık/başarı belirtilerini kullanır.

TDD, sizi geliştirici olarak daha üretken hale getirmek için bu adımları resmileştirmenin ve otomatikleştirmenin bir yoludur.

1) Yazılım mühendisliğini köprü yapımıyla karşılaştıramazsınız, köprü yapımındaki esneklik bir yazılım programı tasarlamanınkine yakın değildir. Köprünün inşası aynı programı tekrar tekrar kayıplı bir makineye yazmak gibidir. Köprüler, yazılımın yapabileceği gibi çoğaltılamaz ve tekrar kullanılamaz. Her köprü benzersizdir ve imal edilmesi gerekir. Aynı şey otomobiller ve diğer tasarımlar için de geçerli.

Yazılım mühendisliğindeki en zor şey, hataların çoğaltılmasıdır, bir köprü başarısız olduğunda neyin yanlış gittiğini belirlemek genellikle çok kolaydır ve teoride başarısızlığı yeniden oluşturmak kolaydır. Bir bilgisayar programı başarısız olduğunda, sistemi hatalı duruma getiren karmaşık bir olaylar zinciri olabilir ve hatanın nerede olduğunu belirlemek çok zor olabilir. TDD ve birim testi, yazılım bileşenlerinin, kitaplıkların ve algoritmaların sağlamlığını test etmeyi kolaylaştırır.

2) Sistemin yanlış güven duygusu yaratmasını zorlamayan zayıf birim testleri ve sığ test senaryolarının kullanılması sadece kötü bir uygulamadır. Bir sistemin mimari kalitesini göz ardı etmek ve sadece testleri yerine getirmek elbette kötüdür. Ancak inşaat yerinde bir gökdelenin veya malzemeyi kurtarmak ve köprüleri takip etmemek için bir köprü için hile yapmak kötüdür ve her zaman olur ...

1
Ernelli

Size kısa bir cevap vereceğim. Tipik olarak TDD, tıpkı birim testleri gibi yanlış bir şekilde ele alınır. İyi bir teknik konuşma videosu izledikten sonra yakın zamana kadar birim testini hiç anlamadım. Temelde TDD sadece aşağıdakileri ÇALIŞMAK istediğinizi belirtmektedir. Bunlar uygulanmalıdır ZORUNLU. Sonra yazılımın geri kalanını normal şekilde tasarlarsınız.

Yazma gibi bir kütüphane tasarım önce bir kütüphane için kullanım örnekleri. Dışında bir kütüphanede kullanım durumunu değiştirebilirsiniz ve TDD için olmayabilir (API tasarımı için TDD kullanıyorum). Ayrıca daha fazla test eklemeniz ve testin alabileceği vahşi girdileri/kullanımları düşünmeniz önerilir. Bir şeyi değiştirirseniz, bir şeyi bozduğunuzu bilmeniz gereken kütüphaneler veya API'lar yazarken yararlı buluyorum. Çoğu günlük yazılımda, neden bir düğmeye basarak bir kullanıcı için bir test senaryosuna ihtiyacım olduğu veya bir CSV listesi veya her satırda bir giriş içeren bir liste kabul etmek istediğim için rahatsız etmiyorum ... Bu gerçekten izin verdiğim önemli değil değiştirmek için bu yüzden ben TDD kullanmak/cant gerekir.

0
user2528

TDD neden çalışır?

Öyle değil.

Açıklama: otomatik testler test olmamasından daha iyidir. Ancak şahsen, birim testlerin çoğunun israf olduğunu düşünüyorum çünkü genellikle totolojiktir (yani test edilen gerçek koddan açıkça anlaşılan şeyler söyler) ve tutarlı, gereksiz değil ve tüm sınır durumlarını (hataların genellikle oluştuğu) kapsadıkları kolayca kanıtlanamaz ).

Ve en önemlisi: İyi yazılım tasarımı, birçok çevik/TDD evangelisti tarafından tanıtıldığından sihirli bir şekilde testlerden düşmez. Aksi iddia eden herkes lütfen bunu kanıtlayan hakemli bilimsel araştırmalara bağlantılar sağlayın veya en azından TDD'nin faydalarının kod değişiklikleri geçmişi ile potansiyel olarak incelenebileceği bazı açık kaynaklı projelere referans verin.

0
KolA

TDD gerçekten test etmekle ilgili değil. Ve kesinlikle iyi testlerin yerini tutmaz. Size verdiği şey, iyi düşünülmüş, tüketicinin tüketmesi kolay, bakımı kolay ve daha sonra yeniden düzenleyen bir tasarım. Bu şeyler daha az hataya ve daha iyi, daha uyarlanabilir bir yazılım tasarımına yol açar. TDD, varsayımlarınızı düşünmenize ve belgelemenize de yardımcı olur ve çoğu zaman yanlış olduğunu tespit eder. Bunları sürecin erken aşamalarında buluyorsunuz.

Güzel bir yan fayda olarak, bir yeniden düzenleme işleminin yazılımınızın davranışını (girişler ve çıkışlar) değiştirmediğinden emin olmak için çalıştırabileceğiniz büyük bir test paketine sahipsiniz.

0
Marcie

Yazılım, yapısal mühendislik somut olduğunda organiktir.

Köprünüzü inşa ettiğinizde, bir köprü olarak kalacaktır ve kısa bir süre içinde başka bir şeye dönüşmesi olası değildir. İyileştirmeler aylar ve yıllar boyunca yapılacaktır, ancak yazılımda olduğu gibi saatler ve günler değil.

Tek başına test ettiğinizde, normalde kullanabileceğiniz iki tür çerçeve vardır. Kısıtlı çerçeve ve kısıtlanmamış. Kısıtlanmamış çerçeveler (.NET'te) erişim değiştiricilerinden bağımsız olarak her şeyi test etmenize ve değiştirmenize olanak tanır. Yani özel ve korumalı bileşenleri saplayabilir ve taklit edebilirsiniz.

Gördüğüm projelerin çoğunda kısıtlı çerçeveler (RhinoMocks, NSubstitute, Moq) kullanılıyor. Bu çerçevelerle test ettiğinizde, uygulamanızı çalışma zamanında bağımlılıkları enjekte edebilecek ve değiştirebilecek şekilde tasarlamanız gerekir. Bu, gevşek bağlı bir tasarıma sahip olmanız gerektiği anlamına gelir. Gevşek bağlı tasarım (doğru yapıldığında) endişelerin daha iyi ayrılmasını gerektirir, bu iyi bir şeydir.

Özetlemek gerekirse, bunun arkasında düşünmenin, tasarımınız test edilebilirse, bu nedenle gevşek bir şekilde bağlanmış ve endişelerin iyi bir şekilde ayrıldığına inanıyorum.

Bir yan notta, gerçekten test edilebilir, ancak nesne yönelimli tasarım perspektifinden kötü yazılmış uygulamaları gördüm.

0
CodeART