Birim test kodlama standartları


22

Genellikle kodlama standartlarından bahsederken, programın kendisinin koduna atıfta bulunuruz; Birim testlerine özgü belirli kodlama standart kuralları var mı? Onlar neler?

Yanıtlar:


12

Kafamın üstünden, test kodu için kodlama stilinde üç fark olduğunu düşünebilirim.

Test yöntemlerini isimlendirirken, kalıplarını takip ediyorum shouldDoSomethingWhenSomeConditionHolds.

Testin içinde, aşağıdaki boşluk düzenini izlemek alışılmış bir şeydir:

@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
    // Some lines 
    // of setup code
    // go here.

    // The action being tested happens after a blank line.

    // An assertion follows another blank line.
}

Bazıları test başına sadece bir iddiada ısrar ediyor, ancak bu evrensel olmaktan uzak.

DRY (Kendinizi Tekrar Etmeyin), test kodunda, üretim kodundan daha az dikkate alınır. Bazı tekrarlanan kodların bir setUp yöntemine veya bir testUtils sınıfına yerleştirilmesi gerekirken, test kodunda sıfır tekrar için çalışmak, yeniden birleşmeyi engelleyen sıkıca birleştirilmiş ve esnek olmayan testlere yol açacaktır.


Elbette, çeşitli modeller vardır, bu yüzden de bir cevap vermelisiniz.
Eric Wilson

10
Bu Düzen, Hareket, Assert kalıbıdır.
StuperUser

KURU hala önemlidir. Birden fazla testte aynı iddiaları yapmanız gerekiyorsa, ortak bir işlev oluşturun ve tüm testlerde arayın.
MiFreidgeim SO-stop kötü olma

@MichaelFreidgeim Belki sadece derecelerden bahsediyoruz, fakat test kodunda tekrarlama için önemli ölçüde daha yüksek tolerans gösteriyorum. Çok az tekrarlayan çok sayıda bina test takımı tecrübesi yaşadım ve testlerin gereksinimlerin ne zaman değiştiğini değiştirmek ve anlamak zorlaştığını gördüm. Sonra testlerde DRY hakkında endişelenmeyi bıraktım ve test takımlarımın kullanımı daha kolaydı. <shrug>
Eric Wilson

16

Roy Osherove, testlerinizi adlandırmak için aşağıdaki modeli önerir:

NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior() 

Bkz http://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspx


Roy ile aynı fikirdeyim. ReSharper bana bunları kaldırmam gerektiğini söylemeye devam etmesine rağmen okunabilirliği artırıyor NameOfMethodUnderTestStateUnderTestExpectedBehavior();)
Oscar Mederos

Metot aşırı yüklendiğinde bu nasıl çalışır, bu yüzden aynı isimde birden fazla metot olabilir mi?
Narendra Pathai

6

Asıl mesele, birim testlerinin aslında küçük şartname olduğunu hatırlamak. Bu, vurgunun daima okunabilir olması gerektiği anlamına gelir.

Birincisi, bu, isimlerin test edilen ve iddia edilenleri açıkça ifade etmesi gerektiği anlamına gelir.

İkincisi, bazen unutulmuş olsa da, spesifikasyonlar olarak tam da bunu - belirten davranışlar yapmaları gerektiğidir. Yani, birim testleri mantık içermemelidir - ya da potansiyel olarak test etmek yerine programın işlevselliğini tekrar etme tuzağına düşerler.

Bazen testler kurmak için karmaşık olan nesneler içerebilir, bu kurulum mantığını bir nesne annesi veya bir test veri oluşturucu gibi bir şey kullanarak testlerinizden ayrı tutmaya çalışmalısınız .

Birkaç kitap önerisi ile bir araya geleceğim:

xUnit Test Kalıpları: Yeniden Test Etme Test Kodu: Mükemmel kitap, bazıları biraz kuru olduğunu söylüyor ama sanmıyorum. Testleri organize etmenin birçok farklı yolu ve bunların nasıl korunabilir olacağı hakkında çok ayrıntıya giriyor. NUnit vs. gibi bir şey kullanıyorsanız, ilgili

Birim Sınama Sanatı: .Net'teki Örneklerle : Yazma ve sürdürme testlerinin nitrit-en iyi kitabı. Gerçekten yeni olmama rağmen, alaycı bölümleri zaten biraz tarihli buluyorum, çünkü AAA sözdizimi şimdi yapmaktan başka bir yol yerine oldukça standart.

Büyüyen Nesneye Yönelik Yazılımlar, Testler Kılavuzuyla : Bu kitap sadece şaşırtıcı! Bugüne kadarki en iyi ünite test kitabı ve ünite testini tasarım sürecinde birinci sınıf vatandaş olarak gösteren tek gelişmiş kitap. Bunu herkese açık bir beta iken okuyordum ve o zamandan beri tavsiye ediyorum. Kitap boyunca kullanılan mükemmel gerçek dünyaca işlenmiş örnek. Yine de Roy'un kitabını okumanızı tavsiye ederim.


IMHO, birim testlerinin mantık içermesi sorun değil: Doğru davranışı belirlemek için aynı şeyi yapan naif bir algoritma kullanarak bir algoritmanın oldukça optimize edilmiş, etkili bir versiyonunu test etmek kesinlikle mantıklı. Örneğin, doğrusal bir arama tabanlı ilişkisel dizi oluşturarak bir karma tablosunun test edildiğini hayal edin.
dsimcha

2
Evet, ancak bu test veri üreticileri içindeki testin dışındadır (eğer içlerindeki mantık önemsiz değilse kendileri test edilmelidir). Bunun istisnası, genellikle "doğru" olduğu ve test edilmeden kullanılabileceği konusunda güvenilen üçüncü taraf kütüphaneleri olacaktır.
FinnNk

3

Ünite testlerine mantık koymayın. Örneğin, bir ekleme yöntemi test ettiğinizi varsayalım, şöyle bir şey olabilir:

void MyTest_SaysHello()
{
   string name = "Bob";
   string expected = string.Format("Hello, {0}", name);
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello(name);
   Assert.AreEqual(expected, actual);
}

Bu özel durumda, testte olanlarla aynı mantığı tekrar ediyorsunuzdur, bu nedenle aslında "1 + 1 == 2" yerine "1 + 1 == 1 + 1" i test ediyorsunuz. "gerçek" sınav. Öyleyse, test kodunuzun gerçekten görünmesini istediğiniz şey şudur:

void MyTest_SaysHello()
{
   string expected = "Hello, Bob";
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello("Bob");
   Assert.AreEqual(expected, actual);
}

2
Küçük düzeltme: 'string expected = string.Format ("Merhaba, Bob")' ın 'string expected = "Hello, Bob"' anlamına geldiğini düşünüyorum.
Mike Rosenblum

@MikeRosenblum açık bir şekilde haklısınız ve birisi düzeltmeye çalıştı, ancak iki hakem bu düzenlemeyi reddetti
Konrad Morawski

@Konrad: Bu garip. Bu bir programlama forumu, değil mi?
Mike Rosenblum

Cevabı bir kez daha Mike Rosenblum’un önerdiği şekilde değiştirdim.
bdsl

0

Uzun, açıklayıcı yöntem adları. Unutmayın, test yöntemleri hiçbir zaman koddan çağrılmaz (üniteleri yansıtma yoluyla keşfeden ve çağıran birim test çalıştırıcısı tarafından çağrılırlar), bu yüzden çıldırmak ve 50-80 karakter uzunluğunda yöntem adlarına sahip olmak sorun değil. Belirli adlandırma kuralı (deve durum, alt çizgi, "gerekir", "zorunluluk", "ne zaman", "verilen", vb.), Ad üç soruyu yanıtladığı sürece gerçekten önemli değildir:

  • test altında ne var
  • Şartlar nelerdir?
  • Beklenen sonuç nedir?

Test yöntemleri kısa olmalıdır .

Test yöntemleri basit, doğrusal bir yapıya sahip olmalıdır . İf veya loop yapıları yok.

Test yöntemleri "arrange-act-assert" desenini takip etmelidir .

Her test bir şeyi test etmelidir . Bu genellikle test başına bir iddia anlamına gelir. Gibi bir test { Do A; Assert B; Assert C; }ikiye yeniden yansıtılmalıdır: { Do A; Assert B; }ve{ Do A; Assert C; }

Rasgele veriden veya 'DateTime.Now' gibi şeylerden kaçının

Tüm test fikstürü üyelerinin, testin sonunda orijinal durumlarına geri getirildiğinden emin olun (örneğin bir teardown kullanarak )

Çoğaltmayı üretim kodunuzda acımasızca kaldırsanız bile, test fikstürlerinde kod çoğaltması çok daha küçük bir sorundur.


-1

Farmboy'un daha önce söylediklerine benzer şekilde, My name name format

 <MethodName>Should<actionPerformed>When<Condition>

Örneğin

 GetBalanceShouldReturnAccountBalance() {
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.