Alıcılarımız ve ayarlayıcılarımız için testler yazmamız mı gerekiyor yoksa aşırıya kaçıyor mu?
Alıcılarımız ve ayarlayıcılarımız için testler yazmamız mı gerekiyor yoksa aşırıya kaçıyor mu?
Yanıtlar:
Hayır derdim.
@% 100 kod kapsamı hedeflemeniz gerektiğini, ancak bence bu tehlikeli bir dikkat dağıtıcı. % 100 kapsama alan birim testleri yazabilir ve yine de hiçbir şeyi test edemezsiniz.
Birim testleri, kodunuzun davranışını anlamlı ve anlamlı bir şekilde test etmek için vardır ve alıcılar / ayarlayıcılar sadece bir amaç için bir araçtır. Testler, "gerçek" işlevselliğini test etme hedeflerine ulaşmak için alıcıları / ayarlayıcıları kullanırsa, bu yeterince iyidir.
Öte yandan, alıcılarınız ve ayarlayıcılarınız sadece alıp ayarlamaktan daha fazlasını yaparsa (yani düzgün bir şekilde karmaşık yöntemlerdir), o zaman evet, test edilmelidir. Ama bir birim test durumda yazmayın sadece zaman kaybı olan bir alıcı ve ayarlayıcılar, test etmek.
Roy Osherove 'Ünite Test Sanatı' adlı ünlü kitabında şöyle diyor:
Özellikler (Java'daki alıcılar / ayarlayıcılar) genellikle herhangi bir mantık içermeyen ve test gerektirmeyen kodlara iyi örneklerdir. Ancak dikkat edin: mülkün içine herhangi bir çek eklediğinizde, mantığın test edildiğinden emin olmak istersiniz.
Not : Bu cevap potansiyel olarak kötü bir tavsiye de olsa oyları almaya devam ediyor. Nedenini anlamak için aşağıdaki küçük kız kardeşine bir göz atın .
Tartışmalı tamam, ama bu soruya 'hayır' yanıtını veren herkesin temel bir TDD kavramının eksik olduğunu iddia ediyorum.
Benim için, TDD'yi takip ederseniz cevap evettir . Eğer değilseniz, hayır mantıklı bir cevap.
TDD'nin genellikle ana faydaları olduğu belirtilir.
Programcılar olarak, nitelikleri önemli bir şey olarak düşünmek ve alıcıları ve belirleyiciyi bir tür genel gider olarak düşünmek çok caziptir.
Ancak öznitelikler bir uygulama ayrıntısıyken, ayarlayıcılar ve alıcılar, programların çalışmasını sağlayan sözleşmeli arabirimdir.
Bir nesnenin hecelemesi gerektiği çok daha önemlidir:
Müşterilerinin durumunu değiştirmesine izin ver
ve
İstemcilerinin durumunu sorgulamasına izin ver
bu durumun gerçekte nasıl depolandığı (bir özniteliğin en yaygın olduğu, ancak tek yol olmadığı).
Gibi bir test
(The Painter class) should store the provided colour
TDD'nin dokümantasyon bölümü için önemlidir .
Nihai uygulamanın önemsiz (öznitelik) olması ve herhangi bir savunma faydası taşımaması, testi yazarken bilinmemelidir.
Sistem geliştirme dünyasında önemli sorunlardan biri olmaması gidiş-dönüş mühendislik 1 - bir sistemin gelişim süreci (dokümantasyon, kod) sıklıkla tutarsız eserler olan kopuk alt süreçlere halinde dağıtılır.
1 Brodie, Michael L. "John Mylopoulos: kavramsal modelleme tohumlarının dikilmesi." Kavramsal Modelleme: Temeller ve Uygulamalar. Springer Berlin Heidelberg, 2009. 1-9.
Öyle dokümantasyon sistemi ve onun kod özellikleri her zaman tutarlı olmasını sağlar TDD parçası.
TDD içinde önce başarısız kabul testini yazıyoruz, ancak daha sonra geçmelerine izin veren kodu yazıyoruz.
Üst düzey BDD içinde önce senaryoları yazıyoruz, sonra geçmelerini sağlıyoruz.
Ayarlayıcıları ve alıcıyı neden hariç tutmalısınız?
Teorik olarak, TDD içinde bir kişinin testi yazması ve diğerinin geçmesini sağlayan kodu uygulaması mükemmeldir.
Kendinize sorun:
Bir sınıf için testleri yazan kişi, alıcılar ve pasörden bahsederse.
Alıcılar ve ayarlayıcılar bir sınıfa açık bir arabirim olduğundan, yanıt açıkça evettir veya bir nesnenin durumunu ayarlamanın veya sorgulamanın bir yolu olmayacaktır. Ancak , bunu yapmanın yolu her yöntemi ayrı ayrı test etmek değildir, daha fazla bilgi için diğer cevabıma bakın.
Açıkçası, önce kodu yazarsanız, cevap o kadar net olmayabilir.
tl; dr: Evet sen should ve birlikte OpenPojo Önemsiz.
Alıcılarınızda ve ayarlayıcılarınızda bazı doğrulamalar yapmalısınız, böylece bunu test etmelisiniz. Örneğin, setMom(Person p)
kendilerinden daha genç kimsenin annesi olarak belirlenmesine izin vermemelidir.
Bunlardan herhangi birini şimdi yapmasanız bile, olasılıklar gelecekte olacaksınız, o zaman bu regresyon analizi için iyi olacaktır. Annelerin ayarlanmasına izin vermek null
istiyorsanız, daha sonra birisinin değişmesi durumunda bunun için bir test yaptırmalısınız, bu varsayımlarınızı güçlendirecektir.
Yaygın bir hata void setFoo( Object foo ){ foo = foo; }
nerede olması gerektiğidir void setFoo( Object foo ){ this.foo = foo; }
. (Birinci durumda foo
yazılan olmasıdır parametre değildirfoo
saha nesne ).
Bir dizi veya koleksiyon döndürüyorsanız, alıcının geri dönmeden önce ayarlayıcıya aktarılan verilerin savunma kopyalarını yapıp yapmayacağını test etmeniz gerekir .
Aksi takdirde, en temel ayarlayıcılara / alıcılara sahipseniz, birim testi, nesne başına en fazla yaklaşık 10 dakika ekleyecektir, yani kayıp nedir? Davranış eklerseniz, zaten bir iskelet testiniz var ve bu regresyon testini ücretsiz olarak alıyorsunuz. Java kullanıyorsanız, OpenPojo olduğu için mazeretin yok . Kodunuzda tutarlı bir şekilde uygulandıklarından emin olmak için tüm projenizi etkinleştirip ardından tarayabileceğiniz mevcut bir kurallar kümesi vardır.
Onların Gönderen örnekler :
final PojoValidator pojoValidator = new PojoValidator();
//create rules
pojoValidator.addRule( new NoPublicFieldsRule () );
pojoValidator.addRule( new NoPrimitivesRule () );
pojoValidator.addRule( new GetterMustExistRule () );
pojoValidator.addRule( new SetterMustExistRule () );
//create testers
pojoValidator.addTester( new DefaultValuesNullTester () );
pojoValidator.addTester( new SetterTester () );
pojoValidator.addTester( new GetterTester () );
//test all the classes
for( PojoClass pojoClass : PojoClassFactory.getPojoClasses( "net.initech.app", new FilterPackageInfo() ) )
pojoValidator.runValidation( pojoClass );
Ayrıntıya girmeme izin ver:
Gönderen eski kod ile etkili çalışma 1 :
Birim testi terimi, yazılım geliştirmede uzun bir geçmişe sahiptir. Birim test kavramlarının çoğu için ortak olan, bunların yazılımın bireysel bileşenlerinin izolasyonunda testler olduğu fikridir. Bileşenler nelerdir? Tanım değişiklik gösterir, ancak birim testinde genellikle bir sistemin en atomik davranış birimleri ile ilgileniriz. Prosedür kodunda, birimler genellikle işlevlerdir. Nesneye yönelik kodda, birimler sınıflardır.
Alıcıları ve ayarlayıcıları bulduğunuz OOP ile, ünitenin sınıf olması gerekir, mutlaka bireysel yöntemler değildir .
Tüm gereksinimler ve testler Hoare mantığı biçimindedir :
{P} C {Q}
Nerede:
{P}
önkoşul ( verilen )C
tetikleme koşulu ( ne zaman ){Q}
son koşul ( o zaman )Sonra maxim geliyor:
Test davranışı, uygulama değil
Bu C
, post-koşula nasıl ulaşıldığını test etmemeniz gerektiği anlamına gelir {Q}
, bunun sonucunu kontrol etmelisiniz C
.
OOP söz konusu olduğunda C
, bir sınıftır. Bu yüzden iç etkileri değil, sadece dış etkileri test etmelisiniz.
Harfler ve ayarlayıcılar bazı mantık içerebilir, ancak bu mantığın dış etkisi yoktur - onları fasulye erişimcileri haline getirir 2 ) bir test nesnenin içine bakmak ve sadece kapsüllemeyi ihlal etmekle kalmaz, aynı zamanda uygulama testi de yapar.
Bu yüzden fasulye çekicilerini ve ayarlayıcılarını ayrı ayrı test etmemelisiniz. Bu kötü:
Describe 'LineItem class'
Describe 'setVAT()'
it 'should store the VAT rate'
lineItem = new LineItem()
lineItem.setVAT( 0.5 )
expect( lineItem.vat ).toBe( 0.5 )
Eğer rağmen setVAT
bir istisna olur şimdi beri karşılık gelen bir testi uygun olur orada bir dış etki.
Eğer böyle bir değişiklik daha sonra ortaya çıksa bile, dışarıdan bir etkisi olmazsa, bir nesnenin iç durumunu değiştirmenin neredeyse hiçbir anlamı yoktur.
Bu nedenle, ayarlayıcılar ve alıcılar için bir test, bu yöntemlerin dahili etkisiyle değil, dış etkisiyle ilgilenmelidir.
Örneğin:
Describe 'LineItem class'
Describe 'getGross()'
it 'should return the net time the VAT'
lineItem = new LineItem()
lineItem.setNet( 100 )
lineItem.setVAT( 0.5 )
expect( lineItem.getGross() ).toBe( 150 )
Kendiniz düşünebilirsiniz:
Bir saniye,
getGross()
burada test etmiyoruzsetVAT()
.
Ama eğer setVAT()
arıza bu testin tamamen başarısız olması durumunda.
1 Tüyler, M., 2004. Eski kodla etkin çalışma. Prentice Hall Profesyonel.
2 Martin, RC, 2009. Temiz kod: çevik yazılım işçiliğinin bir el kitabı. Pearson Eğitim.
Özellikler için haklı nedenler olsa da, Üye devleti Özellikler yoluyla göstermenin kötü tasarım olduğuna dair yaygın bir Nesneye Dayalı Tasarım inancı vardır. Robert Martin'in Açık Kapalı Prensibi ile ilgili makalesi, Özelliklerin birleştirmeyi teşvik ettiğini ve dolayısıyla bir sınıfı modifikasyondan kapatma yeteneğini sınırladığını belirterek genişler - mülkü değiştirirseniz, sınıfın tüm tüketicilerinin de değişmesi gerekecektir. Üye değişkenleri ortaya çıkarmanın mutlaka kötü bir tasarım olmadığını, sadece zayıf bir stil olabileceğini kabul ediyor. Ancak, özellikler salt okunursa, kötüye kullanım ve yan etki olasılığı daha azdır.
Birim testi için sağlayabileceğim en iyi yaklaşım (ve bu tuhaf görünebilir) mümkün olduğunca çok sayıda özelliği korumalı veya dahili yapmaktır. Bu, alıcılar ve ayarlayıcılar için aptalca testler yazmayı önlerken birleşmeyi önleyecektir.
Giriş alanlarına bağlı ViewModel özellikleri gibi okuma / yazma Özelliklerinin kullanılması gereken bariz nedenler vardır.
Daha pratik olarak, birim testleri genel yöntemler yoluyla işlevselliği artırmalıdır. Test ettiğiniz kod bu özellikleri kullanıyorsa, kod kapsamını ücretsiz olarak alırsınız. Bu özelliklerin kod kapsamı tarafından asla vurgulanmadığı ortaya çıkarsa, çok güçlü bir olasılık vardır:
Alıcılar ve ayarlayıcılar için testler yazarsanız, yanlış bir kapsam duygusu alırsınız ve özelliklerin gerçekten işlevsel davranış tarafından kullanılıp kullanılmadığını belirleyemezsiniz.
Eğer cyclomatic karmaşıklık toplamamaddesi ve / veya Pasörlük (genellikle olan) 1, daha sonra cevap yapmamalıdın, hayır.
Bu nedenle,% 100 kod kapsamı gerektiren bir SLA'nız yoksa, rahatsız etmeyin ve yazılımınızın önemli yönünü test etmeye odaklanın.
Not: Özelliklerin aynı görünebileceği C # gibi dillerde bile, alıcıları ve ayarlayıcıları ayırt etmeyi unutmayın. Setter karmaşıklığı alıcıdan daha yüksek olabilir ve bu nedenle bir birim testi doğrular.
Mizahi, ancak akıllıca bir fikir : Testivus Yolu
"Bugün yapabileceğiniz testi yazın"
Deneyimli bir test kullanıcısıysanız ve bu küçük bir projeyse test alıcıları / ayarlayıcıları aşırıya kaçabilir. Ancak, yeni birimin nasıl test edileceğini öğrenmeye başlıyorsanız veya bu alıcılar / ayarlayıcılar mantık içerebilirse (@ ArtB setMom()
örneği gibi), o zaman test yazmak iyi bir fikir olacaktır.
Bu benim takımım ve ben arasında son zamanlardaki bir konu oldu.% 80 kod kapsamı için çekim yapıyoruz. Ekibim, alıcıların ve ayarlayıcıların otomatik olarak uygulandığını ve derleyicinin perde arkasında bazı temel kodlar ürettiğini savunuyor. Bu durumda, oluşturulan kod müdahaleci olmadığı göz önüne alındığında, derleyicinin sizin için oluşturduğu kodu test etmek gerçekten mantıklı değildir. Ayrıca, zaman uyumsuz yöntemler hakkında bu tartışmayı yaptık ve bu durumda derleyici sahnelerin arkasında bir sürü kod üretir. Bu farklı bir durum ve test ettiğimiz bir şey. Uzun cevap kısa, ekibinizle birlikte getirin ve test etmeye değer olup olmadığına kendiniz karar verin.
Ayrıca, bizim gibi kod kapsamı raporunu kullanıyorsanız, yapabileceğiniz bir şey [ExcludeFromCodeCoverage] özniteliğini eklemektir. Çözümümüz bunu sadece alıcılar ve ayarlayıcılar kullanan veya mülkün kendisinde bulunan özelliklere sahip modellerde kullanmaktı. Bu şekilde, kod kapsamı yüzdesi hesaplamak için kullandığınız varsayılarak, kod kapsamı raporu çalıştırıldığında toplam kod kapsamı yüzdesini etkilemez. Mutlu testler!
Bence kod kapsamı, kapsaması gereken herhangi bir işlevselliği kaçırıp kaçırmadığınızı görmenin iyi bir yoludur.
Kapsamı güzel renklendirmeyle manuel olarak incelediğinizde, düz alıcıların ve ayarlayıcıların test edilmesine gerek olmadığı söylenebilir (her zaman yapmam rağmen).
Projenizde yalnızca kod kapsamı yüzdesini kontrol ettiğinizde,% 80 gibi bir test kapsamı yüzdesi anlamsızdır. Tüm mantıksal parçaları test edebilir ve bazı önemli parçaları unutabilirsiniz. Bu durumda sadece% 100, tüm hayati kodunuzu (ve tüm mantıksal olmayan kodu) test ettiğiniz anlamına gelir. % 99.9 olduğu anda bir şeyi unuttuğunu biliyorsunuz.
Bu arada: Kod kapsamı, bir sınıfı tamamen (birim) test edip etmediğinizi görmek için son kontroldür. Ancak% 100 kod kapsamı, sınıfın tüm işlevlerini gerçekten test ettiğiniz anlamına gelmez. Bu yüzden, birim testler her zaman sınıfın mantığını izleyerek uygulanmalıdır. Sonunda bir şey unutup unutmadığınızı görmek için kapsama alanı çalıştırın. Doğru yaptığınızda, ilk seferinde% 100 vurdunuz.
Bir şey daha var: Son zamanlarda Hollanda'da büyük bir bankada çalışırken Sonar'ın% 100 kod kapsamı gösterdiğini fark ettim. Ancak bir şeyin eksik olduğunu biliyordum. Dosya başına kod kapsamı yüzdelerini inceleyerek, dosyayı daha düşük bir yüzde olarak gösterdi. Tüm kod tabanı yüzdesi, bir dosyanın yüzdeyi% 99.9 olarak göstermediği kadar büyüktü. Yani bunun için bakmak isteyebilirsiniz ...
JUnit kodunda elde edilen kapsamın küçük bir analizini yaptım .
Açık kodun bir kategorisi "test etmek için çok basit" tir . Bu, JUnit geliştiricilerinin test etmediği basit alıcıları ve ayarlayıcıları içerir .
Öte yandan, JUnit herhangi bir test kapsamında olmayan 3 satırdan daha uzun (kullanım dışı) yöntemi yoktur.
Şunu söyleyebilirim: EVET Getter / setter yöntemlerindeki hatalar sessizce gizlice girebilir ve bazı çirkin hatalara neden olabilir.
Bunu ve diğer bazı testleri kolaylaştırmak için bir lib yazdım. JUnit testlerinizde yazmanız gereken tek şey şudur:
assertTrue(executor.execute(Example.class, Arrays.asList( new DefensiveCopyingCheck(),
new EmptyCollectionCheck(), new GetterIsSetterCheck(),
new HashcodeAndEqualsCheck(), new PublicVariableCheck())));
Evet, özellikle alınacak öğe soyut bir sınıftan alt sınıfa alınmış bir sınıfın nesnesiyse. IDE'niz belirli bir mülkün başlatılmadığı konusunda sizi uyarabilir veya uyaramayabilir.
Ve sonra görünüşte ilgisiz bazı test çöküyor NullPointerException
ve bir gettable özelliği aslında ilk etapta orada olmadığını anlamak için biraz zaman alır.
Yine de bu, üretimdeki sorunu keşfetmek kadar kötü bir yerde olmayacaktı.
Tüm soyut sınıflarınızın yapıcılara sahip olduğundan emin olmak iyi bir fikir olabilir. Değilse, bir alıcı testi sizi orada bir sorunla ilgili uyarabilir.
İlkelleştiriciler ve düzenleyiciler için soru şu olabilir: Programımı mı test ediyorum yoksa JVM veya CLR'yi mi test ediyorum? Genel olarak, JVM'nin test edilmesine gerek yoktur.