it-swarm.asia

TDD neden üniversitelerde daha popüler değil?

Son zamanlarda, burada bir kişi Python bir listedeki elemanların tüm permütasyonlarında nasıl hesaplanacağı hakkında temel bir soru sordu.Öğrenciler tarafından sorulan çoğu soruya gelince, gerçek kaynak kodunu cevabımı değil, daha çok soruna nasıl yaklaşılacağını açıkladı.

Sorunun kendisini düşünerek, ben üniversitede programlama okurken çözmem gereken benzer sorunları hatırladım. Biz hiçbir zaman test odaklı geliştirme hakkında ne de karşılaştırılabilir herhangi bir yöntem öğretilmedi, ancak yine de sürekli bir listeden öğeleri sıralamak veya Hanoi Towers bulmaca, vb çözmek algoritmalar yazmak istendi. SoftwareEngineering gelen tüm öğrenciler ne de görünüyor. TDD'nin (Test Odaklı Geliştirme) kendilerine verilen sorunları çözmelerine nasıl yardımcı olacağını bilmek: eğer olsaydı, sorularını çok farklı formüle ederlerdi.

Gerçek şu ki, TDD olmadan, tüm bu problemler gerçekten oldukça zordur. Kendimi profesyonel bir geliştirici olarak görüyorum, ancak yine de TDD olmadan bir liste sipariş algoritması yazmak için biraz zaman harcayacağım ve hala bir listedeki öğelerin tüm permütasyonlarını hesaplamam istenirse çoğunlukla clueless olurdum TDD kullanarak. TDD ile öğrenciye cevabı yazarken permütasyon problemini birkaç dakika içinde çözdüm.

TDD'nin ya hiç öğretilmemesinin ya da en azından üniversitelerde geç kalmasının nedeni nedir? Diğer bir deyişle, TDD yaklaşımını daha önce öğrencilerden liste sıralama algoritmaları ve benzeri şeyler yazmalarını istemek sorun olur mu?


Soruların ikisindeki açıklamaları takip ederek:

Sorunuzda TDD'yi bir "problem çözme cihazı" olarak görüyorsunuz [...] Geçmişte TDD bir "çözüm bulma mekanizması" olarak sunulmuştu, ancak Bob Martin (TDD'nin ana savunucusu) bile tekniğe önemli miktarda ön bilgi getirmelisiniz.

ve özellikle:

TDD'nin neden iyi tanımlanmış bir spesifikasyonla zor bir algoritma problemi yaptığını düşündüğünüzü merak ediyorum.

Bence sorun çözme konusunda TDD hakkında bu kadar büyülü olanı biraz daha açıklamanın gerekli olduğunu düşünüyorum.

Lisede ve üniversitede, problemleri çözmek için herhangi bir spesifik tekniğim yoktu ve bu hem programlama hem de matematik için geçerliydi. Retrospektif olarak, bu tekniklerden birinin mevcut/son dersi/dersi gözden geçirmek ve alıştırma ile ilişki aramak olduğunu düşünüyorum. Eğer ders integrallerle ilgiliyse, öğretmenin çözmesini istediği sorunun integralleri kullanma olasılığı vardır. Ders özyineleme ile ilgiliyse, öğrencilere verilen bulmacanın özyineleme kullanılarak çözülme şansı vardır. Ayrıca matematikteki problemleri çözmede iyi biçimlendirilmiş yaklaşımlar olduğundan eminim ve bu yaklaşımlar programlamaya da uygulanabilir; ancak hiç öğrenmedim.

Bu, pratikte benim yaklaşımımın sorunu çözmek için nasıl olduğunu tahmin etmeye çalışmak . O zamanlar, bir listeden elemanların permütasyonlarını oluşturma zorluğu bana verilirse, girdi olarak boş bir liste ile başlamazdım, bunun yerine [4, 9, 2] Gibi açıklayıcı bir örnekle nedenini anlamaya çalışırdım. Altı olası permütasyon var ve bunları kod yoluyla nasıl oluşturabilirim? Oradan, sorunu çözmek için olası bir yol bulmak için çok fazla düşünmeye ihtiyacım var. Bu aslında orijinal soru yazarının yaptığı ve random kullanarak sona erdi. Benzer şekilde, ben bir öğrenciyken, yaşımdaki hiçbir öğrenci [] İle başlamazdı: hepsi derhal iki veya üç unsurlu davaya koşar ve sonra yarım saat boyunca sıkışır, bazen de derlenmeyen veya çalışmayan kod.

TDD yaklaşımı benim için karşı sezgisel görünüyor. Yani, çok iyi çalışıyor, ama TDD ile ilgili birkaç makaleyi okumadan önce, kendimi asla çözemezdim, (1) en basit durumla başlamam, (2) kod yazmadan önce testi yazmam ve (3 ) asla Rush, kodda birkaç senaryoyu yerine getirmeye çalışıyorum. Yeni başlayan programcıların nasıl düşündüğüne baktığımda, bunun sezgisel olduğunu düşünen tek kişi olmadığımı düşünüyorum. İşlevsel bir dili iyi bilen programcılar için daha sezgisel olabilir. Örneğin Haskell'de permütasyon problemini önce boş bir liste, sonra bir elemanlı bir liste ve daha sonra birden fazla elemanlı bir liste halinde ele almak doğal olacaktır. Yinelemeli algoritmaların mümkün olduğu, ancak Haskell'deki kadar doğal olmadığı dillerde, bu tür bir yaklaşım elbette TDD uygulamadığı sürece çok daha az doğaldır.

123
Arseni Mourzenko

Yerel bir topluluk kolejinde yarı zamanlı programlama öğretmeniyim.

Bu kolejde öğretilen ilk ders Java Programlama ve Algoritmalar. Bu, temel döngüler ve koşullarla başlayan ve kalıtım, polimorfizm ve koleksiyonlara giriş ile biten bir derstir. Hepsi bir dönemde, daha önce hiç kod satırı yazmayan öğrencilere, çoğu için tamamen egzotik bir etkinlik.

Bir kez müfredat inceleme kuruluna davet edildim. Kurul, üniversitenin CS müfredatında bir takım problemler belirledi:

  1. Çok fazla programlama dili öğretildi.
  2. Yazılım Geliştirme Yaşam Döngüsü hakkında ders yok.
  3. Veritabanı kursu yok.
  4. Kısmen bu okulların "Bilgisayar Bilimi", "Bilgi Teknolojisi" ve "Yazılım Mühendisliği" terimleri için tek tip bir tanım üzerinde anlaşamaması nedeniyle, devlet ve yerel üniversitelere transfer kredilerinde zorluk.

Onlara tavsiyem? Müfredata öğrencilerin tam yığın uygulama yazabilecekleri iki dönemli bir capstone sınıfı ekleyin, bu da gereksinimleri toplamaktan dağıtıma kadar tüm yazılım geliştirme yaşam döngüsünü kapsayacak bir kurstur. Bu onları yerel işverenlerde (çırak düzeyinde) kiralanabilir yapacaktır.

TDD tüm bunlara nerede uyuyor? Dürüst olmak gerekirse bilmiyorum.

Sorunuzda TDD'yi bir "problem çözme cihazı" olarak sunuyorsunuz; TDD'yi çoğunlukla kod tasarımını ve test edilebilirliğini geliştirmenin bir yolu olarak görüyorum. Geçmişte, TDD bir "çözüm bulma mekanizması" olarak sunulmuştu, ancak Bob Martin (TDD'nin ana savunucusu) bile tekniğe önemli miktarda ön bilgi getirmeniz gerektiğini kabul ediyor.

Başka bir deyişle, önce koddaki sorunları nasıl çözeceğinizi bilmeniz gerekir. TDD, yazılım tasarım özelliklerine göre sizi doğru genel yönde sürükler. Bu, onu alt düzey değil, üst düzey bir ders yapar.

135
Robert Harvey

Her şeyden önce, Bilgisayar Bilimi ve Yazılım Mühendisliği . (Ve belki de daha az bir ölçüde Yazılım Mühendisliği ve Programlama veya "Kodlama" arasında.)

CS profesörlerimden birinin söylediği gibi: klavyeye ihtiyacınız varsa CS yapmıyorsunuz.

TDD, bir Yazılım Mühendisliği uygulamasıdır. Bilgisayar Bilimi ile pek bir ilişkisi yok. Dolayısıyla, neden CS öğrencilerinin TDD öğrenmediğini soruyorsanız, bunun nedeni TDD'nin CS ile gerçekten fazla ilgisi olmamasıdır.

Şimdi, Yazılım Mühendisliği, bu tamamen farklı bir balık su ısıtıcısı. TDD'nin orada öğretilmesi gerektiğine çok katılıyorum. bir Yazılım Mühendisliği dersim vardı (bir dönem için haftada 90 dakika) ve bu derste Şelale, V Modeli, RUP, CMM, CASE öğrendik , RAD, Spiral, Yinelemeli ve muhtemelen unuttuğum başka şeyler. Şüphesiz, özellikle derslerin geri kalanıyla entegre ederseniz ve TDD'yi programlama gerektiren tüm derslerde tüm ödevlere ve sınıf çalışmasına uygularsanız, TDD'de sıkmak için yer olurdu.

Adil olmak gerekirse, benim durumumda, Agile Manifesto henüz yazılmamıştı ve TDD belirsiz bir niş tekniğiydi.

Programlama öğretimi için kişisel favorime bir göz atarsanız, Programları Nasıl Tasarlanırsınız , çok öğrettiklerini göreceksiniz bu işlevlerin başlarında kullanım örnekleri ile birlikte gelmelidir ve sadece biraz sonra, kitap otomatik birim testi ve bu kullanım örneklerinin test şeklinde yazılması gerektiğini önermektedir. Ayrıca kullanım örnekleri ve "amaç deyimleri" dediklerini (JavaDoc yorumunun özet satırı olarak düşünebilirsiniz) koddan önce yazılması gerektiğini de öğretirler.

TDD'yi açıkça öğretmiyorlar (kendi metodolojileri var), ama bu en azından biraz yakın. HtDP, lise öğrencilerinin bir yıldan az bir sürede öğretilmesi için tasarlanmıştır, bu yüzden üniversitede tek bir dönemde öğretmenin mümkün olduğunu düşünüyorum.

Dürüst olmak gerekirse, öğrencilerin büyük bir kazanımı zaten farklı girdilerle yazdıkları kodu çalıştırabilecekleri öğretilirdi. (Başka bir deyişle, kaba bir manuel test şekli.) Öğrencilerin bu zihinsel adımı ne sıklıkta alamadıklarına şaşırıyorum.

Örneğin, Yığın Taşması üzerinde esasen "bu kodun çalışması için hangi yöntemi kullanmam gerekiyor?" Bu yöntemin kodu hakkında olmadığını (asker yöntemin nasıl uygulanacağını biliyordu), sadece adı . Ancak, soru soranlardan biri sadece kodu çalıştırma ve NoMethodError her zaman yükseltilecek istisna.

97
Jörg W Mittag

TDD, "gerçek dünya" programlamasında güzel bir süreçtir, çünkü masalarımızda sık sık sorunlar ortaya çıkmaktadır. "X yapan bir özellik ekleyin", "Y'yi yaparsanız yanlış olan şeyi gösterdiği hatayı düzeltin" vb. TDD, programlamaya başlamadan önce bizi bir spesifikasyon oluşturmaya zorlar.

CS/programlama derslerinde, problemler genellikle bize çok iyi tanımlanmıştır. Msgstr "Bir tamsayı dizisi alan ve aynı tamsayıları azalan sırada düzenlenmiş bir dizi döndüren bir işlev yazın". Spec bize teslim edilir.

TDD'nin neden iyi tanımlanmış bir spesifikasyonla zor bir algoritma problemi yaptığını düşündüğünüzü merak ediyorum. Özellikle, bunu açıklamanızı istiyorum:

Bir listede bulunan elementlerin tüm permütasyonlarını hala TDD kullanmadan hesaplamam istenirse çoğunlukla clueless olurdum. TDD ile öğrenciye cevabı yazarken permütasyon problemini birkaç dakika içinde çözdüm.

Söyleyeceğinizden şüpheliyim çünkü P([]) -> [[]], P([1]) -> [[1]], P([1, 2]) -> [[1, 2], [2, 1]], vb. İddia eden test durumları yazdınız ve özyinelemenin nasıl çalışması gerektiğini görmenize neden oldunuz . Ama bu TDD değil, sadece ... problemi düşünüyor. Başarısız olan gerçek birim testlerini yazma işlemi olmadan sorunu düşünebilirsiniz.

53
MattPutnam

Çoğunlukla otomatik testler yazmak test edilen kodu yazmaktan daha zor olduğundan şüpheleniyorum. Hala temel mekanikle uğraşıyorsanız, başka bir katman eklemek zor. Ayrıca, diğer cevapların da işaret ettiği gibi, uygulayıcıları daha çok didaktik bir cihaz olarak düşünmesine rağmen, TDD bir yazılım mühendisliği süreci olarak algılanmaktadır. Ayrıca, önce hangi testlerin yazılacağını bilmek kendi başına bir beceridir.

Eğer bir giriş dersi öğretiyor olsaydım, TDD düzeninde bazı testler sağlamak olurdu ve öğrencilere bu sırayla birer birer sınavı geçmelerini söylerdim. Bu, programlamayı deneyimli bir danışmanla eşleştirmek için çok benzer bir deneyim. Şahsen, adım adım ilerlemeden dolayı tekniğe harcanan zamanı dengeleyecek algoritmalar gibi sınıfların öğretilmesini kolaylaştıracağını düşünüyorum. Öğrencilere, "İki öğeli bir listenin tüm permütasyonlarını bulabilecek bazı kanıtlanmış çalışma kodlarım var. 3+ öğe için çalışmasını sağlamak için bu kodu mümkün olduğunca tekrar nasıl kullanabilirim?"

33
Karl Bielefeldt

Temel sorun, TDD sürecinde testleri icat etmenin bilgisayar bilimi veya yazılım mühendisliği ile bir ilgisi olmamasıdır. uygulama etki alanı hakkında bilgi gerektirir.

Tabii ki gerçek dünya uygulamalarında TDD'nin gücü budur: inşa ettiğiniz sistemin aslında ne için kullanılacağını düşünmekten kaçamazsınız. Ancak, tipik CS ve SE faaliyetlerinde, öğrenciye verilen görevler minimum bağlama sahiptir ve sadece bazı öğrenme hedeflerini test etmek veya göstermek için vardır.

Örneğin, öğrenme amacı bir programlama dilinde "vaka" yapısının anlaşıldığını göstermekse, TDD önemsizdir: "TD" testlerini hiç kullanmadan tüm TDD testlerini geçen bir yazılım yazabilirsiniz. Örnek yapay olsaydı, "vaka" kullanmamak aslında gerçek dünyadaki soruna daha iyi bir çözüm olabilirdi, ama amaçlanan öğrenme hedefi açısından olmasa da.

Elbette, öğrencileri kendi test senaryolarını icat etmeye ve yürütmeye teşvik edin, ancak resmi bir TDD süreci kullanmaya çalışmak konunun yanındadır.

İkinci bir konu, CE ve SE'nin öğretilme şekliyle daha fazla ilgili olabilir, ancak yine de pratik bir konudur: öğrencinin test koleksiyonunu TDD kullanırken? Bu süreci otomatikleştirmenin açık bir yolu yoktur.

"Aşağıdaki 15 veya 20 durum için test yapmalısınız" yazan bir model çözümü üretseniz bile, yine de öğrencinin testlerinden hangisinin model yanıtınızın her bir kısmına (tamamen veya kısmen) karşılık geldiğini manuel olarak belirlemeniz gerekir. Ve önemsiz durumlar dışında, öğrenci mantıksal olarak model yanıtından farklı bir şekilde yapılandırılmış iyi bir dizi test üretmiş olabilir.

9
alephzero

Ortalama bir öğrenci gerçekten bilmesi ve yapması beklenen şeylere ilişkin kötü bir genel bakışa sahiptir. TDD'yi öğretmek için anlamaları gerekir:

  1. Teknik sorunlar nasıl giderilir. Başlangıçta kodun tek seferde yazıldığını düşünüyorlar. Ancak daha sonra, daha artımlı yazmaya geçtikleri temel hata ayıklama stratejilerini fark ettiklerinde. Onlara bunu önceden söyleseniz bile, yine de bu şekilde yapacaklar çünkü işlerin böyle yapıldığını düşünüyorlar (bu da insanların neden çizmeyi, piyano çalmayı, matematik yapmayı vb. )

  2. Kendi davranışlarınızda tekrarlanabilir kalıplar bulabilmek için kendi eylemlerinizi nasıl içselleştirebilirsiniz? Bunu yaptıktan sonra kendi çalışmanızı otomatikleştirebilirsiniz. Ancak bu, belirli bir seviyeye gelene kadar çoğu insan için tamamen yabancıdır.

  3. Gereksinimler nasıl yazılır.

  4. Sorun alanınızın köşe durumlarını anlama.

  5. Risk yönetiminde mühendislik felsefesini anlama. (ha ama mühendis olduğunuzu bile bilmiyorsunuz)

  6. Kodun yeniden düzenlenmesi ve bakımının kavranması.

  7. Gerçek bir şirkette programlamanın nasıl çalıştığını anlamak.

Aslında TDD'ye çok erken tanıtılan meslektaşlarım oldu, gerçekten bu kadar faydası olmadı. Bununla birlikte, bu etkiye doğru bebek adımları atmak hala mümkündür. Sadece insanların faydalanmak için arkalarında biraz deneyime ihtiyacı var.

Böylece öğretebilirsiniz ama başladığınız bir şey değil. Özellikle TDD'ye çok kolay borç vermeyen bir kod olduğu için.

8
joojaa

TDD üniversitelerde daha popüler değildir, çünkü (genel olarak konuşursak) üniversiteler öğrencilere verilen bilginin gerçek dünya bağlamlarına aktarılabilmesini sağlamada çok zayıf bir iş çıkarmaktadır.

Tartışmalı olarak, bu ilk etapta üniversitenin rolü değildir ve daha çok CS'nin temel kavramlarını ve temel kavramlarını öğretmekle ilgilidir. Bu, öğrencilerin akademide kariyer yapmakla ilgilenecekleri öğretici, önemli ve esastır, ancak öğrencilerin derecelerini bitirip endüstriye kaydolmaları, gelişmeyi takip eden bir ekibe entegre olmaları kısa sürer. en iyi uygulamalar, CI/CD vb.

Açıkçası, kavşaklar vardır ve her ikisi de birbirinden yararlanabilir, ancak nihayetinde üniversite henüz daha yetenekli, ilgili ve güncel yazılım mühendislerini mezun etmek için yapılması gerekenlerle henüz hız kazanmamıştır.

6
Bruno Oliveira

Soruyu doğrudan cevaplamak için:

Birinin önerdiği gibi, bir dönem boyunca yeterli öğrenme var. Ayrı bir kurs mu? Olabilir. TDD'nin yazılım tasarımı konuları ile birleştiğini görebiliyordum. IMO TDD'nin en büyük değeri mevcut davranışları kilitlemektir, böylece daha sonra yeni davranışlar ekleyebilir ve tasarımı bu yeni davranışlar için uygun olacak şekilde değiştirebiliriz. Yani bir yazılım tasarım sınıfı?

TDD'nin arkasındaki düşünme sürecini görmek güzel olurdu (kötü adlandırılmış ve bir keresinde Kent Beck'e tekrar düşünüp düşünmeyeceğini sordum; "trenin istasyondan ayrıldığını" söyledi) mümkün olduğunca erken tanıtıldı. 1976'dan beri kod askısı yapıyorum ve TDD'nin ilk başta çok doğal olmadığını hissettim. Ama şimdi oldukça doğal geliyor. Test kodu yazarak zamanım telafi edilmez, daha sonra yılda sadece bir kez ciddi bir kusuru düzeltmem gerektiğinde telafi edilir (UofM Transplant Center'ın tamamen test odaklı olarak yazılan OTIS2 yazılımı 2004'te son "yazılım acil durumu" na sahipti ).

Taze mezunları bir ay boyunca denemeye teşvik ediyorum. Ancak TDD'ye daha erken maruz kalmaları onlar için çok daha kolay olurdu. Yeni bir dil öğrenirken birim testi çerçevesini kullanmanın yararlı olduğunu düşünüyorum (Gerçek hikaye: "Şimdi bu testi Ruby'de geçmek için nasıl alabilirim? MAYBE işe yarayacak ... HEY IT WORKED!") Veya keşfetme yeni bir kütüphane ("Dokümanlar bunların iade edilme sırası konusunda belirsiz ... Bir test yazacağım ...").

Bir algoritma uygularken TDD'yi değerli buluyorum (bir tane icat ETMİYORUM ... buna ulaşacağım) ya da baştan sona karmaşık bir iş kuralı oluşturduğum gibi. Geçen her test tüm sonsuzluk için "kilitlenir". Test yeterince ayrıksa, değiştirmek zorunda kalmayacaktır (ancak that iyi olmak için bir aydan çok daha uzun sürer).

Bu yüzden TDD'yi önceki programlama sınıflarına dahil etmek ilginç olurdu. Üç iyileştirme noktası:

  1. Çoğu geliştiricinin sadece işlerinin doğası olduğunu düşündüğü hata ayıklama ve düzeltme işlemlerine daha az odaklanabiliriz. Öyle değil. O kadar acı verici veya zaman alıcı olmak zorunda değil.
  2. Birim test çerçeveleri #ifdef DEBUG/printf ("...")/#endif için basit bir alternatiftir - bu nedenle zamanın başından beri benzer (ancak daha riskli) bir şey yapıyoruz.
  3. "Önce testi yazmalısınız" sözünü duyduğumuzda yanıltıcı oluyoruz. Ben istiyorum yazmak üzere olduğum kod için beklentilerimi yazmak için. Bir sonraki davranışa veya tasarımı temizlemeye odaklanırken bunu çalışır durumda bırakmak istiyorum.

Yararlı olabilecek başka bir şey, bir ders kitabı veya en azından TDD uygulamasının çeşitli yönlerini iletmek için tasarlanmış laboratuvarlara sahip yoğun bir saçma müfredattır. Bunun için bir önerim var (daha sonra deneyim/feragatnameye bakınız).

Eleştirmenleri cevaplamak için:

Burada yeniyim, ancak bazı "cevapların" soruyu cevaplamadığını, ancak TDD'nin adil eleştirileri olduğunu not ediyorum. Yani bu endişelerden bazılarını ele almanın bir sakıncası yok mu?

  1. Doğru, TDD ile birim test sonrası (UTA?) Karşılaştırması yapılmış çalışmalar TDD'nin başlangıçta daha yavaş olduğunu göstermektedir. Bununla birlikte, UTA grubunun test kapsamı çok daha düşük ve daha fazla kusuru vardı. Sanırım bu çalışma bu oldu: Endüstride Test Odaklı Bir Geliştirme Uygulamasının Kullanımının Uzunlamasına Çalışması

Birkaç aydan uzun bir süredir bir ürün üzerinde çalışan geliştiriciler gerçekten zamanlarının çoğunu yeni özellikler yazmaya harcıyorlarsa, bu olumsuz olurdu. Ama bir geliştirici olarak üzerinde çalıştığım altı TDD ekibi zamanlarını bu şekilde harcarken, TDD'den önce askı kodunu harcadığım on yıl çoğunlukla hata ayıklayıcıda ya da dikkatli bir şekilde kopyalayıp yapıştırarak/değiştirerek harcadım./başkasının kodu. TDD'nin faydaları anlık değildir, ancak daha düşük geliştirici fazla mesaisi (ve stres) ve artan gelirler = . Alt satır: Her zaman bu TDD ekipleriyle çalışmayı dört gözle bekliyordum. (Bir keresinde çay içirdim.)

  1. TDD'nin yeni bir algoritma icat edemeyeceği de doğrudur. TDD kullanarak bir Sudoku çözücü oluşturmaya çalışan ve kendi Sudoku becerilerinin uygulamaya müdahale etmemesine çalışan Ron Jeffries olduğunu düşünüyorum. O kaybetti. Şaşırmadım. TDD iş kurallarının bozulmasına, basitleştirilmesine ve uygulanmasına yardımcı olur; bir algoritma hakkımız olduğunu doğrulamaya yardımcı olur (örneğin, indirgenemeyebilecek karmaşık bir şifreleme algoritması); yeni özellikleri güvenle ekleyebilmemiz için kodu daha sonra yeniden şekillendirmemize yardımcı olur; ve bunu ürünün davranışlarına yaptığımız yatırımı tespit ederek yapar.

Bir "test" yazdığınızda (aka spesifikasyon, aka senaryo) cevabı bilmek zorundasınız! Ayrıca, çözümü nasıl uygulayacağınıza dair bir fikriniz (ön bilgi) olan çözümden yeterince küçük bir ısırık yazmak istersiniz.

Kod sürprizlerine dikkat edersek ve bu kodla ilgili tüm testler geçtiğinde gerektiğinde yeniden düzenlersek, tasarımın ne kadar açık ve basit olabileceği genellikle şaşırtıcıdır.

Hiç kimse, iyi tasarım kalıpları veya dil deyimleri ya da SOLID ilkeleri ya da Sudoku'nun nasıl oynanacağı ya da nasıl bir öbek sıralaması yapacağımızı bilmemizi önermiyor.

TDD, hızlı bir şekilde yeni özellikler eklememize ve başka hiçbir şey kırmadan bu yeni özelliklere uyacak şekilde tasarımı değiştirmemize güven veren bir güvenlik ağı oluşturmakla ilgilidir.

UTA, biri ölümüne kadar bir delikten düştükten sonra güvenlik ağını yamalı. (İlginç yan not: OTIS2 projesi hayati önem taşıyan bir sistemdir, bu nedenle hasta ölüm riski bizim için bir şaka değildi. Şimdi 10 dakikada 20.000'den fazla test gerçekleştirildi that bir güvenlik aracıdır!)

Deneyim/feragatnameleri:

TDD'yi 1998'den 2004'e kadar neredeyse tam zamanlı ve ~ 6 farklı takımla yaptım. Hepsi en az 6 aylık bir gelişme idi. Ondan önce, 13 yıl boyunca başka bir şekilde yazılım yazarak geçirdim ve printf () ile hata ayıklayıcılardan ve manuel testlerden nefret etmeye geldim.

2001 yılında TDD, BDD ve SA-CSD kurslarını içeren yazılım geliştirme uygulamaları öğretmeye başladım. Tabii, bu iyi bir yaşam, ama aynı zamanda TDD'nin ekip merkezli yazılım geliştirmeyi tekrar akılcı ve eğlenceli hale getirmenin kolay bir yolu olduğunu da biliyorum. Yani...

Bir üniversite veya lise ders kitabı olacağını umuyorum yazıyorum (çevrimiçi depolar, laboratuarlar, videolar vb. İle): Temel Test Odaklı Geliştirme

4
user30938

TDD'yi asla bir sorunu çözmenin bir yolu olarak düşünmedim ve sorunuzu okuduktan sonra hala bilmiyorum.

TDD sizi yalnızca bir soruna bir uçtan bakmaya zorlar: müşterinin sonu. Bu, müşterinin sorusuyla eşleşmeyen bir çözüm bulmanızı önlemeye yardımcı olabilir. Bu genellikle iyi bir şeydir, ancak sizi de sınırlayabilse de, soruna daha geniş bir açıdan bakmanızı engeller, müşterinizin dikkate almadığı soruna daha iyi, daha genel bir çözüm olabilir.

Buna bakmanın bir başka yolu, nihai yukarıdan aşağıya yaklaşım olmasıdır. TDD Yukarıdan Aşağıya Gelişim anlamına gelebilir. Geliştirmeye en ders seviyesinde başlarsınız ve yavaş yavaş yakınlaştırırsınız.

Her iki durumda da soyut bir kavram. Bir öğrenciye bundan bahsedebilir, bir tanım verebilirsin, ama bu olacak. Bir sınavda bu konuda pek çok soru soramazsınız. Bu nedenle, herhangi bir SE veya CS sınıfında, bir SE bağlamında yararlı olsa da, asla bir yan nottan daha fazlası olamaz.

4
Martin Maat

Bana TDD kısaltması icat edilmeden çok önce 1970'lerde bilgisayar bilimi öğretildi ve elbette bize bu tekniği asla açık bir şekilde öğretmedik. Ancak bize verilen programlama egzersizlerinden biri için bir dizi test vakası verildi ve çözümümüzün testleri geçmek zorunda olduğu söylendi. Bu yüzden yaklaşımın değerini hiç açık bir şekilde öğretilmeden öğrendim ve o zamandan beri kullandım.

4
Michael Kay

Testler yazmak yazılım geliştirme için önemli bir beceri olsa da, bilimsel kanıtlar TDD'nin yinelemeli test-son (ITL) geliştirmeden (OTOH) daha iyi bir yazılım ürettiğini göstermez, aynı zamanda kötü ).

Kanıt için Davide Fucci ve ark. "Çok Alanlı Kör Analiz Yaklaşımı Kullanarak Test Odaklı Geliştirmenin Etkileri Üzerine Harici Bir Çoğaltma" ( link ) ve Turhan ve arkadaşlarının Yazılım Yapmadaki meta analizi ( link ).

Dolayısıyla, TDD'nin aslında ölçülebilir kazançlar sağladığına dair kanıt görmeye başlamadığımız sürece, TDD'nin belirli bir uygulama olarak, geliştirme sürecinin bir noktasında test yazma alışkanlığının iyi aşılanmasını aşılamak yerine öğretilmesi daha az önemlidir.

3
Anzel

ancak istenirse TDD'siz bir liste sıralaması algoritması yazmak için biraz zaman harcayacağım ve yine de TDD kullanmadan bir listedeki öğelerin tüm permütasyonlarını hesaplamam istenirse çoğunlukla clueless olurdum. TDD ile permütasyon problemini birkaç dakika içinde çözdüm

Bu beni ciddiye alıyor.
Bana göre test odaklı geliştirme, testleri erken düşünmek ve testleri uygulamak ve bunları kodla güncel tutmak için zaman ayırmak anlamına gelir.
Elbette neyin test edileceğini düşünmek, sorunu çözmek için iyi bir şans ve bazı durumlarda tuzakların ne olduğuna dair iyi bir resim elde etmek.
Ama TDD yapmamak, ilk önce testlere konsantre olmamak altta yatan problem hakkında düşünmeyi yasaklamıyor zaten. Bir adım daha atmak ve şu anda test uygulamak isteyip istemediğinize bakılmaksızın, ne yaptığınızı her zaman düşünmeli ve durumu netleştirmelisiniz.

öğrencilerden liste sıralama algoritmaları ve benzeri şeyler yazmalarını istemeden TDD yaklaşımını açıklamak sorun yaratır mı?

TDD'yi ne ölçüde açıklayacağınıza bağlıdır.
Bir şey duymak yardımcı olur. Ancak öğrenciler henüz yorumlayamadıkları bir çok şey duyarlar çünkü diğer temeller hala eksiktir. Bu nedenle, temel bilgiler olmadan, bilinmeyen terimler için işe yaramaz ve yabancılaştırıcı bir karmaşa olacağı bir kavramın içine girmemelisiniz.
Bunun yanı sıra muhtemelen birçok programcı, bir sorunla ilgili nasıl yapacağınızı arıyorsanız ve gerçekten bir çözüm gösteren örnekler bulursanız ne hissettirdiğini biliyor, ancak her şeyden önce her türlü diğer alakasız şeyi sıralamanız gerekiyor yazar ekledi.

Bu soruyu cevaplamak için, eğer bir öğrenciysem, şeylerin ayrılmasını isterdim. Bize bir listenin nasıl sıralanacağını açıkladığını açıklarsanız, lütfen bunun nasıl yapılacağını bize söyleyin, ancak test malzemelerini doldurma yolunu bırakmayın. Testleri açıklamaya başlamak istiyorsanız, sıralamayı uyguladığınızı duyurmayın, çünkü bu hala uzun bir süre gerçekleşmez.
Sıralamayı ya da testleri yazmaya başlamadan önce tekrar düşünmemiz gerekiyor. Listeler sıralamadan önce ve sonra neye bakar? Örnekler oluşturun, tuzaklar hakkında düşünün, bir liste boşken başarısız olmaktan kaçınmak için nelere dikkat edilmesi gerektiği vb. Tüm bunlar göz önünde bulundurulmalıdır, ancak henüz bir test satırı yazılmamıştır.

Genellikle ayrı tutulması gereken iki şeyi karıştırdığınızı söyleyebilirim.

  • Çözmek istediğiniz sorunun doğasını düşünmek.
  • Kodunuza girdi ve hangi çıktıya verileceği hakkında düşünmek.

Sorunu düşünmek, test senaryoları yazmaya odaklanmaktan çok farklı.

Kötü nasıl yapılır

Bir keresinde, TDD'ye takıntılı biri tarafından bir TDD örneğiyle karşılaştım.
Maalesef yazarın öğreticisine çok düşkün olduğu ortaya çıktı, bu yüzden gerçekte ne olduğunu anlamıyordu.

Yazar sadece kodlarının ele alması gereken sorun üzerinde değil, test senaryoları üzerinde yoğunlaşmıştır. Tüm giriş permütasyonlarını asla bulamayacağınız için, gerçekte ne yaptığınıza dair bir genel bakışa sahip olmanız, sorunun tamamını görmeniz gerekir. Her zaman boş girişle başlayamazsınız, daha sonra biraz daha giriş ekleyebilir ve yeni girişi doğru şekilde işlemek için her zaman kod ekleyebilirsiniz.
Genel olarak neyle uğraştığınıza dair bir fikriniz olmalı. Ama yazar yapmadı.

Bir listeyi sıralamaya çevirmeye çalışırsam, boş bir listeyle başlayacağız, sonra olduğu gibi döndürülebilecek bir öğe, belki de değiştirilmesi gereken ve belki de bir özyineleme ile sonuçlanması gereken iki öğeli bir liste. üç unsur iki gibidir (zaten çözdük) ve bir adım daha ekleyerek ...
Bir sıralama algoritması için korkunç bir szenario- ama kimse bunu gerçekleştirmeyecek çünkü sadece test senaryolarına odaklanıyoruz.

Sonuç

Yorumlar bana biraz daha yazmamı sağlıyor.

Bence "test odaklı geliştirme" terimi yanlış. "Test destekli geliştirme" olmalı, yani sadece kodlama ve umut değil, aynı zamanda test etmeyi de düşünüyoruz ve bir şeyler ters gittiğinde erkenden bilmek her zaman iyidir.

Geliştirme, testlerle yönlendirilirse isimlendirilirse, bu her şeyin sadece testlere bağlı olduğu anlamına gelebilir ve birkaç test vakası tatmin edilir edilmez yapılır. Bu gereklilik, hiçbir zaman bir sorunu bir bütün olarak görmeye çalışmayan, ancak tüm test durumları yanlışlıkla yeşile dönene kadar - sonra gerçek işlemde başarısız olana kadar ileri geri hacklenen çok yetersiz kodla bile karşılanacaktır.

2
puck

Sorunuzu "TDD neden temel bir öğrenme aracı olarak öğretilmiyor?" Şeklinde güncellediniz. Diğer cevaplar zaten TDD'nin 101 kodlaması için neden iyi bir konu olmadığını yeterince iyi açıklıyor, ancak asıl cevap gerçekten de TDD'nin özünde bir problem çözme aracı olmamasıdır. Bu amaç için kullanılabilir, ancak herhangi bir araç gibi, önce ne zaman ve nasıl kullanılacağını anlamanız gerekir.

TDD bir test sürecidir ve bu nedenle en doğal olarak ya bir Geliştirme Süreçleri kursunun parçası olarak ya da bir Yazılım Test kursunun bir parçası olarak öğretilecektir. 101 ders kodlamada amaç öğrencilerin problemleri çözmesi değil, çeşitli programlama kavramlarının nasıl kullanılacağını öğretmektir. Genel olarak, 101 ve 102 kodlu projelerin çoğu, sorunun nasıl çözüleceği konusunda çok açık olacaktır, öğrencilerin görevi kopyala-yapıştır olmayan bir şekilde yapmayı öğrendiklerini anlamaları yeterlidir.

Her öğrenci farklı şekillerde öğrenir. Bazı öğrencilerin bu konuyu okuması gerekir, bazılarının sözlü olarak açıklanması gerekir, bazıları ise boyun kodları derinleşmedikçe asla anlamazlar. TDD'ye öğrenme sürecine yardım etmeyi öğretmek, çoğu öğrenciye ve yardım ettiği öğrencilere yardımcı olmaz mı? Öğretmenler TDD öğretme zamanının ekstra öğrenme hızına değip değmeyeceğine karar vermek zorunda kalacaklar. Net bir bütün olarak, herhangi bir öğrenme yönteminin öğretilmesi, kursa özgü konulara harcanabilecek sınıf zamanına değmez. (Genel olarak, öğrenme ve problem çözme becerileri genellikle kendilerini öğrenmek için öğrencilere bırakılır, çünkü yalnızca öğrenci onlar için en iyi olanı belirleyebilir)

TP: RD; Farklı insanların farklı etkili süreçleri vardır. Üniversiteler nasıl bir şey yapmanız gerektiğini reçete etmez; Size en uygun olanı yapabilmeniz için size sadece araçlar verin.

1
Tezra

TDD harika bir uygulama aracıdır ve bence yararlı olması konusunda haklısınız yazılım yazmak isteyenler için.

TDD'nin ya hiç öğretilmemesinin ya da en azından üniversitelerde geç kalmasının nedeni nedir? Diğer bir deyişle, öğrencilerden liste sıralama algoritmaları ve benzeri şeyler yazmalarını istemeden önce TDD yaklaşımını açıklamak sorun yaratır mı?

Muhtemelen en büyük neden, bu programları öğreten profesörlerin yazılım geliştirme konusunda nadiren bilgi sahibi olmalarıdır, çünkü bu onların uzmanlık alanı değildir. Diğer cevapların da belirttiği gibi, bilgisayar bilimi ve yazılım mühendisliği farklı disiplinlerdir ve bilgisayar bilimi öğrencilerinin yazılım mühendisliğini öğrendikleri beklentisini araba tasarımını öğrenen fizik öğrencileriyle karşılaştırırdım. TDD, gerçekten etkili bir şekilde öğretebilmek için iyi bir uygulama gerektiren bir beceridir ve bilgisayar bilimleri profesörleri kariyerlerinin çoğunu bilgisayar bilimleri üzerinde çalışarak geçirirler, bu nedenle bilgisayar bilimleri fakültesinin TDD'yi gerçekten bir şekilde öğretebilmesini bekler sadece öğrencilerinin kafasını karıştırmayacak bence oldukça gerçekçi değil.

Bilgisayar bilimi ve profesyonel yazılım geliştirme sürecini tamamen ayrı oldukları alanlar olarak ele almamız gerekiyor. Amacınız bilgisayar bilimini öğrenmekse, React) kariyerinin son 30 yılını grafik yaparak geçirmiş birinden yanlış bir şekilde web sitelerini nasıl yapacağınızı öğrenmek için binlerce dolar ödemekle yükümlü olmamanız gerekir. Aynı şekilde, eğer hedefiniz bir yazılım mühendisi olmak ise, neden matematiğin sadece belirli bir alanı olduğunu öğrenmek için neden 4 yıl ve on binlerce dolar harcamak istediğinizi bilmiyorum. tıpkı bir egzoz manifoldu tasarlayan birinin bir miktar fiziği nasıl anlaması gerektiği gibi, alanda temel bir anlayışa sahip olmak için, ancak egzoz manifoldunu tasarlayan kişinin kuantum mekaniği, özel görelilik, ve işlerini yapmak için elektromanyetizma.

Eğer bir muhasebeci olmak istiyorsanız, muhasebe derecesine sahip olabilirsiniz ve profesörlerinizin hepsi muhtemelen bir noktada CPA olacaktır. Makine mühendisi olmak istiyorsanız, makine mühendisliği diploması alabilirsiniz ve profesörlerinizin hepsi bir noktada lisanslı mühendislerdir. Ancak bir yazılım mühendisi olmak istiyorsanız, yazılım mühendisliğinin herhangi bir derecesi aslında seçmeli bazılarınız sizin için seçilmiş olan bir bilgisayar bilimi derecesi olacaktır ve profesörlerinizin neredeyse hiçbiri profesyonel yazılım geliştiricileri olmayacaktır. Muhasebe derecesi matematik bölümünün bir parçası değildir ve makine mühendisliği derecesi fizik bölümünün bir parçası değildir, ancak yazılım mühendisliği derecesi hemen hemen her zaman bilgisayar bilimleri bölümünün bir parçası olacaktır. Akademi bir bütün olarak bu iki alanı farklı personel tarafından yönetilen farklı bölümlere tamamen ayırıncaya kadar, TDD gibi yazılım mühendisleri olmak isteyen öğrencilere öğretilmeyen şeylerin her zaman uzun bir listesi olacağını düşünüyorum.

1
Dogs