it-swarm.dev

"İyi" birim testleri nasıl yazılır?

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.

63
Jens

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.

52
Andy Lowry

İ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.

43
mojuba

İyi birim testleri esasen çalıştırılabilir formdaki özelliklerdir:

  1. kullanım senaryolarına karşılık gelen kodun davranışını tanımlar
  2. teknik köşe vakalarını kapsar (null değeri geçilirse ne olur) - köşe durumu için bir test yoksa, davranış tanımsızdır.
  3. test edilen kod şartnameden uzaklaşırsa kes

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.

10
user1249

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.

7
Steven A. Lowe

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.

5
user281377

İ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.

5
Tim Post

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.

4
glenatron

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.

3

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):

  • Hızlı (çabuk koşmalılar, böylece insanlar onları koşturmaya aldırmazlar)
  • Bağımsız (testler birbirleri için kurulum veya sökme yapmamalıdır)
  • Tekrarlanabilir (tüm ortamlarda/platformlarda çalıştırılmalıdır)
  • Kendini doğrulayan (tam otomatik; çıktı bir günlük dosyası değil, "başarılı" veya "başarısız" olmalıdır)
  • Zamanında (ne zaman yazılır - test ettikleri üretim kodunu yazmadan hemen önce)
2
Kazark