Sözleşmeye Dayalı Programlama ve Birim Testi


13

Ben biraz savunmacı bir programcıyım ve Microsofts Kod Sözleşmelerinin büyük bir hayranıyım.

Şimdi her zaman C # kullanamıyorum ve çoğu dilde sahip olduğum tek araç iddialar. Bu yüzden genellikle böyle bir kod ile sonuçlanır:

class
{       
    function()
    {   
         checkInvariants();
         assert(/* requirement */);

         try
         {
             /* implementation */
         }
         catch(...)
         {
              assert(/* exceptional ensures */);                  
         }
         finally
         {
              assert(/* ensures */);
              checkInvariants();
         }
    }

    void checkInvariants()
    {
         assert(/* invariant */);
    }
}

Ancak, bu paradigma (ya da her ne derseniz) kod karmaşasına neden olur.

Gerçekten çabaya değip değmeyeceğini ve uygun birim testinin zaten bunu kapatacağını merak etmeye başladım?


6
Birim testleri, iddiaların uygulama kodunun dışına taşınmasına izin verirken (ve dolayısıyla karışıklıktan kaçınır), gerçek üretim sisteminde olabilecek her şeyi kontrol edemediklerini düşünün. Dolayısıyla IMO kod sözleşmelerinin, özellikle doğruluğun özellikle önemli olduğu kritik kodlar için bazı avantajları vardır.
Giorgio

Yani temelde geliştirme zamanı, sürdürülebilirlik, okunabilirlik ve daha iyi kod kapsamı?
13:57

1
Çoğunlukla parametrelerin doğruluğunu kontrol etmek için kodda iddiayı kullanıyorum (örneğin boşta) ve birim testinde ek olarak bu iddiaları kontrol ediyorum.
artjom

Yanıtlar:


14

Bunu "vs" olarak düşünmeniz gerektiğini düşünmüyorum.
@Giorgio'nun yorumlarında belirtildiği gibi, kod sözleşmeleri değişmezleri (üretim ortamında) kontrol etmek ve birim testleri, bu koşullar karşılandığında beklenen şekilde çalıştığınızdan emin olmak içindir.


2
Ben koşullar, kodun işleri (örneğin bir istisna atar) olup olmadığı da test etmek önemli olduğunu düşünüyorum değil buluştu.
svick

6

Sözleşmeler, birim testlerin yapmadığı en az bir şey konusunda size yardımcı olur. Herkese açık bir API geliştirirken kullanıcıların kodunuzu nasıl kullandığını test edemezsiniz. Ancak yine de yöntemleriniz için sözleşmeler tanımlayabilirsiniz.

Şahsen ben sadece bir modülün kamu API ile uğraşırken sözleşmeler hakkında bu titiz olurdu. Diğer birçok durumda, muhtemelen çabaya değmez (ve bunun yerine birim testlerini kullanabilirsiniz), ancak bu sadece benim düşüncem.

Bu, bu gibi durumlarda sözleşmeler hakkında düşünmemeyi tavsiye ettiğim anlamına gelmez. Onları hep düşünüyorum. Sadece açıkça onları kodlamak için gerekli olduğunu sanmıyorum.


1

Daha önce de belirtildiği gibi Sözleşmeler ve birim testleri farklı amaçlara sahiptir.

Sözleşmeler, ön koşulların karşılandığından, kodun doğru parametrelerle çağrıldığından emin olmak için savunma programlamasıyla ilgilidir.

Farklı senaryolarda kodun çalışmasını sağlamak için birim testleri. Bunlar 'dişli gözlükler' gibidir.

Ekler, kod sağlam yapmak iyidir. Ancak, çok fazla kod eklediğinden endişe ediyorsanız, hata ayıklama sırasında bazı yerlerde koşullu kesme noktaları eklemek ve Assert sayısını azaltmak isteyebilirsiniz.


0

CheckVariants () çağrılarınızda bulunan herhangi bir şey, testten yapılabilir, bunun ne kadar çaba olabileceği pek çok şeye bağlıdır (dış bağımlılıklar, bağlantı seviyeleri vb.), Ancak kodu bir bakış açısından temizler. İddialara karşı geliştirilen bir kod-bazının nasıl test edilebileceğinden emin değilim.

@Duros ile hemfikirim, bunlar münhasır veya rakip yaklaşımlar olarak düşünülmemelidir. Aslında bir TDD ortamında 'gereksinim' iddialarının test yaptırması gerekeceğini bile iddia edebilirsiniz :).

Bununla birlikte, hatalı denetimi düzeltmek için bir şey yapmadığınız sürece kodu daha sağlam hale getirmez, sadece ilk sorun belirtisinde işlemeyi durdurarak verilerin bozulmasını veya benzerliğini durdururlar.

Test güdümlü / iyi test edilmiş bir çözüm, etkileşen bileşenleri geliştirirken ve zaten onlarla sorunun kaynağına daha yakın bir şekilde ilgilenirken, kötü girdilerin ve çıktıların birçok kaynağını / nedenini zaten düşünmüş ve / veya keşfetmiş olacaktır.

Kaynağınız harici ise ve üzerinde herhangi bir kontrole sahip değilseniz, kodunuzun diğer kod sorunlarıyla uğraşmasını önlemek için kaynak ve bileşen arasında bir tür veri temizleme / onaylama bileşeni uygulamayı ve kontrollerinizi oraya koymayı düşünebilirsiniz. .

Ayrıca, xUnit veya birisinin geliştirdiği başka bir test kütüphanesi olmayan hangi dilleri kullandığınızı merak ediyorum, bu günlerde her şey için hemen hemen bir şey olduğunu düşündüm?


0

Birim testleri ve kod sözleşmelerine ek olarak, sadece kodlarınızı ilk etapta yanlış arama olasılığını ortadan kaldıracak veya azaltacak şekilde arayüzlerinizi tanımlamanın değeri olan başka bir yönü vurgulayacağımı düşündüm.

Her zaman kolay veya mümkün değil, ama kesinlikle kendinize, "Bu kodu daha kusursuz yapabilir miyim?" Sorusunu sormaya değer.

C # 'ın yaratıcısı Anders Hejlsberg, C #' daki en büyük hatalardan birinin nullenemeyen referans türlerini içermediğini söyledi. Bu kadar gerekli güvenlik kodu karmaşasının ana nedenlerinden biridir.

Yine de, sadece gerekli ve yeterli miktarda güvenlik koduna sahip olmak için yeniden düzenleme, benim tecrübelerime göre, daha kullanışlı ve sürdürülebilir bir kod oluşturur.

Geri kalanında @duros ile aynı fikirde.


0

Her ikisini de yapın, ancak niyetlerinizi netleştirmek için bazı statik yardımcı yöntemler yapın. Google'ın Java için yaptığı şey budur, code.google.com/p/guava-libraries/wiki/PreconditionsExplained adresine bakın

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.