TDD açısından bakıldığında, sahte yerine canlı bir son noktaya karşı test yaparsam kötü bir insan mıyım?


16

TDD'yi dini olarak takip ediyorum. Projelerim tipik olarak% 85 veya daha iyi test kapsamına sahip ve anlamlı test senaryoları var.

HBase ile çok çalışıyorum ve ana müşteri arayüzü HTable, alay etmek için gerçek bir acı. Birim testlerimi yazmak, canlı uç nokta kullanan testler yazmaktan 3 veya 4 kat daha uzun sürüyor.

Felsefi olarak, sahte kullanan testlerin canlı uç nokta kullanan testlere göre öncelikli olması gerektiğini biliyorum. Ancak HTable ile alay etmek ciddi bir acıdır ve canlı bir HBase örneğine karşı test etmekten daha fazla avantaj sunduğundan emin değilim.

Ekibimdeki herkes iş istasyonunda tek düğümlü bir HBase örneği çalıştırıyor ve Jenkins kutularımızda çalışan tek düğümlü HBase örneklerine sahibiz, bu nedenle bu bir kullanılabilirlik sorunu değil. Canlı uç nokta testlerinin çalışması, alay kullanan testlerden daha uzun sürer, ancak bunu gerçekten umursamıyoruz.

Şu anda, tüm sınıflarım için canlı son nokta testleri ve sahte tabanlı testler yazıyorum. Alaycılardan kurtulmak isterdim, ancak sonuç olarak kalitenin düşmesini istemiyorum.

Hepiniz ne düşünüyorsunuz?


8
Canlı uç nokta gerçekten bir birim test değil, değil mi? Bu bir entegrasyon testidir. Ama sonuçta bu muhtemelen bir pragmatizm sorunudur; alay yazma zamanını harcayabilir veya özellikleri yazma veya hataları düzeltme için zaman harcayabilirsiniz.
Robert Harvey

4
Kendi kodlarına karşı bir birim test yaparak 3. parti hizmetlerini indiren insanların hikayelerini duydum ... bu canlı bir uç noktaya bağlandı. Hız sınırlaması, birim testlerin genellikle yaptığı veya önemsediği bir şey değildir.

14
Sen kötü biri değilsin. Kötü bir şey yapan iyi bir insansın.
Kyralessa

15
TDD'yi dini olarak takip ediyorum Belki sorun budur? Bu metodolojinin hiçbirinin bunu ciddiye alması gerektiğini düşünmüyorum . ;)
FrustratedWithFormsDesigner

9
TDD'yi dini olarak takip etmek,% 15 ortaya çıkarılan kodu atmanız anlamına gelir.
mouviciel

Yanıtlar:


23
  • İlk tavsiyem sahip olmadığınız tiplerle alay etmemek . HTable'ın alay etmek için gerçek bir acı olduğunu söylediniz - belki de bunun yerine ihtiyacınız olan HTable özelliklerinin% 20'sini ortaya çıkaran bir Adaptöre sarmanız ve gerektiğinde sargıyı alay etmelisiniz.

  • Bununla birlikte, hepinizin sahip olduğunuz türlerden bahsettiğimizi varsayalım. Sahte tabanlı testleriniz, her şeyin yolunda gittiği mutlu yol senaryolarına odaklanıyorsa, entegrasyon testleriniz muhtemelen aynı yolları zaten test ettiği için onları yok eden hiçbir şeyi kaybetmezsiniz.

    Bununla birlikte, test edilen sisteminizin, konuştuğu gerçek somut nesneye bakılmaksızın, işbirlikçisinin sözleşmesinde tanımlanan her küçük şeye nasıl tepki vermesi gerektiğini düşünmeye başladığınızda, izole edilmiş testler ilginç hale gelir. Bu, bazılarının temel doğruluk dediği şeyin bir parçası . Bu küçük vakaların birçoğu ve bunların daha fazla kombinasyonu olabilir. İzole testler hızlı ve yönetilebilir kalırken entegrasyon testleri berbat olmaya başlar.

    Daha somut olmak için, HTable bağdaştırıcınızın yöntemlerinden biri boş bir liste döndürürse ne olur? Boş döndürürse ne olur? Bir bağlantı istisnası atarsa ​​ne olur? Bu edilmelidir Adaptçrünün sözleşmede tanımlanan Bunların hiçbirisini olabilirdi eğer, ve tüketicilerin herhangi edilmelidir bu durumlarla başa çıkmak için hazırlanan , onlar için testler için dolayısıyla ihtiyaç.

Özetlersek: entegrasyon testlerinizle aynı şeyleri test ettiyse , sahte tabanlı testlerinizi kaldırarak hiçbir kalite düşüşü görmezsiniz . Bununla birlikte, ek izole testler (ve sözleşme testleri ) hayal etmeye çalışmak , entegrasyon testleri ile düşünülmesi zor ve / veya yavaş test edilmesi gereken kusurlarla başa çıkarak arayüzlerinizi / sözleşmelerinizi kapsamlı bir şekilde düşünmenize ve kaliteyi artırmanıza yardımcı olabilir.


+1 Alay testleri ile uç durumlar oluşturmayı veritabanını bu durumlarla doldurmaktan çok daha kolay buluyorum.
Rob

Cevabınızın çoğuna katılıyorum. Ancak, Adaptör kısmını kabul ettiğimden emin değilim. HTable, sahte bir acıdır çünkü oldukça çıplak metaldir. Örneğin, toplu alma işlemi yapmak istiyorsanız, bir grup Get nesnesi oluşturmanız, bunları bir listeye koymanız ve HTable.batch () öğesini çağırmanız gerekir. Alaycı bir bakış açısından, bu ciddi bir acıdır, çünkü HTable.batch () öğesine ilettiğiniz get nesnelerinin listesini inceleyen ve ardından bu get () nesneleri listesi için doğru sonuçları döndüren özel bir Matcher oluşturmanız gerekir. Ciddi bir ağrı.
sangfroid

Sanırım HTable için tüm bu kat hizmetleriyle ilgilenen güzel, dostça bir sarmalayıcı sınıf oluşturabilirdim, ama bu noktada ... HTable etrafında bir çerçeve inşa ediyor gibi hissediyorum ve bu gerçekten benim işim olmalı mı? Genellikle "Bir çerçeve oluşturalım!" yanlış yöne gittiğimin bir işaretidir. HBase'i daha kolay hale getirmek için günler dersler yazarak geçirebilirim ve bunun zamanımın büyük bir kullanımı olup olmadığını bilmiyorum. Artı, o zaman sadece düz eski HTable nesnesi yerine bir arayüz veya sarıcı etrafında paasing ve bu kesinlikle benim kod daha karmaşık hale getirecek.
sangfroid

Ama ana noktanıza katılıyorum, birinin sahip olmadığı sınıflar için alay yazmaması gerekiyor. Ve kesinlikle bir uyum testi ile aynı şeyi test eden bir sahte test yazmanın bir anlamı olmadığını kabul edin. Alaylar, arayüzleri / sözleşmeleri test etmek için en iyisi gibi görünüyor. Tavsiye için teşekkürler - bu bana çok yardımcı oldu!
sangfroid

HTable'ın gerçekten ne yaptığını ve nasıl kullandığınızı bilmiyorum, bu yüzden sarmalayıcı örneğimi mektuba almayın. Sarmak için bir şey nispeten küçük olduğunu düşündüm çünkü bir sarıcı / adaptör bahsetmişti. HTable'a birebir bir kopyasını tanıtmak zorunda değilsiniz, ki bu elbette bütün bir çerçeve değil, bir acı olacaktır - ancak bir dikişe , uygulamanızın alanı ile HTable'ınki arasında bir arayüze ihtiyacınız var . HTable'ın bazı işlevlerini uygulamanızın kendi terimlerine yeniden yazmalıdır. Depo deseni, veri erişimi söz konusu olduğunda böyle bir dikişin mükemmel bir enkarnasyonudur.
guillaume31

11

felsefi olarak, sahte kullanan testler, canlı uç nokta kullanan testlere göre öncelikli olmalıdır

Ben bir nokta olduğunu, en azından düşünüyorum akım devam eden tartışmalar TDD savunucuları arasında.

Benim kişisel görüşüm, alay temelli bir testin çoğunlukla bir arayüz sözleşmesi biçimini temsil etmenin bir yolu olduğunu söylemek dışındadır ; ideal olarak sadece arayüzü değiştirirseniz kırılır (yani başarısız olur) . Ve böyle, Java gibi makul derecede güçlü bir dilde yazılmış ve açıkça tanımlanmış bir arayüz kullanırken, neredeyse tamamen gereksizdir: derleyici arayüzü değiştirip değiştirmediğinizi size söylemiş olacaktır.

Ana istisna, ek açıklamalara veya yansımaya dayanan çok genel bir arayüz kullandığınızda, derleyicinin otomatik olarak polis tarafından kullanılamadığıdır. O zaman bile, alayları kullanarak elle değil, programlı bir şekilde doğrulama yapmanın (eq bir SQL sözdizimi kontrol kütüphanesi) olup olmadığını kontrol etmelisiniz.

Bir 'canlı' yerel veritabanı ile test ederken yaptığınız ikinci durum; htable uygulaması, arayüz sözleşmesini elle yazmayı düşündüğünüzden çok daha kapsamlı bir şekilde onaylar ve uygular.

Ne yazık ki, sahte tabanlı testlerin çok daha yaygın kullanımı testtir:

  • testin yazıldığı tarihte kod ne olursa olsun
  • kodun var olması ve çalıştırılması dışında herhangi bir özelliği hakkında hiçbir garanti vermez
  • bu kodu her değiştirdiğinizde başarısız olur

Bu tür testler elbette görüşte silinmelidir.


1
Bunu yeterince destekleyemem. 100 adet dolgudan daha büyük testlerle 1 adet kapsama sahip olmayı tercih ederim.
Ian

3
Mock tabanlı testler aslında 2 nesne tarafından birlikte konuşmak için kullanılan sözleşmeyi açıklar, ancak Java gibi bir dilin tür sisteminin yapabileceklerinin çok ötesine geçer. Sadece yöntem imzaları ile ilgili değil, aynı zamanda istisnalar kabul edilebilir, hangi sırayla ve kaç kez yöntem çağırılabileceği vb. İçin bağımsız değişkenler veya döndürülen sonuçlar için geçerli değer aralıkları belirtebilirler. bunlardaki değişikliklerdir. Bu anlamda onların gereksiz olduğunu düşünmüyorum. Sahte tabanlı testler hakkında daha fazla bilgi için infoq.com/presentations/integration-tests-scam adresine bakın .
guillaume31

1
... katılıyorum yani arayüz çağrısı etrafında mantığı test etme
Rob

1
Arabirimi statik olarak daha az yazılan şeyler listesine kesinlikle denetlenmeyen özel durumlar, bildirilmemiş önkoşullar ve örtülü durum ekleyebilir ve bu nedenle basit derleme yerine sahte tabanlı testi haklı çıkarabilir. Sorun, ancak, bu yönler zaman olacağı yapmak değişikliği, onların şartname örtük ve tüm istemcilerin testler arasında dağıtılır olduğunu. Hangi güncellenmesi muhtemel değildir ve bu yüzden sessizce yeşil bir onay işaretinin arkasındaki bir hatayı saklayarak oturun.
soru

"spesifikasyonları örtük": arayüzleriniz için sözleşme testleri yazarsanız ( blog.thecodewhisperer.com/2011/07/07/contract-tests-an-example ) ve alayları ayarlarken bunlara bağlı kalmazsanız değil .
guillaume31

5

Uç nokta tabanlı bir testin çalıştırılması, sahte bir testten ne kadar sürer? Önemli ölçüde daha uzunsa, evet, birim testlerini daha hızlı hale getirmek için test yazma zamanınızın yatırımına değer - çünkü bunları birçok kez çalıştırmanız gerekir. Uç nokta tabanlı testler "saf" birim testleri olmasa da, birimi test etmek için iyi bir iş yaptıkları sürece, bu konuda dini olmak için hiçbir neden yoktur.


4

Ben guillaume31 yanıtı ile tamamen aynı fikirdeyim, asla sahip olmadığın sahte tipler !.

Normalde testteki bir ağrı (karmaşık bir arayüzle alay etmek) tasarımınızdaki bir sorunu yansıtır. Belki de modeliniz ve veri erişim kodunuz arasında bir soyutlamaya ihtiyacınız var, altıgen bir mimari ve bir depo deseni kullanarak form örneği, bu tür sorunları çözmenin en genel yoludur.

Bir şeyleri kontrol etmek için bir entegrasyon testi yapmak istiyorsanız, bir entegrasyon testi yapın, eğer mantıkınızı test ettiğiniz için bir birim testi yapmak istiyorsanız, bir birim testi yapın ve kalıcılığı izole edin. Ancak bir entegrasyon testi yapmak, çünkü mantığınızı harici bir sistemden nasıl izole edeceğinizi bilmediğinizden (veya bir acısını izole ettiğinizden) büyük bir koku olduğu için, gerçek bir ihtiyaç için değil, tasarımınızdaki bir sınırlama için birim üzerinde entegrasyonu seçersiniz entegrasyonu test etmek.

Ian Cooper'ın şu konuşma formuna bir göz atın: http://vimeo.com/68375232 , altıgen mimarlık ve testten bahsediyor, ne zaman ve ne yapacağı hakkında konuşuyor, gerçek TDD hakkında sizin gibi birçok soruyu çözen gerçekten ilham verici bir konuşma .


1

TL; DR - Gördüğüm yol, testlere ne kadar çaba harcamanıza ve bunun yerine gerçek sisteminize daha fazla harcama yapmanın daha iyi olup olmayacağına bağlıdır.

Uzun versiyon:

Burada bazı iyi yanıtlar var, ancak benim üstlenmüm farklı: test, kendisi için geri ödeme yapması gereken ekonomik bir faaliyettir ve harcadığınız zaman, geliştirme ve sistem güvenilirliğinde (veya çıkmak istediğiniz başka bir şeyde) kötü bir yatırım yapıyor olabilirsiniz; test yazma değil, bina sistemleri işindesiniz. Bu nedenle, test yazma ve sürdürme çabasını azaltmak çok önemlidir.

Örneğin, testlerden kazandığım bazı temel değerler şunlardır:

  • Güvenilirlik (ve dolayısıyla geliştirme hızı): refactor kodu / yeni bir çerçeve entegre etme / bir bileşeni / bağlantı noktasını farklı bir platforma değiştirme, işlerin hala işe yaradığından emin olun
  • Tasarım geri bildirimi: klasik TDD / BDD düşük / orta seviye arayüzlerinizde "kodunuzu kullanın" geribildirimi

Canlı bir uç noktaya karşı testler yine de bunları sağlamalıdır.

Canlı bir uç noktaya karşı test etmenin bazı dezavantajları:

  • Ortam kurulumu - test çalışma ortamını yapılandırmak ve standartlaştırmak daha fazla iştir ve çok farklı ortam kurulumları çok farklı davranışlara neden olabilir
  • Vatansızlık - canlı bir uç noktaya karşı çalışmak, kırılgan ve muhakemesi zor olan mutasyona uğrayan bir son nokta durumuna dayanan yazma testlerini teşvik edebilir (yani bir şey başarısız olduğunda, garip durum nedeniyle başarısız mıdır?)
  • Test çalışma ortamı hassastır - eğer bir test başarısız olursa, test, kod veya canlı uç nokta mıdır?
  • Çalışma hızı - canlı bir uç nokta genellikle daha yavaştır ve bazen paralel hale getirilmesi daha zordur
  • Test için uç durumlar oluşturma - genellikle bir alay ile önemsiz, bazen canlı bir son noktaya sahip bir ağrı (örneğin, kurması zor olanlar taşıma / HTTP hatalarıdır)

Bu durumda olsaydım ve dezavantajlar bir sorun gibi görünmese de , uç noktanın takılması test yazımı önemli ölçüde yavaşlattı, emin olduğum sürece kalp atışında canlı bir uç noktaya karşı test ederdim dezavantajların pratikte bir sorun olmadığını görmek için bir süre sonra tekrar kontrol edin.


1

Test açısından, mutlak bir zorunluluk olan bazı gereksinimler vardır:

  • Test (birim veya başka bir şekilde) hiçbir zaman üretim verilerine dokunmanın bir yolu olmamalıdır
  • Bir testin sonuçları asla başka bir testin sonuçlarını etkilememelidir
  • Her zaman bilinen bir konumdan başlamalısınız

Bu, testlerinizin dışında durumu koruyan herhangi bir kaynağa bağlanırken büyük bir zorluktur. Bu "saf" bir TDD değil, ama Ruby on Rails ekibi bu sorunu sizin amaçlarınıza göre uyarlanabilecek şekilde çözdü. Raylar test çerçevesi şu şekilde çalıştı:

  • Birim testleri çalıştırılırken test yapılandırması otomatik olarak seçildi
  • Veritabanı, birim testleri çalıştırılmaya başlandığında oluşturuldu ve başlatıldı
  • Birim testleri çalıştırıldıktan sonra veritabanı silindi
  • SqlLite kullanılıyorsa, test yapılandırması bir RAM veritabanı kullandı

Tüm bu çalışmalar test kayışına yerleştirildi ve oldukça iyi çalışıyor. Çok daha fazlası var, ancak bu konuşma için temel bilgiler yeterli.

Zaman içinde çalıştığım farklı ekiplerde, kodun test edilmesini teşvik edecek seçimler yapacağız , en doğru yol olmasa bile . İdeal olarak, tüm çağrıları kontrol ettiğimiz kod ile bir veri deposuna sararız. Teorik olarak, eğer bu eski projelerden herhangi biri yeni bir fon elde ederse, geri dönüp dikkatimizi sadece bir avuç sınıfa odaklayarak Hadoop'a bağlı veritabanı olmaktan çıkarabiliriz.

Önemli hususlar, üretim verileriyle uğraşmamak ve test ettiğinizi düşündüğünüzü gerçekten test ettiğinizden emin olmaktır. Harici hizmeti, kodunuzdan bile, talep üzerine bilinen bir taban çizgisine sıfırlayabilmeniz gerçekten önemlidir.

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.