bu kon tarafından tetiklenen, ben (tekrar) sonunda projelerimde birim testleri kullanmayı düşünüyorum. Birkaç poster, "Testler güzel, eğer iyi testler ise" gibi bir şey söylüyor. Şimdi sorum: "İyi" testler nelerdir?
Uygulamalarımda, ana kısım genellikle, büyük miktarda gözlenen verilere bağlı olarak ve bu verileri modellemek için kullanılabilecek bir uyum işleviyle sonuçlanan bir tür sayısal analizdir. Olası girişler ve sonuçların sayısı sadece her vakayı test etmek için çok fazla olduğundan ve yöntemlerin kendileri genellikle oldukça uzun ve performanstan ödün vermeden kolayca yeniden düzenlenemediğinden, bu yöntemler için testler yapmak özellikle zor buldum. Özellikle bu tür bir yöntem için "iyi" testlerle ilgileniyorum.
Birim Testi Sanatı birim testleri hakkında şunları söyleyebilir:
Birim testi aşağıdaki özelliklere sahip olmalıdır:
- Otomatik ve tekrarlanabilir olmalıdır.
- Uygulaması kolay olmalıdır.
- Yazıldıktan sonra, ileride kullanılmak üzere kalmalıdır.
- Herkes onu çalıştırabilmelidir.
- Bir düğmeye basarak çalışmalıdır.
- Çabuk çalışmalı.
ve daha sonra tam otomatik, güvenilir, okunabilir ve bakımı yapılabilir olması gerektiğini ekliyor.
Henüz yapmadıysanız bu kitabı okumanızı şiddetle tavsiye ederim.
Benim düşünceme göre, tüm bunlar çok önemlidir, ancak son üçü (güvenilir, okunabilir ve bakımı yapılabilir) özellikle, testleriniz bu üç özelliğe sahipmiş gibi, kodunuz genellikle de bunlara sahiptir.
İyi bir birim testi, test ettiği işlevi yansıtmaz.
Büyük ölçüde basitleştirilmiş bir örnek olarak, ortalama iki int döndüren bir işleve sahip olduğunuzu düşünün. En kapsamlı test işlevi çağırır ve bir sonucun aslında bir ortalama olup olmadığını kontrol eder. Bu hiç mantıklı değil: test ettiğiniz işlevselliği yansıtıyorsunuz (çoğalıyorsunuz). Ana işlevde bir hata yaptıysanız, aynı hatayı testte yaparsınız.
Başka bir deyişle, birim testteki ana işlevselliği çoğaltırsanız, zamanınızı boşa harcamanızın olası bir işaretidir.
İyi birim testleri esasen çalıştırılabilir formdaki özelliklerdir:
Test-Driven-Development'in, öncelikle API'yi ve daha sonra gerçek uygulamayı yazarken kütüphane rutinleri için çok uygun olduğunu gördüm.
tDD için "iyi" test testi müşterinin istediği özellikleri ; özellikler mutlaka işlevlere karşılık gelmez ve geliştirici tarafından bir vakumda test senaryoları oluşturulmamalıdır
sizin durumunuzda - tahmin ediyorum - 'özellik', uyum fonksiyonunun giriş verilerini belirli bir hata toleransı içinde modellemesidir. Gerçekten ne yaptığını bilmediğim için bir şey uyduruyorum; umarım analgous olur.
Örnek hikaye:
[X-Kanat Pilotu] olarak [% 0.0001'den fazla uyum hatası yok] istiyorum, böylece [hedefleme bilgisayarı bir kutu kanyonunda tam hızda hareket ederken Ölüm Yıldızının egzoz portuna vurabilir]
Böylece pilotlarla (ve eğer varsa hedef bilgisayarla) konuşursunuz. Önce 'normal' olandan, sonra anormalden bahsedin. Bu senaryoda neyin önemli olduğunu, neyin yaygın olduğunu, neyin olası olmadığını ve neyin mümkün olduğunu öğrenirsiniz.
Normalde yedi telemetri verisi kanalında yarım saniyelik bir pencereye sahip olacağınızı varsayalım: hız, adım, yuvarlanma, sapma, hedef vektör, hedef boyut ve hedef hız ve bu değerler sabit olacak veya doğrusal olarak değişecektir. Anormal olarak daha az kanalınız olabilir ve/veya değerler hızla değişiyor olabilir. Yani birlikte gibi bazı testler yaparsınız:
//Scenario 1 - can you hit the side of a barn? Given: all 7 channels with no dropouts for the full half-second window, When: speed is zero and target velocity is zero and all other values are constant, Then: the error coefficient must be zero //Scenario 2 - can you hit a turtle? Given: all 7 channels with no dropouts for the full half-second window, When: speed is zero and target velocity is less than c and all other values are constant, Then: the error coefficient must be less than 0.0000000001/ns ... //Scenario 42 - death blossom Given: all 7 channels with 30% dropout and a 0.05 second sampling window When: speed is zero and position is within enemy cluster and all targets are stationary Then: the error coefficient must be less than 0.000001/ns for each target
Şimdi, hikayede açıklanan belirli durum için hiçbir senaryo olmadığını fark etmiş olabilirsiniz. Müşteri ve diğer paydaşlarla konuştuktan sonra, orijinal hikayedeki amacın sadece varsayımsal bir örnek olduğu ortaya çıkıyor. Gerçek testler sonraki tartışmadan çıktı. Bu olabilir. Hikaye yeniden yazılmalıdır, ancak [hikaye sadece müşteriyle sohbet etmek için bir yer tutucu olduğundan] olmak zorunda değildir.
Yalnızca minimum sayıda giriş (olası 1 veya 0) ve birkaç standart durum içeren bir test seti gibi köşe vakaları için testler oluşturun. Bu birim testleri, kapsamlı kabul testlerinin yerine geçmez ve olmamalıdır.
İnsanların nadiren girilen kodlar için test yazma ve sık girilen kodlar için testler yazma konusunda çok fazla çaba harcadığı birçok durum gördüm.
Herhangi bir test yazmak için oturmadan önce, yeterli kapsama alanı planladığınızdan emin olmak için bir tür arama grafiğine bakmalısınız.
Buna ek olarak, sadece "Evet, bunu test ediyoruz" demek uğruna sınav yazmaya inanmıyorum. Bırakılan ve değişmeyecek bir kütüphane kullanıyorsam, bazı bölümleri puanlasa bile, bir API'nin asla değişmeyecek şekilde çalıştığı gibi beklendiği gibi çalıştığından emin olmak için bir gün yazma testleri harcamazım yüksek bir arama grafiği. tüketmek kütüphane (kendi kodum) bunu işaret eder testler.
Pek de TDD değil, ancak KG'ye girdikten sonra, KG süreci sırasında ortaya çıkan hataları yeniden oluşturmak için test senaryoları oluşturarak testlerinizi geliştirebilirsiniz. Bu, daha uzun vadeli desteğe girdiğinizde ve insanların yanlışlıkla eski hataları yeniden vermelerini riske attığınız bir yere gitmeye başladığınızda özellikle değerli olabilir. Bunu yakalamak için bir testin yapılması özellikle değerlidir.
Her testin sadece bir şeyi test etmesini sağlamaya çalışıyorum. Her sınama shouldDoSomething () gibi bir isim vermeye çalışıyorum. Uygulamayı değil davranışı test etmeye çalışıyorum. Sadece herkese açık yöntemleri test ediyorum.
Genellikle başarı için bir veya birkaç testim var ve belki de genel yöntem başına başarısızlık için bir avuç testim var.
Çok fazla maket kullanıyorum. İyi bir sahte çerçeve muhtemelen PowerMock gibi oldukça yararlı olacaktır. Henüz kullanmama rağmen.
A sınıfı başka bir B sınıfı kullanıyorsa, bir arabirim (X) eklerdim, böylece A doğrudan B'yi kullanmaz. Sonra mock-up XMockup oluşturmak ve testlerimde B yerine onu kullanmak istiyorum. Test yürütmesini hızlandırmaya, test karmaşıklığını azaltmaya yardımcı olur ve ayrıca A için yazdığım test sayısını azaltır, çünkü B'nin özellikleriyle başa çıkmak zorunda değilim. Örneğin A'nın X.someMethod () çağırdığını test edebilirim B.someMethod () öğesini çağırmanın bir yan etkisi yerine.
Test kodunu da temiz tutun.
Veritabanı katmanı gibi bir API kullanırken, bunu taklit edip mock-up'ın komut üzerindeki olası her fırsatta bir istisna atmasını sağlarım. Daha sonra testleri bir kez atmadan ve bir döngüde her seferinde test tekrar başarılı oluncaya kadar bir sonraki fırsatta bir istisna atarım. Symbian için mevcut olan hafıza testleri gibi.
Andry Lowry'nin Roy Osherove'un birim test metriklerini zaten yayınladığını görüyorum; ancak hiç kimse Bob Amca'nın Temiz Kod (132-133) ile verdiği (ücretsiz) seti sunmamış gibi görünüyor. FIRST kısaltmasını kullanıyor (burada özetlerimle):