Bugün hala Debug.Assert kullanmalı mıyım?


23

Geçenlerde birçok Debug.Assert (C #) ile serpiştirilmiş bazı yeni yazılmış kodlarla karşılaştım.

Genel olarak TDD, BDD ve Ünite Testi kullanımına rağmen, bunu hala yaygın olarak kullanmalı mıyız?


9
Birinin diğerini nasıl dışladığını göremiyorum.
SuperM

2
@superM Kesinlikle tembel geliştiricilerin, bağımlılıklarını çözmenin zor olacağı şekilde kodlarını yazdıkları için önceden testler eklediklerini gördüm. Tabii ki bunu tavsiye etmem
jk.

Yanıtlar:


23

Assert'i kullanmamanız için hiçbir neden görmüyorum. Bunu yaparak, önkoşullar ve değişmezler gibi gardiyanlara ihtiyaç duyduğunuzu çoktan kabul ettiniz ve Design by Contract'a doğru bir adım atıyorsunuz . Assert bunu başarmanın tek yoludur ...

// Precondition using Asert
void SomeMethod(Foo someParameter)
{
    Debug.Assert(someParameter != null)
}

// Precondition using If-Then-Throw
void SomeMethod(Foo someParameter)
{
    if (someParameter == null)
        throw new ArgumentNullException("someParameter");
}

// Precondition using Code Contracts
void SomeMethod(Foo someParameter)
{
    Contract.Requires(someParameter != null);
}

// Precondition using some custom library
void SomeMethod(Foo someParameter)
{
    Require.ArgumentNotNull(() => someParameter);
}

Hepsi aynı şeyi başarmanın yolları: koddaki sağlamlık. Bu sadece, Assert'in geçerli bir seçim olduğu bir seçenek seçmekle ilgilidir.

Unutmayın ki, çok farklı bir şey başardıkları için birim testlerden hiç bahsetmedim. Bir birim testi resmen bir koruma uygulayarak kodun sağlamlığını kanıtlar:

[Test]
void SomeMethod_WhenGivenNull_ThrowsArgumentNullException()
{
    delegate call = () => someObject.SomeMethod(null);

    Assert.That(call).Throws<ArgumentNullException>();
}

Bu tamamen farklı bir tür iddia.

** Bazı çerçevelerde, bir onaylama hatası için bir onaylama sınamasının bir bütün olarak test edilmesinin oldukça zor olduğunu unutmayın;


10

Alet kutumda iki farklı araç olduğunu iddia ve birim testleri düşünüyorum. Bazı şeyler birine daha uygun, bazıları diğerine daha uygundur.

Örnek olarak, bugünlerde genel olmayan yöntemlerin parametrelerini doğrulamak için çoğunlukla varlıkları kullanıyorum.


5

Debug.Assert'i bugünlerde erken optimizasyon olarak görüyorum. Performansa gerçekten ihtiyacınız olmadıkça, Assert’i sürüm modunda bastırmak hataları daha uzun süre gizleyebilir.

MattDavey’in işaret ettiği gibi, kod sözleşmeleri daha üstün olabilir, dinamik kontrol yerine statik kontrol sağlar ve eğer mevcut değilse Trace.Assert veya düz eski bir ürünü tercih ederimif(x) throw SomeException;


4
Serbest bırakma modunda Visual Studio ile kod üretmenin, Debugsınıf yöntemlerine yapılan tüm çağrıları derlemeden atlanmasına neden olacağından bahsetmekte fayda var, bu yüzden çağrıları Assertsadece performans için basitçe bastırmak sadece erken bir optimizasyon değil, sade bir saçmalık.
Konamiman

@Konamiman mesele, neredeyse her zaman serbest bırakma modunda aynı şekilde başarısız olmasını istiyorum:. Debug.Assert bana zamanın% 97'sini kullanmaz
jk.

Öyleyse% 3 ne, @jk? Yalnızca eski kod veya başka bir örnek?
DougM

@DougM performans kritik kodu, knuth alıntılarına atıfta bulunuyor. Ayrıca, heartbleed böceğinin benim görüşümün doğru olduğunu gösterdiğini düşünüyorum, başka seçeneğiniz olmadıkça, önkoşul kontrollerini sürüm kodunuzda
jk) seçmeyin.
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.