TDD'de “gerçek” kodu ne zaman yazıyorsunuz?

johnny 08/19/2017. 11 answers, 20.464 views
tdd

Eğitim videolarını okuduğum ve gördüğüm tüm örneklerin basit örnekleri var. Ama ben yeşildikten sonra "gerçek" kodu nasıl yaparsam görmüyorum. Bu "Refactor" kısmı mı?

Karmaşık bir yöntemle oldukça karmaşık bir nesneye sahip olursam, ve benim testimi ve bunu yapmak için en azını yazarım (ilk başarısız olduktan sonra, Kırmızı). Ne zaman geri dönüp gerçek kodu yazarım? Ve tekrar test etmeden önce ne kadar gerçek kod yazarım? Sanırım sonuncusu daha sezgidir.

Edit: Yanıtlayan herkese teşekkürler. Bütün cevapların bana çok yardımcı oldu. Ne diye sorduğum veya karıştığım hakkında farklı fikirler var gibi görünüyor ve belki de var, ama sorduğum şey, okul yapmak için bir başvurum olduğunu söyledi.

Tasarımımda, başlamak istediğim bir mimarim var, Kullanıcı Hikayeleri, vb. Buradan Kullanıcı Öykülerini aldım ve Kullanıcı Hikayesini test etmek için bir test yapıyorum. Kullanıcı, İnsanların okula kayıt yaptırıp kayıt ücretlerini ödediklerini söylüyor. Yani, bunu başarısızlığa uğratmanın bir yolunu düşünüyorum. Bunu yaparken, başarısız olan X sınıfı (belki Öğrenci) için bir test Sınıfı tasarlıyorum. Sonra "Öğrenci" sınıfını yaratırım. Belki "Okul" bilmiyorum.

Ancak, her halükarda, TD Design beni hikayeyle düşünmeye zorluyor. Eğer bir test başarısız olursa, bunun neden başarısız olduğunu bilirim, ama bunu yapabilmeyi öneriyorum. Bu tasarımla ilgili.

Bunu Recursion hakkında düşünmeye sevdim. Özyineleme zor bir kavram değildir. Aslında kafanızda takip etmek daha zor olabilir, ama gerçekte en zor kısmı, “duruş” durduğunda, ne zaman duracak (benim fikrim.) Yani ne durduğunu düşünmek zorundayım. önce Özyineleme. Bu sadece kusurlu bir benzeşimdir ve her yinelemeli yinelemenin bir "geçiş" olduğunu varsayar. Yine, sadece bir fikir.

Uygulamada, okul görmek daha zordur. Sayısal ve bankacılık defterleri basit aritmetik kullanabileceğiniz anlamda “kolay” dır. Ben bir + b görebilirim ve 0, vs. döndürürüm. Bir insan sistemi durumunda, bunu nasıl implement daha fazla düşünmeliyim. Başarısızlık, geçme, refakat kavramı (çoğunlukla çalışma ve bu sorudan dolayı) var.

Bilmediğim şey deneyimsizliğe dayanıyor, bence. Yeni bir öğrenciyi nasıl imzalayacağımı bilmiyorum. Soyadı yazarak ve veritabanına kaydedilmekte nasıl başarısız olur bilmiyorum. Basit bir matematik için + 1'i nasıl yapacağımı biliyorum, ancak bir kişi gibi varlıklar ile, sadece bir veritabanında benzersiz bir kimlik alıp almadığımı veya başka bir adla bir kullanıcı adı girdiğinde veritabanı ya da ikisi ya da ikisi de.

Ya da, belki bu hala kafamın karıştığını gösteriyor.

5 Comments
187 hobbs 07/25/2017
TDD'den sonra insanlar gece için eve gidiyorlar.
14 Goyo 07/25/2017
Yazdığın kodun neden gerçek olmadığını düşünüyorsun?
2 johnny 07/26/2017
@RubberDuck Diğer cevaplardan daha fazlasını yaptı. Eminim yakında ona başvuracağım. Hala yabancı bir şey ama ben bundan vazgeçmeyeceğim. Söylediklerin mantıklı. Sadece bağlamımda veya normal bir iş uygulamasında anlam kazanmaya çalışıyorum. Belki bir envanter sistemi veya benzeri. Bunu düşünmeliyim. Zamanın için minnettarım. Teşekkürler.
1 Edmund Reed 07/26/2017
Cevaplar kafasındaki çiviye çarptı, ancak tüm testler geçtikçe ve yeni bir sınamaya / işleve gerek duymuyorsanız, sahip olduğunuz kodun üst üste bindirildiğini varsayabilirsiniz.
3 Borjab 07/26/2017
Soruda "karmaşık bir yönteme sahip oldukça karmaşık bir nesneye sahibim" sorun yaratabilecek bir eğilim söz konusudur. TDD'de ilk önce testlerinizi yazarsınız, böylece oldukça basit bir kodla başlarsınız. Bu, modüler olması gereken test dostu bir yapıyı kodlamaya zorlar. Daha basit nesneleri birleştirerek karmaşık davranışlar yaratılacaktır. Oldukça karmaşık bir nesne veya yöntemle sona ererseniz, o zaman refactor

11 Answers


RubberDuck 07/27/2017.

Karmaşık bir yöntemle oldukça karmaşık bir nesneye sahip olursam, ve benim testimi ve bunu yapmak için en azını yazarım (ilk başarısız olduktan sonra, Kırmızı). Ne zaman geri dönüp gerçek kodu yazarım? Ve tekrar test etmeden önce ne kadar gerçek kod yazarım? Sanırım sonuncusu daha sezgidir.

"Geri dönme" ve "gerçek kod" yazmazsınız. Hepsi gerçek kod. Yaptığınız şey geri dönüp yeni sınama geçişi yapmak için kodunuzu change forces başka bir test eklemektir.

Yeniden test etmeden önce ne kadar kod yazıyorsunuz? Yok. Daha fazla kod yazmanızı forces başarısız bir test yapmadan zero kodu yazarsınız.

Desene dikkat et?

Yardım edeceği ümidiyle (başka) basit bir örnekte yürüyelim.

 Assert.Equal("1", FizzBuzz(1)); 

Kolay peazy.

 public String FizzBuzz(int n) {
    return 1.ToString();
} 

Gerçek kod dediğin şey değil, değil mi? Değişime zorlayan bir test ekleyelim.

 Assert.Equal("2", FizzBuzz(2)); 

if n == 1 gibi aptalca bir şey yapabiliriz, ama aklı başında olan çözümlere geçeceğiz.

 public String FizzBuzz(int n) {
    return n.ToString();
} 

Güzel. Bu, FizzBuzz olmayan tüm sayılar için çalışacaktır. Üretim kodunu değişmeye zorlayacak sonraki giriş nedir?

 Assert.Equal("Fizz", FizzBuzz(3));

public String FizzBuzz(int n) {
    if (n == 3)
        return "Fizz";
    return n.ToString();
} 

Ve yeniden. Henüz geçmeyecek bir test yaz.

 Assert.Equal("Fizz", FizzBuzz(6));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    return n.ToString();
} 

Ve şimdi üçün tüm katlarını ele aldık (beşin katları değil, not edeceğiz ve geri döneceğiz).

Henüz "Buzz" için bir test yazmadık, hadi bunu yazalım.

 Assert.Equal("Buzz", FizzBuzz(5));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n == 5)
        return "Buzz"
    return n.ToString();
} 

Ve yine, ele almamız gereken başka bir olay olduğunu biliyoruz.

 Assert.Equal("Buzz", FizzBuzz(10));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n % 5 == 0)
        return "Buzz"
    return n.ToString();
} 

Ve şimdi, 3'ün katları olmayan 5'in tüm katlarını idare edebiliriz.

Bu noktaya kadar, refakatçi adımı görmezden geliyoruz, ama bir miktar kopya görüyorum. Şimdi bunu temizleyelim.

 private bool isDivisibleBy(int divisor, int input) {
    return (input % divisor == 0);
}

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

Güzel. Şimdi çoğaltmayı kaldırdık ve iyi adlandırılmış bir işlev oluşturduk. Kodu değiştirmemizi zorlayacak bir sonraki test nedir? Neyse, sayının hem 3 hem de 5 tarafından bölünebileceği durumdan kaçındık. Şimdi yazalım.

 Assert.Equal("FizzBuzz", FizzBuzz(15));

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n) && isDivisibleBy(5, n))
        return "FizzBuzz";
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

Testler geçiyor, ancak daha fazla kopyalamamız var. Seçeneklere sahibiz, ancak birkaç kez tekrar edip "Yeniden Yazmak için Yerel Değişkenler" uygulayacağım.

 public String FizzBuzz(int n) {

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

Ve her makul girdiyi ele aldık, ama unreasonable girdilerden ne haber? 0 ya da negatif geçirirsek ne olur? Bu test senaryolarını yaz.

 public String FizzBuzz(int n) {

    if (n < 1)
        throw new InvalidArgException("n must be >= 1);

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

Bu henüz "gerçek kod" gibi görünmeye başlıyor mu? Daha da önemlisi, hangi noktada "gerçek olmayan kod" olmayı ve "gerçek" olmaya geçişi durdurdu? Üzerinde düşünecek bir şey var ...

Böylece, bunu her adımda geçemeyeceğimi bildiğim bir test arayarak yapabildim, ama çok fazla pratik yaptım. İşteyken işler bu kadar basit değildir ve her zaman hangi testin bir değişikliği zorlayacağını bilemeyebilirim. Bazen bir test yazacağım ve zaten geçtiğini görmek için şaşıracağım! Başlamadan önce bir "Test Listesi" oluşturma alışkanlığını kazanmanızı şiddetle tavsiye ederim. Bu test listesi, aklınıza gelebilecek tüm "ilginç" girdileri içermelidir. Hepsini kullanamazsınız ve büyük olasılıkla gittiğinizde vaka ekleyeceksiniz, ancak bu liste bir yol haritası görevi görmektedir. FizzBuzz için test listem böyle bir şeye benziyordu.

  • Negatif
  • Sıfır
  • Bir
  • İki
  • Üç
  • Dört
  • Beş
  • Altı (3 önemsiz olmayan çoklu)
  • Dokuz (3 kare)
  • On (5 olmayan önemsiz çoklu)
  • 15 (3 ve 5 katları)
  • 30 (3 & 5 önemsiz olmayan çoklu)
5 comments
3 maple_shaft♦ 07/27/2017
Yorumlar uzun tartışma için değil; Bu sohbet sohbete taşındı .
40 GManNickG 07/27/2017
Bu cevabı tamamen yanlış anlamadığım sürece: "N == 1 gibi aptalca bir şey yapabiliriz, ama aklı başında olan çözümlere geçeceğiz." - her şey aptalcaydı. Ön tarafını biliyorsanız <spec> yapan bir işlev istersiniz, <spec> için sınamalar yazın ve <spec> hatası veren sürümleri yazdığınız bölümü atlayın. <Spec> 'da bir hata bulursanız emin olun: düzeltmeden önce egzersiz yapabildiğinizi doğrulamak için bir test yapın ve düzeltmeden sonra test geçişlerini gözlemleyin. Ancak tüm bu ara adımları atmaya gerek yok.
15 user3791372 07/28/2017
Bu cevapta ve genel olarak TDD'deki büyük kusurlara işaret eden yorumlar, sohbete taşındı. TDD'yi kullanmayı düşünüyorsanız, lütfen 'sohbeti' okuyun. Maalesef 'kalite' yorumları gelecekteki öğrencilerin okuyabileceği bir sohbet yükü arasında gizli.
nbro 07/28/2017
Bu cevabı iyileştirmek istiyorsanız, bu "test listesinin" içeriği ile ilgili daha kesin olurdum. Açıkça "sınır değerleri" ve "sınıf bölümleme" hakkında konuşacağım.
2 hvd 07/30/2017
@GManNickG Eminim doğru miktarda test yapmak gerektiğine inanıyorum. Testlerin önceden yazılması, hangi özel durumların test edilmesi gerektiğini test etmeyi kolaylaştırır, bu da ya testlerde yeterince kapsanmayan durumlara yol açar, ya da esasen aynı durum testlerde anlamsız bir şekilde kapsanan zamanlardır. Bu ara adımlar olmadan bunu yapabilirsen, harika! Yine de herkes bunu yapamaz, pratik yapan bir şey.

GenericJon 07/24/2017.

"Gerçek" kod, test geçişinizi yapmak için yazdığınız koddur. Really . Bu kadar basit.

İnsanlar testi yeşil yapmak için en azını yazmayı düşündüğünde, bu sadece gerçek kodunuzun YAGNI ilkesine uyması gerektiği anlamına gelir.

Refakatçı adımı fikri, yalnızca gereksinimlerinizi karşıladığından mutlu olduğunuzda yazdıklarınızı temizlemektir.

Yazdığınız testler aslında ürün gereksinimlerinizi kapsadığı sürece, kodları geçtikten sonra kod tamamlanır. Tüm iş gereksinimlerinizin bir testi varsa ve bu testlerin hepsi yeşilse, daha ne yazacak? (Tamam, gerçek hayatta tam test kapsamımız yok, ama teori sağlam.)

5 comments
44 Derek Elkins 07/24/2017
Birim testleri, aslında nispeten önemsiz gereksinimler için bile ürün gereksinimlerinizi kapsamaz. En iyisi, giriş-çıkış alanını örnekliyorlar ve fikir, tam giriş-çıkış boşluğuna doğru (genel olarak) genellemenizdir. Elbette, kodunuz, tüm testlerden geçecek ve diğer girdiler için başarısız olacak her bir birim testi için büyük bir switch olabilir.
8 Taemyr 07/25/2017
@DerekElkins TDD, başarısız testlerini şart koşar. Başarısız birim testleri.
6 jonrsharpe 07/25/2017
@DerekElkins bu yüzden sadece ünite testleri yazmıyorsunuz, ve neden sadece bir şey yapmaya çalıştığınıza dair genel bir varsayım var.
35 Derek Elkins 07/25/2017
@jonrsharpe Bu mantıkla, asla önemsiz uygulamaları yazmam. Örneğin, RubberDuck'un cevabında (sadece birim testleri kullanan) FizzBuzz örneğinde, ilk uygulama açıkça "sadece numaralandırır". Soruyu anlayabilmem, tam olarak bildiğiniz yazı kodu ile bu gereksinimi yerine getireceğine inandığınız kod arasındaki "gerçek kod" arasındaki bu ikiliktir. "Büyük switch ", "testleri yeşil yapmak için çıplak minimum yazmanın" mantıksal bir ucu olarak tasarlandı. OP'nin sorusunu şu şekilde ele alıyorum: TDD'de bu büyük switch önleyen ilke nerede?
2 Luaan 07/25/2017
@GenericJon Bu benim deneyimimde biraz fazla iyimser :) Birincisi, akılsız tekrarlayan işten zevk alan insanlar var. Dev bir anahtar ifadeyle "karmaşık karar verme" ye göre daha mutlu olacaklar. Ve işlerini kaybetmek için, ya onları tekniğin dışına çağıran birine ihtiyaç duyarlar (ve aslında şirket fırsatlarını / paralarını kaybetmekte olduklarına dair daha iyi kanıtlara sahip olurlar) ya da son derece kötü bir şekilde yaparlar. Pek çok projenin bakımını üstlendikten sonra, müşteriyi mutlu edeceği (ve ödeyeceği) sürece çok naif kodun on yıllarca sürmesinin kolay olduğunu söyleyebilirim.

Carl Raymond 07/24/2017.

Kısa cevap, "gerçek kod" testini geçiren koddur. Testinizi gerçek koddan başka bir şeyle geçirirseniz, daha fazla test ekleyin!

TDD hakkında birçok öğreticinin basit olduğunu kabul ediyorum. Bu onlara karşı çalışır. 3 + 8 hesaplamasının gerçekten de 3 + 8 değerini hesaplamak ve sonucu karşılaştırmak için bir seçeneği olmayan çok basit bir test. Bu, sadece kodun çoğunu kopyalayacağınız gibi görünmesini sağlar ve bu testin hatasız, hataya açık ekstra çalışma olduğunu görürsünüz.

Test etmede iyi olduğunuzda, bu, uygulamanızı nasıl yapılandıracağınızı ve kodunuzu nasıl yazdığınızı bildirecektir. Mantıklı, yardımcı testlerle sorun yaşarsanız, muhtemelen tasarımınızı biraz düşünmelisiniz. İyi tasarlanmış bir sistemin testi kolaydır - mantıklı testlerin düşünülmesi ve uygulanması kolaydır.

Önce testlerinizi yazdığınızda, başarısızlıklarını izleyin ve ardından onları geçiren kodu yazın, bu, tüm kodunuzun ilgili testlere sahip olduğundan emin olmak için bir disiplindir. Kod yazarken o kurala uymuyorum; genellikle gerçeklerden sonra testler yazarım. Ancak test yapmak önce dürüst olmanıza yardımcı olur. Bazı deneyimlerle, önce test yazmadığınız zamanlarda bile kendinizi köşeye kodladığınızda fark etmeye başlayacaksınız.

4 comments
6 Steve Jessop 07/26/2017
Şahsen, yazacağım test assertEqual(plus(3,8), 11) değil, assertEqual(plus(3,8), my_test_implementation_of_addition(3,8)) . Daha karmaşık durumlar için, testte doğru sonucu dinamik olarak hesaplamak ve eşitliği kontrol etmek other than , sonucu doğru bir şekilde kanıtlamanın bir yolunu ararsınız.
Steve Jessop 07/26/2017
Yani bu örnek için gerçekten aptalca bir şekilde yaptığınız için, plus(3,8) in 3 sonucunu çıkararak doğru sonuca getirdiğini kanıtlayabilirsin, bundan 8'i çıkarır ve sonucu 0'a karşı kontrol eder. Bu çok açık bir şekilde assertEqual(plus(3,8), 3+8) eşit assertEqual(plus(3,8), 3+8) biraz saçma, ama eğer test edilen kod sadece bir tam sayıdan daha karmaşık bir şey oluşturuyorsa, sonucu almak ve her parçanın doğruluğunu kontrol etmek çoğu zaman doğru yaklaşım. Alternatif olarak, bunun gibi bir şey for (i=0, j=10; i < 10; ++i, ++j) assertEqual(plus(i, 10), j)
Steve Jessop 07/26/2017
... çünkü bu büyük korkuyu önlediğinden, test yazılırken aynı hatayı, canlı kodda yaptığımız "nasıl eklenir?" konusuna da yaparız. Bu nedenle test, herşeye 10 ekleyen herhangi bir kodu yazmayı dikkatli bir şekilde önler, testte plus() şeylere 10 ekleyebilir. Elbette programcı onaylı intial döngü değerlerine de güveniyoruz.
3 Warbo 07/28/2017
Sadece testlerden sonra yazıyor olsanız bile, başarısızlıklarını izlemek için iyi bir fikir olduğunu belirtmek istersiniz; Üzerinde çalıştığınız her şey için çok önemli görünen kodun bir kısmını bulun, biraz düzeltin (örn. a + ile değiştirin, ya da her neyse), testleri çalıştırın ve başarısızlıklarını izleyin, değişikliği geri alın ve onları izleyin. Bunu yaptığım birçok kez test başarısız oldu, işe yaramazsa daha da kötüleşti: sadece bir şey test etmiyor, bir şey test edildiğine dair yanlış bir güven veriyor!

Victor Cejudo 07/25/2017.

Bazen TDD ile ilgili bazı örnekler yanıltıcı olabilir. Diğer insanlar daha önce işaret ettikleri gibi, test yapmak için yazdığınız kod gerçek koddur.

Ama gerçek kodun sihir gibi göründüğünü düşünmeyin, bu yanlış. Neyi başarmak istediğinize dair daha iyi bir anlayışa ihtiyacınız var ve en kolay durumlardan ve köşe durumlarından başlayarak testi uygun şekilde seçmeniz gerekiyor.

Örneğin, bir lexer yazmanız gerekirse, boş bir dizeyle başlarsınız, daha sonra bir demet beyaz boşlukla, sonra bir sayıyla, daha sonra bir boşluk ile çevrili bir sayıyla, sonra yanlış bir sayıyla, vb. Ile başlarsınız. Bu küçük dönüşümler sizi Doğru algoritma, ama en kolay durumdan gerçek kodu yapmak için aptalca seçilen oldukça karmaşık bir duruma atlamıyorsunuz.

Bob Martin burada mükemmel bir şekilde açıklıyor.


CandiedOrange 07/25/2017.

Yorgun olduğunuzda ve eve gitmek istediğinizde refaktör kısmı temizleniyor.

Bir özellik eklemek üzereyken, refaktör bölümü bir sonraki testten önce değiştirdiğiniz şeydir. Yeni özellik için yer açmak için kodu yeniden düzenlersiniz. Bunu, yeni özelliklerin ne olacağını know zaman yaparsınız. Sadece hayal ettiğin zaman değil.

Bu "Merhaba Anne" yazdıracak bir özellik eklemek için bir GreetMom sınıf (bir test ettikten sonra) oluşturmadan önce GreetImpl için GreetWorld olarak yeniden adlandırma kadar basit olabilir.


graeme 07/27/2017.

Ancak gerçek kod TDD aşamasının refactor aşamasında görünecektir. Yani son sürümün parçası olması gereken kod.

Her değişiklik yaptığınızda testler yapılmalıdır.

TDD yaşam döngüsünün sloganı şöyle olurdu: RED GREEN REFACTOR

RED : Testleri yaz

GREEN : Testleri mümkün olduğunca çabuk geçiren işlevsel bir kod elde etmek için dürüst bir girişimde bulunun: çifte kod, belirsiz olarak adlandırılan değişkenler en yüksek mertebeden kesiciler, vs.

REFACTOR : Kodu REFACTOR , değişkenleri doğru şekilde adlandırın. Kodu yükselt .

5 comments
5 mcottle 07/25/2017
"Yeşil" aşama hakkında ne söylediğini biliyorum, ancak testleri geçmek için sert kablo dönüş değerlerinin uygun olabileceğini ima ediyor. Tecrübemde "Yeşil", çalışma şartlarının yerine getirilmesi için dürüst bir girişimde bulunmalı, mükemmel olmayabilir, ancak geliştiricinin bir ilk geçişte yönetebileceği kadar eksiksiz ve "gönderilebilir" olmalıdır. Refactoring, muhtemelen daha fazla geliştirme yaptıktan sonra bir süre sonra yapılabilir ve ilk geçişle ilgili sorunlar daha belirgin hale gelir ve DRY'nin ortaya çıkması için fırsatlar ortaya çıkar.
graeme 07/25/2017
@mcottle Ben de aynı görevin tamamını düşünüyorum. bitir, sonra temizle. Diğer görevlerin bir parçası olarak devam ettikçe daha fazla refakatlar yapılmalıdır.
1 Bryan Boettcher 07/25/2017
@mcottle: Sadece getiri deponunun kaç uygulamasının codebase'de kodlanmış değerler olabileceğine şaşırabilirsiniz. :)
6 Kaz 07/25/2017
Neden kod yazabilirim ve temizlerim, güzel yazabilirim, üretim kalitesi kodu yazabileceğim kadar hızlı mı? :)
1 Kaz 07/27/2017
@TimothyTruckle En basit olası değişikliği bulmak için 50 dakika sürüyorsa, ancak en basit ikinci değişikliği bulmak için sadece 5 tane mi gerekiyor? En basitiyle mi yoksa en basit aramaya devam mı edeceğiz?

Timothy Truckle 07/27/2017.

TDD'de “gerçek” kodu ne zaman yazıyorsunuz?

red faz, kod write yerdir.

refactoring aşamasında birincil amaç kodu delete .

red fazda, test geçişini as quick as possible ve at any cost yapmak için her şeyi yaparsınız. İyi kodlama uygulamalarını veya tasarım desenlerini benzer şekilde duyduğunuz şeyleri tamamen göz ardı edersiniz. Testi yeşil yapmak önemli.

refactoring aşamasında, hazırladığınız pisliği temizliyorsunuz. Şimdi ilk önce yaptığınız değişiklik, Dönüşüm Öncelik listesinde en üstte yer alan türden bir değişiklik olup olmadığına bakarsınız ve herhangi bir kod çoğaltması varsa, büyük olasılıkla bir tasarım şablonu uygulayarak kaldırabilirsiniz.

Son olarak, tanımlayıcıları yeniden adlandırarak ve magic numbers ve / veya değişmez dizeleri sabitlere çıkararak okunabilirliği geliştirirsiniz.


Kırmızı-refactor değil, kırmızı-yeşil-refactor. - Rob Kinyon

Bunu işaret ettiğin için teşekkürler.

Yani real code yazdığınız green aşamadır

red fazda, executable specification yazıyorsunuz ...

2 comments
Rob Kinyon 07/27/2017
Kırmızı-refactor değil, kırmızı-yeşil-refactor. "Kırmızı" test takımını yeşilden (tüm testler geçer) kırmızıya (bir test başarısız) alır. "Yeşil", test takımınızı kırmızıdan (bir test başarısız) yeşile (tüm testler geçer) attığınız yerdir. "Refactor", kodunuzu aldığınız ve tüm testleri geçerken güzel yaptığınız yerdir.
Timothy Truckle 07/27/2017
@RobKinyon Teşekkürler, cevabı güncelledi.

Robert Andrzejuk 07/27/2017.

Tüm zamanlar Real Code yazıyorsun.

Her adımda Kodunuzun gelecekteki arayanları için hangi koşulların yerine getirileceği koşullarını yerine getirmek için kod yazıyorsunuz (bu siz olabilirsiniz ya da olmayabilir ...).

Kullanışlı ( real ) kod yazmadığınızı düşünüyorsunuz, çünkü bir an bunu tekrar gözden geçirebilirsiniz.

Code-Refactoring , harici davranışını değiştirmeden, var olan bilgisayar kodunun yeniden yapılandırılmasıdır.

Bunun anlamı, kodu değiştirseniz bile, kodun yerine getirildiği koşullar değişmeden bırakılır. Ve kontroller ( tests ) Doğrulamak için uyguladınız. Kodunuzda değişiklikleriniz bir şey değişip değişmediğini doğrulamak için zaten var. Yani bütün zaman yazdığınız kod, sadece farklı bir şekilde orada.

Bir başka sebep Bunun gerçek bir kod olmadığını düşünebilirsiniz, çünkü son programın Sizin tarafınızdan halihazırda takip edilebileceği örneklerdir. Bu çok iyi, çünkü programladığınız domain hakkında bilgi sahibi olduğunu gösteriyor.
Ancak çoğu zaman programcılar, kendileri için unknown new bir domain . Nihai sonucun ne olacağını bilmiyorlar ve TDD, bu sistemin nasıl çalışması gerektiği ve kodumuzun bu şekilde çalıştığını doğrulayan knowledge belgeleyen, adım adım program yazacak bir technique .

TDD'deki Kitabı (*) okuduğumda, benim için öne çıkan en önemli özellik: TODO listesiydi. Bana göre, TDD aynı zamanda geliştiricilerin aynı anda tek bir şeye odaklanmalarına yardımcı olan bir tekniktir. Yani bu da sorunuza bir cevaptır. How much Real code to write ? Tek seferde 1 şey üzerinde odaklanmak için yeterli kod söyleyebilirim.

(*) "Tahribatı Geliştirme Denemesi: Örnek", Kent Beck

1 comments
2 Robert Andrzejuk 07/27/2017
"Test Tahrikli Gelişim: Örnek", Kent Beck

Zenilogix 07/31/2017.

Testlerinizi başarısız yapmak için kod yazmıyorsunuz.

Hangi başarının nasıl görüneceğini tanımlamak için testlerinizi yazıyorsunuz. Bu, başlangıçta başarısız olacak kodun henüz yazılmadığı için başarısız oluyor.

Başlangıçta başarısız olan testlerin yazılmasıyla ilgili bütün nokta iki şey yapmaktır:

  1. Tüm durumlarda - tüm nominal kasalar, tüm kenar kasaları vb.
  2. Testlerinizi doğrulayın. Onları sadece geçtiğini görürseniz, bir hata oluştuğunda güvenilir bir şekilde rapor edebileceklerinden nasıl emin olabilirsiniz?

Kırmızı-yeşil-refactor'un ardındaki nokta, doğru testlerin yazılmasının önce testlerin geçmesi için yazdığınız kodun doğru olduğunu bilmenizdir ve testlerinizin sizi en kısa sürede bilgilendireceği güvenini yeniden kazanmanızı sağlar. Bir şey kırılır, bu yüzden hemen geri dönüp düzeltebilirsiniz.

Kendi tecrübemde (C # /. NET), saf test ilk olarak ulaşılamaz bir idealdir, çünkü henüz mevcut olmayan bir yönteme bir çağrı derleyemezsiniz. Yani "önce test et", gerçekten önce arayüzleri kodlama ve uygulamalarını kodlama hakkındadır, daha sonra taslaklar uygun bir şekilde ortaya çıkıncaya kadar (başlangıçta başarısız olacak) taslaklara karşı testler yazmaktadır. Ben asla "başarısız kod" yazmam, sadece taslaklardan yapıyorum.


Zan Lynx 07/27/2017.

Birim testleri ve entegrasyon testleri arasında karışık olabilirsiniz. Kabul testlerinin de olabileceğine inanıyorum, ama bu sizin sürecinize bağlı.

Tüm küçük "birimleri" test ettikten sonra hepsini bir araya getirdiğinizde veya "entegre" olarak test ettiniz. Bu genellikle bir bütün program veya kütüphane.

Entegrasyon testlerini yazdığım kodda, verileri okuyan ve kütüphaneye besleyen çeşitli test programlarına sahip bir kütüphane var, ardından sonuçları kontrol edin. Sonra iş parçacığı ile yapıyorum. Sonra ortada konu ve çatal () ile yapıyorum. Sonra koşarım ve 2 saniye sonra -9'u öldür, sonra onu başlat ve kurtarma modunu kontrol et. Ben fuzz ediyorum. Her türlü yolla işkence ediyorum.

Hepsi de test ediyor, ama sonuçlara göre kırmızı / yeşil bir ekranım yok. Ya başarılı oluyor, ya da nedenini öğrenmek için birkaç bin satırlık hata kodunu kazıyorum.

"Gerçek kodu" test ettiğin yer burası.

Ve bunu düşündüm ama belki de birim testlerini yapmanın ne zaman olduğunu bilmiyorum. Testleriniz, belirttiğiniz her şeyi uyguladığınız zaman, birim testleri yazmanız yeterlidir. Bazen, tüm hata işleme ve kenar durumları arasında bunu izleyemezsiniz, bu nedenle, yalnızca teknik özelliklerle doğrudan doğruya giden güzel bir test grubunu test etmek isteyebilirsiniz.

1 comments
Peter Mortensen 07/27/2017
(onun = sahiplenme, bu = "budur" ya da "vardır". Örneğin bkz. How to Use Its and It's .)

user3791372 07/27/2017.

Sorunun başlığına cevap olarak: “TDD'de“ gerçek ”kodu ne zaman yazıyorsunuz?” Cevabı: 'neredeyse hiç' veya 'çok yavaş'.

Bir öğrenci gibi konuşuyorsun, o yüzden bir öğrenciye tavsiyem gibi cevap vereceğim.

Çok sayıda kodlama 'teori' ve 'teknikleri' öğreneceksiniz. Overpriced öğrenci kurslarına zaman ayırmak için harikalar, ama çok az bir yararı var ki, bir kitapta okuyamayacağın zamanın yarısı kadar.

Bir kodlayıcının işi sadece kod üretmek içindir. Kod gerçekten iyi çalışıyor. Bu nedenle, siz kodlayıcı zihninizde, kağıda, uygun bir uygulamada vb. Kodları siz planlarsınız ve kodlamadan önce mantıksal ve yanal olarak düşünerek olası kusurları / delikleri önceden planlamanız gerekir.

Ancak, iyi bir kod tasarlayabilmek için uygulamanızı nasıl kırılacağını bilmeniz gerekiyor. Örneğin, Little Bobby Table'ı (xkcd 327) bilmiyorsanız, büyük olasılıkla veritabanınızla çalışmaya başlamadan önce girdilerinizi dezenfekte etmeyeceksiniz, böylece verilerinizi bu konsept etrafında güvende tutamazsınız.

TDD, kodunuzu kodunuzdaki hataları en aza indirecek şekilde tasarlamanızı sağlar. Böylece kodlama, uygulamanızı kodlamadan önce neyin ters gidebileceğini test eder, çünkü kodlama sizin girdiğiniz kodların katlanarak artmasını zorlaştırır ve bir kez düşündüğünüz hataları unutursunuz. Uygulamayı bitirdiğini düşündüğünüzde testleri ve patlamayı çalıştırırsanız, umarım hatalar testlerinizle yakalanır.

TDD, bazı insanların inandığı gibi, bir test yazıp, en az kodla geçmesini, başka bir test yapmasını, minimum kodla geçmeyi vb. Yapmasını istemiyor. Bunun yerine, kendinize güvenli bir şekilde kod yazmanın bir yolu. Testler ile çalışmasını sağlamak için sürekli yeniden kodlama kodunun bu ideali aptalcadır, ancak öğrenciler arasında güzel bir kavramdır çünkü yeni bir özellik eklediklerinde kendilerini harika hissettirir ve hala nasıl kodlanacağını öğrenirler ...

Lütfen bu tuzağı düşürmeyin ve ne olduğu için kodlama rolünü görmeyin - bir kodlayıcının işi sadece kod üretiyor. Kod gerçekten iyi çalışıyor. Şimdi, profesyonel bir kodlayıcı olarak saatte olacağınızı unutmayın, ve 100.000 onaylama yazdıysanız, müşteriniz ilgilenmeyecektir. Gerçekten de, aslında.

5 comments
3 johnny 07/25/2017
Bir öğrenciye bile yakın değilim, ama iyi teknikleri uygulamaya ve profesyonel olmaya çalışıyorum. Yani bu anlamda, ben bir "öğrenciyim". Sadece çok basit sorular soruyorum, çünkü ben buyum. Tam olarak neden yaptığımı yaptığımı bilmek istiyorum. Maddenin kalbi. Eğer anlamadım, beğenmiyorum ve soru sormaya başlamıyorum. Neden kullanacağımı bilmeliyim, eğer kullanacaksam. TDD, neyi yaratmanız ve düşünmeniz gerektiğini bilmek gibi bazı yönlerden sezgisel olarak iyi görünüyor, ancak uygulamanın anlaşılması zordu. Sanırım şimdi daha iyi bir kavrayışım var.
4 Sean Burton 07/27/2017
Bunlar TDD'nin kuralları. İstediğiniz kadar kod yazabilirsiniz, ancak bu üç kurala uymuyorsanız TDD yapmıyorsunuz.
2 user3791372 07/27/2017
Bir kişinin "Kuralları"? TDD, bir dine değil, size yardımcı olmak için bir öneridir. Pek çok insanın bu kadar analitik bir fikre bağlı olduğunu görmek çok üzücü. TDD'nin kökenleri bile tartışmalıdır.
2 Alex 07/28/2017
@ user3791372 TDD çok katı ve açıkça tanımlanmış bir süreçtir. Birçok kişi, "Programlama yaparken bazı testler yapın" anlamına gelse bile, öyle değil. Burada terimleri karıştırmaya çalışalım, bu soru genel test değil, süreç TDD'si ile ilgili.

Related questions

Hot questions

Language

Popular Tags