Ünite testleri yazmadan önce kod yazmanın dezavantajları nelerdir?


33

Her zaman önce birim testlerini yazmamız ve sonra da kod yazmaya başlamamız önerisini gördüm. Ancak, diğer yöne gitmenin çok daha rahat olduğunu düşünüyorum (benim için) - kod yazıp sonra birim testleri, çünkü gerçek kodu yazdıktan sonra çok daha fazla netliğe sahip olduğumuzu hissediyorum. Kodu ve ardından testleri yazarsam, test edilebilir bir tasarım oluşturmaya yoğunlaşsam bile, test edilebilir hale getirmek için kodumu biraz değiştirmek zorunda kalabilirim. Öte yandan, testleri ve ardından kodu yazarsam, testler kodun biçimlendirilmesinde olduğu gibi ve oldukça sık değişecektir.

Test yazmaya başlamak ve daha sonra kodlamaya geçmek için bir çok öneri gördüğümde, başka bir şekilde yaparsam, dezavantajları nelerdir - kod yaz ve sonra birim testleri?


7
Belirli bir uygulamanın neden benimsemeden önce "en iyi uygulama" olduğunu sorduğun için +1
TaylorOtwell

Yanıtlar:


37

Cevap kırmızı. Kırmızı, TDD'nin elde edemediğiniz kırmızı-yeşil-refactor döngüsünden elde edeceğiniz şeydir, test niteliğindedir. İlk önce başarısız bir test yazın. Başarısız olduğunu izle. Bu senin kırmızı ve önemli. Ben bu gereksinimi var ve: Diyor biliyorum benim kod bunu tatmin edici değil. Dolayısıyla, 2. adıma (yeşil) gittiğinizde, kesin olarak, kodunuzun şimdi bu gereksinimi karşıladığını kesin olarak bilirsiniz. Gereksinimi karşılayacak şekilde kod tabanınızı değiştirdiğinizi biliyorsunuz.

Koddan sonra geliştirilen gereksinimler (testler), koda dayalı olarak, sizi bu tür bir kesinlikten, bu güvenden mahrum eder.


+1 - mükemmel nokta ve alınan nokta! Fikrin için teşekkürler!
k25

7
Testler! = Gereksinimler. Hem testler hem de kod gereksinimlerden türetilmelidir .
Bart van Ingen Schenau

2
@Bart van Ingen Schenau: TDD'nin gücü tam olarak ARE gerekliliklerini test ediyor. Ayrıca, çalıştırılabilir gereksinimlerdir.
mouviciel

1
@Bart: Birim testleri, (yüksek seviye) müşteri talepleri için genellikle çok ayrıntılıdır, ancak fikir kesinlikle, özellikle de bir zamanlar yazılı olarak kesin şartlar olması gereken otomatik kabul testleri gibi daha yüksek seviye testleri de göz önüne alırsak, geçerlidir. Bu "çevik kabul testi" nin özüdür.
Martin Wickman,

3
TDD test ile ilgili değil, şartname ile ilgilidir. TDD yaklaşımında inşa edilen testler, geliştirici ile müşteri arasında hangi ürünün yapılması gerektiği konusunda anlaşmaya varmak için kullanılan bir iletişim aracıdır.
mouviciel

18

Kodu ve ardından testleri yazarsanız, kodun belirtime uyduğundan emin olmak için testleri yazmak yerine kodları geçmesi için testleri yazma tuzağına düşmek çok kolaydır.

Bu, kesinlikle bir şeyler yapmanın tek yolu olmadığını ve yazılım geliştirmenin "en iyi" bir yolunun olmadığını söyledi. Test senaryoları geliştirmek için çok fazla çaba sarfederseniz, önerilen mimarinizin çok daha sonraya kadar kusurları olup olmadığını bilmiyorsunuz; çaba.


Evet, ilk konuda haklısın, ama her zaman bunu yapmadığımdan emin oluyorum. Sınama başarısız olursa, her zaman koda gider ve doğru olduğundan emin olurum ve sonra sınamamın doğru olup olmadığına bakın ve hangisinin yanlış olduğunu değiştirin. Fikriniz için teşekkürler, bunu aklımda tutacağım .. 1. ve son nokta için benden +1 ...
k25

2
Peki ya test geçerse? Test başarılı olabilir, çünkü aslında ilgi kurallarını kullanmaz; Bu gerçekten TDD altında gerçekleşemez, çünkü testin başlangıçta başarısız olması gerekiyor ve yapıyor - eğer yapmazsa, düzeltene kadar 2. adıma geçemezsiniz. Son testte ilk önce testte bulunmayan bir arıza modu var.
Carl Manaster

@ Carl Manaster - Evet, geçerli bir puanınız var. Kodu yazdıktan sonra, gereksinimlerin tam olarak farkındayım ve bu nedenle birim test durumum doğru olurdu (ideal). Test davam geçerse, kodun doğru olduğunu söyleyebilirim, test başarısız olursa, söylediklerimi takip edeceğim. Ancak,% 100 orada geçerli bir noktaya sahip olduğunuzu kabul ediyorum.
k25

@ k25: Mesele şu ki, test durumunuz geçerse, hala kodun doğru olup olmadığını bilmiyorsunuzdur. Test durumu yanlış olabilir.
Anon.

@Anon. - evet haklısınız, bu davayı da hesaba katacağım.
k25

12

Aslında, insanlar TDD'ye takıldıkları için kısaltmadaki diğer iki harfi unuttukları halde testle ilgili. Burada okunabilecek bir şey: T veya TDD'siz TDD Test ile ilgili değildir .

Mesele şu ki, TDD ile sıkıca örülmüş başka şeyler hakkında bir sürü şey öğrendim. İlk önce test yapıp yapmamanız önemli değil: Önemli olan yazılım tasarımı hakkında ne düşünüyor .

Ünite testlerini "doğru şekilde" bile yazabilmek için , yani yalıtılmış, hızlı ve otomatik olduklarından, kodunuzu kolaylaştıracak şekilde nasıl düzenleyeceğinizi yeniden düşünmenin biraz zaman alacağını umarız. test etmek için.

Şahsen kendim de böyle bir şey olduğunu bilmeden SOLID ilkelerini öğrendim . Bunun nedeni, birim testleri yazmamın beni sınıfları yeniden yazmaya zorlamasıdır, böylece test etmek için aşırı karmaşık hale gelmezler. Bu gibi şeylere yol açtı:

  • Ayrı sınıflara ayırmak için, bunları ayrı ayrı test edebilmek için, mantıklı gelmeyen veya özel yöntemlerde bulunan işlevselliği taşımak zorunda kaldım. Tek Sorumluluk İlkesi.
  • Büyük kalıtım yapılarından kaçınmalı ve bunun yerine kompozisyonla uygulamaları genişletmeliydim (Açık-Kapalı prensibinde belirgin).
  • Miras konusunda akıllı olmalıydım, paylaşılabilecek ortak kod gördüğümde soyut sınıflar kullandım ve taslak yöntemleri kullandım (Liskov Değiştirme İlkesi).
  • Arabirimleri ve soyut sınıfları yazmak zorunda kaldım, böylece sınıfları ayrı ayrı test edebilecektim. Bu da istemeden sahte nesneler yazmaya yol açar. (Arayüz Ayrıştırma ilkesi)
  • Çok fazla arayüz ve soyut sınıf yazdığım için ortak türü (Bağımlılık inversiyon ilkesi) kullanmak için değişkenler ve parametreler bildirmeye başladım.

Her zaman ilk önce test yapmasam da, test etmeyi biraz daha kolaylaştırmak için takip etmeye başladığınız iyi OO prensiplerini ve uygulamalarını takip ediyorum. Şimdi kendi iyiliği için kod yazmıyorum. Kod yazdım, böylece kolayca test edilebilir veya daha da önemlisi; Kolayca bakımı yapılabilir .


1
SOLID için +1, yazılım tasarımını düşündüğünüz zaman doğal olarak sizin için oluşur.
ocodo

+1 (aslında +10 vermek istedim ama yapamam). Aynen düşüncelerim - puan listeniz son derece iyiydi. Bu soruyu sormamın bir nedeni bu. Kodu yazdıktan sonra ünite testleri yazmaya başladığımda sınıfların çok daha fazla olduğunu hissettim. Ancak her iki tarafın avantajlarını / dezavantajlarını görmek istedim, görüşleriniz için teşekkürler!
k25

10

Diğer cevapların hepsi iyi, ama dokunulmamış bir nokta var. Önce testi yazarsanız, testlerin yazılmasını sağlar. Çalışma kodunu yazdığınızda, testleri geçip UI üzerinden onaylamanız çok caziptir. Kod yazmadan önce her zaman başarısız bir test yapmak için disipline sahipseniz, bu tuzağı önleyebilirsiniz.


4

Önce testlerinizi yazarsanız, tasarımınız hakkında düşünmek için bir şans daha verir, bu tasarım "taş dökülmeden" önce.

Örneğin, belirli bir parametre setini alan bir yönteme ihtiyacınız olduğunu düşünebilirsiniz. Önce kodu yazarsanız, bu şekilde yazar ve testi belirtilen parametrelere uygun hale getirirsiniz. Fakat önce testi yazarsanız, "bir dakika bekleyin, bu parametreyi ana hat kodunda kullanmak istemem, belki de API'yi değiştirmeliyim" diye düşünebilirsiniz.


İlk puan için +1. Ancak, parametreler seviyesine gelmeden, tasarım başkaları ile tartışılıp kabul edilirse ne olur?
k25

@ k25 - Bir şey tasarlandığı gibi kullanımı zorsa, daha fazla düşünmesi gerekir. Bazen - çok nadiren - bu sadece zor bir iştir. Ancak daha sık olarak, daha basit görevlere indirgenebilir. Bir bağlantım yok ama ya Gosling ya da Goetz birkaç yıl önce API tasarımı hakkında Googling'e röportaj yaptı.
Anon

emin, işaretçiler için teşekkürler, kesinlikle onlara bakacağım ...
k25

2

Test yazmaya başlamak ve daha sonra kodlamaya geçmek için pek çok öneri gördüğümde,

Bunun için gerçekten iyi bir sebep var.

"Doğru hissettiren şeyi yap" derseniz, insanlar en aptal ve çılgınca şeyleri yaparlar.

"Önce testler yaz" derseniz, insanlar en azından doğru şeyi yapmaya çalışabilir.

Diğer şekilde yaparsam dezavantajları nelerdir - kod yazıp sonra birim testleri?

Genellikle, berbat bir test ve test edilebilir olması için elden geçirilmesi gereken bir tasarım.

Ancak, bu sadece bir "genellikle". Bazı insanlar tasarımları ve testleri paralel olarak geliştirir. Bazı insanlar test edilebilir kodu uygular ve tekrar çalışmadan testler yazar.

“Önce Test Et” kuralı, hiçbir ipucu olmayan insanlara öğretmek ve talimat vermek için özel olarak var.

Benzer bir şekilde, caddeyi geçmeden önce her zaman "iki tarafa da" bakmamız söylenir. Ancak, biz aslında değil. Ve önemli değil. Sağdan direksiyonlu bir ülkede yaşıyorum ve sadece geçmeye başladığımda sola bakmam gerekiyor.

Soldan direksiyonlu bir ülkeyi ziyaret ettiğimde, sola bakmak sadece beni öldürebilirdi.

Kurallar bir sebepten dolayı çok kuvvetli bir şekilde belirtilmiştir.

Yaptığın şey kendi sorunun.


2

İlk olarak testi yazmanın amacı, sizi düşündüren şeydir.

  • kod nasıl test edilir
  • kodun test edilebilir olması için sunulması gereken arayüz

Eğer basit bir şey yapıyorsanız, muhtemelen hangisini ilk yazdığınız önemli değildir (ilk test alışkanlığını geliştirmek iyi olsa da) çünkü test basit olacaktır ve arayüz açık olacaktır.

ancak TDD sadece birim testlerine değil, kabul testlerine de giriyor ve sonra arayüz önemsiz hale geliyor.


1

Öncelikle testlerinizi yazmazsanız Test Driven Development (TDD) yapmazsınız. Avantajları çoktur ve çoğu kez uygulayana kadar inanması zordur. TDD yaparken geleneksel gelişim üzerine aldığım faydalar:

  1. Testlerin güvenlik ağı - bilmeden bir şeyi kırma korkusu olmadan büyük değişiklikler yapmanızı sağlar
  2. Organik tasarım - en sonunda elde ettiğim tasarım genellikle çizdiğim tasarımdan farklıdır ve her zaman daha iyi olmuştur.
  3. Verimlilik - küçük hedeflere doğru çalışmak (bu testten geçmek) ve (tüm testlerden geçmek) benim için gerçekten iyi çalışıyor ve beni motive ediyor. Bir çift ekleyin, üretkenliğim yeni seviyelere ulaştı.

Kitaplar: Beck, K. Örnekleme ile Test Odaklı Gelişme

İyi bir örnek: http://jamesshore.com/Blog/Lets-Play/


+1 - güzel noktalar (özellikle 1.) ve bağlantılar için teşekkürler!
k25 14:11

0

Bir test yazdığınızda, bir başarısızlık durumu tespit edeceğini nereden biliyorsunuz? Cevap "testi test et" dir. Bunu nasıl yapacağınız ilk önce testi yazmak, başarısız olduğunu görmek ve yalnızca test edilen ünite başarıyla kodlandığında (diğer cevaplardan birinde belirtilen kırmızı / yeşil / refaktör döngüsü) geçtiğini görmek.

Önce kodu, sonra da testi yazarken, testin dürüst bir başarısızlık gösterip göstermeyeceği sorusu açılır.

Testlerinizin özellikleri açıkladığını unutmayın. Kodunuz "biçimlendirilirken" testlerinizi revize etmeniz gerekiyorsa, özelliklerin değişmekte olduğunu gösterir. Bu iyi bir şey olabilir veya olmayabilir. Sorunu anlamanızın başlangıçta doğru olmadığı anlamına gelebilir. Öte yandan, birimin işini yapmak zorunda olduğu şey yerine işini "nasıl" yaptığını test ettiğiniz anlamına gelebilir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.