Birim test senaryolarını nasıl yazıyorsunuz?


14

Bazen diğer geliştiricilerin yazdığı kod için birim test senaryoları yazarım. Geliştiricinin ne yapmaya çalıştığını gerçekten bilmediğim durumlar var (iş bölümü) ve sadece yeşil hattı almak için test senaryosunu değiştiriyorum. Endüstride bunlar normal mi?

Normal eğilim nedir? Geliştiricilerin kendi yazdıkları kod için birim test senaryoları yazmaları gerekiyor mu?


2
"dint"? "Dint" ne anlama geliyor?
S.Lott

Yanıtlar:


12

Bu blog gönderisini okumayı deneyin: Harika Birim Testleri Yazma: En İyi ve En Kötü Uygulamalar .

Ancak web'de sayısız başka var.

Sorularınıza doğrudan cevap olarak ...

  1. "Normal eğilim" - Sanırım bu yerden yere değişebilir, benim için normal olan diğerleri için garip olabilir.
  2. (Benim seçeneğimde) kodu yazan geliştirici, kod önce testi yazacağınız ideal olarak TDD gibi yöntemleri kullanarak testi yazmalıdır. Ancak başkalarının burada farklı yöntemleri ve fikirleri olabilir!

Ve testleri (sizin sorunuzda) yazma şekliniz tamamen yanlıştır!


9

Bu yaklaşım, birim testini değersiz hale getirir.

Bazı gerçek eylemler amaçlandığı gibi çalışmadığında, birim testinin başarısız olması gerekir. Bunu böyle yapmazsanız ve hatta testi test etmek için koddan önce bile yazıyorsanız, çalışmayan duman alarmlarına sahip olmak gibidir.


8
Bu tam olarak doğru değil. Ya da daha doğrusu, ideal bir dünyada doğrudur, ama ne yazık ki, çoğu zaman bundan uzaktayız. Testler olmadan ve spesifikasyonlar olmadan ve belirli bir kod parçasının tam olarak ne yapması gerektiğini dakika ayrıntılarına kadar güvenilir bir şekilde söyleyebilecek biri olmadan eski koda sahip olmayı düşünün (bu , mevcut projelerin büyük bir bölümünde gerçek). Bu durumda bile, kodun mevcut durumunu kilitlemek ve gelecekteki yeniden düzenleme, hata düzeltmeleri veya uzantılarla hiçbir şeyi kırmamanızı sağlamak için birim testleri yazmaya değer olabilir.
Péter Török

2
Ayrıca, sanırım "test etmek için koddan sonra testi yazmak" demek istediniz ?
Péter Török

@ Péter, ifadeler yanlış gitti - doğru anladın. Ancak, testler yazmaya karar verirseniz, yararlı olacak bir şey yapmaları gerekir. Sadece körü körüne kodu bir test olduğunu söyleyerek çağırmak - bence - test değil .

ørn, birim testlerimizde anlamlı iddialara sahip olmamız gerektiğini kastediyorsanız, test edilen kodun gerçekten düşündüğümüz şeyi yaptığını doğrulamak için tamamen katılıyorum.
Péter Török

3

Bir fonksiyonun ne yaptığını bilmiyorsanız, bunun için bir birim testi yazamazsınız. Tüm bildiğiniz için olması gerekeni bile yapmıyor. Önce ne yapması gerektiğini öğrenmelisin. Sonra testi yaz.


3

Gerçek Dünyada, başkasının kodu için birim testleri yazmak kesinlikle normaldir. Elbette, orijinal geliştirici bunu zaten yapmış olmalı, ancak genellikle bunun henüz yapılmadığı eski kodu alırsınız. Arada, söz konusu eski kod çok, çok uzak bir galaksiden yıl önce geldi, yoksa iş arkadaşlarınızla biri geçen hafta içinde kontrol ya da bugün yazdım, ister eski kodu olup olmadığı önemli değildir testler olmadan kod

Kendinize sorun: Neden birim testleri yazıyoruz? Yeşil Olmak açık bir şekilde sadece bir amaç için bir araçtır, nihai amaç test edilen kodla ilgili iddiaları kanıtlamak veya çürütmektir.

Kayan nokta sayısının karekökünü hesaplayan bir yönteminiz olduğunu varsayalım. Java'da arayüz bunu şöyle tanımlar:

public double squareRoot(double number);

Uygulamayı yazıp yazmadığınızdan veya bir başkasının yazıp yazmadığının bir önemi yoktur, squareRoot'un birkaç özelliğini öne çıkarmak istersiniz:

  1. sqrt (4.0) gibi basit kökleri döndürebileceğini
  2. makul bir hassasiyetle sqrt (2.0) gibi gerçek bir kök bulabileceğini
  3. sqrt (0.0) 'ın 0.0 olduğunu bulur.
  4. negatif bir sayı verildiğinde bir IllegalArgumentException özel durumu atar, yani sqrt (-1.0)

Bunları bireysel testler olarak yazmaya başlıyorsunuz:

@Test
public void canFindSimpleRoot() {
  assertEquals(2, squareRoot(4), epsilon);
}

Hata! Bu test zaten başarısız:

java.lang.AssertionError: Use assertEquals(expected, actual, delta) to compare floating-point numbers

Kayan nokta aritmetiği unuttun. Tamam, siz tanıtın double epsilon=0.01ve gidin:

@Test
public void canFindSimpleRootToEpsilonPrecision() {
  assertEquals(2, squareRoot(4), epsilon);
}

ve diğer testleri ekleyin: sonunda

@Test
@ExpectedException(IllegalArgumentException.class)
public void throwsExceptionOnNegativeInput() {
  assertEquals(-1, squareRoot(-1), epsilon);
}

ve ayy, yine:

java.lang.AssertionError: expected:<-1.0> but was:<NaN>

Test etmelisiniz:

@Test
public void returnsNaNOnNegativeInput() {
  assertEquals(Double.NaN, squareRoot(-1), epsilon);
}

Burada ne yaptık? Yöntemin nasıl davranması gerektiği konusunda birkaç varsayımla başladık ve hepsinin doğru olmadığını gördük. Daha sonra yöntemin düzeltilmiş varsayımlarımıza göre davrandığını kanıtlamak için test paketini Yeşil yaptık. Artık bu kodun istemcileri bu davranışa güvenebilir. Birisi squareRoot'un gerçek uygulamasını başka bir şeyle değiştirecek olsaydı, örneğin NaN döndürmek yerine gerçekten bir istisna atan bir şey varsa, testlerimiz bunu hemen yakalayacaktı.

Bu örnek önemsizdir, ancak genellikle gerçekte ne yaptığının belirsiz olduğu büyük kod parçalarını miras alırsınız. Bu durumda, kodun etrafına bir test bandı yerleştirmek normaldir. Kodun nasıl davranması gerektiği hakkında birkaç temel varsayımla başlayın, onlar için birim testleri yazın, test edin. Yeşil ise, iyi, daha fazla test yazın. Kırmızı ise, şimdi bir spesifikasyona karşı tutabileceğiniz konusunda başarısız bir iddianız var. Belki eski kodda bir hata var. Belki de spesifikasyon bu girdi hakkında net değil. Belki bir özelliğiniz yok. Bu durumda, testi beklenmedik davranışı belgeleyecek şekilde yeniden yazın:

@Test
public void throwsNoExceptionOnNegativeInput() {
  assertNotNull(squareRoot(-1)); // Shouldn't this fail?
}

Zamanla, kodun gerçekte nasıl davrandığını belgeleyen ve bir tür kodlu bir spesifikasyon haline gelen bir test koşumuyla sonuçlanırsınız. Eski kodu değiştirmek veya başka bir kodla değiştirmek isterseniz, yeni kodun aynı şekilde davrandığını veya yeni kodun beklenen ve kontrol edilen şekilde farklı davrandığını doğrulamak için test cihazına sahipsiniz (örneğin, aslında düzeltmesini beklediğiniz hatayı düzeltir). Bu koşum takımının ilk günde tamamlanması gerekmez, aslında, eksik bir koşum takımına sahip olmak neredeyse hiç koşum takımına sahip olmaktan daha iyidir. Bir koşum takımına sahip olmak, müşteri kodunuzu daha kolay yazabileceğiniz anlamına gelir, bir şeyi değiştirdiğinizde bir şeylerin nerede kırılacağını ve nihayetinde bozulduklarında nerede kırıldıklarını bilirsiniz.

Sadece bir formdaki zorunlu alanları doldurmanız gerektiği gibi, birim testleri yazmak zorunda olduğunuz zihniyetten çıkmaya çalışmalısınız. Ve sadece kırmızı çizgiyi yeşil yapmak için birim testleri yazmamalısınız. Birim testleri düşman değil, birim testleri arkadaşlarınızdır.


1

Im test durumlarda (yazıcılar için) yazarken her küçük bileşenleri .... ve muhtemelen onu kırmak için ne yapabilirim düşünmeye çalışın. Diyelim ki tarayıcı, örneğin, hangi komutları kullanıyor (pjl yazıcı-iş-dilinde) her işlevselliği test etmek için ne yazabilirim .... Tamam şimdi bunu denemek ve kırmak için ne yapabilirim.

Bunu her büyük bileşen için yapmaya çalışıyorum, ancak yazılım söz konusu olduğunda ve çok fazla donanım olmadığında, her yönteme / işleve bakmak ve sınırları kontrol etmek istiyorsunuz.


1

Ünite testi yapmayan diğer geliştiricilerle (veya diğer geliştiriciler tarafından yazılan kodun bakımını) yaptığınız anlaşılıyor. Bu durumda, test ettiğiniz nesne veya yöntemin ne yapacağını kesinlikle bilmek, ardından bunun için bir test oluşturmak istediğinizi düşünüyorum.

TDD olmayacak çünkü önce testi yazmadınız, ancak durumu iyileştirebilirsiniz. Ayrıca, kod başarısız olduğunda testlerinizin düzgün çalışmasını sağlayabilmeniz için test edilen nesnelerin saplamalarla bir kopyasını oluşturmak isteyebilirsiniz.

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.