Haruskah saya masih menggunakan Debug. Tanyakan hari ini?

23

Saya baru-baru ini menemukan beberapa kode yang baru ditulis yang diselingi dengan banyak Debug.Assert (C #).

Haruskah kita masih menggunakan ini secara luas meskipun penggunaan TDD, BDD dan Unit Testing secara umum?

Dominik Fretz
sumber
9
Saya tidak bisa melihat bagaimana satu mengecualikan yang lain.
superM
2
@superM Saya sudah pasti melihat pengembang malas menambahkan tes sebagai pernyataan sebelumnya karena mereka telah menulis kode mereka sehingga sulit untuk menghilangkan ketergantungan. tidak perlu dikatakan saya tidak akan merekomendasikan ini
jk.

Jawaban:

23

Saya tidak melihat alasan mengapa Anda tidak boleh menggunakan Assert. Dengan melakukan itu, Anda telah mengakui adanya kebutuhan akan penjaga, seperti prasyarat & invarian, dan membuat langkah menuju Desain berdasarkan Kontrak . Menyatakan hanya satu cara untuk mencapai ini ...

// 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);
}

Semua cara mencapai hal yang sama: ketahanan dalam kode. Itu hanya datang untuk memilih opsi, di mana Assert adalah pilihan yang valid.

Perhatikan bahwa saya belum menyebutkan tes unit sama sekali sejauh ini, karena mereka mencapai sesuatu yang sangat berbeda. Tes unit secara formal membuktikan kekokohan kode dengan melatih penjaga:

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

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

Ini adalah jenis pernyataan yang sepenuhnya berbeda ...

** Perhatikan bahwa dalam beberapa kerangka kerja sebenarnya cukup sulit untuk menguji unit untuk kegagalan pernyataan, karena kegagalan pernyataan dapat menurunkan seluruh runtime, jadi salah satu opsi lain mungkin lebih disukai ... *

MattDavey
sumber
10

Saya menganggap tes menegaskan dan unit menjadi dua alat yang berbeda di kotak alat saya. Beberapa hal lebih cocok untuk satu, dan beberapa lebih cocok untuk yang lain.

Sebagai contoh, hari ini saya lebih banyak menggunakan pernyataan untuk memvalidasi parameter untuk metode non-publik.

vaughandroid
sumber
5

Saya melihat Debug.Assert sebagai optimasi prematur saat ini. Kecuali Anda benar-benar membutuhkan kinerja, menekan Assert dalam mode rilis dapat menyembunyikan bug lebih lama.

Sebagai MattDavey poin kontrak kode bisa menjadi unggul, menyediakan statis memeriksa bukannya memeriksa dinamis, dan jika tidak tersedia saya lebih memilih Trace.Assert atau tua polosif(x) throw SomeException;

jk.
sumber
4
Perlu disebutkan bahwa menghasilkan kode dengan Visual Studio dalam mode rilis akan menyebabkan semua panggilan ke metode Debugkelas akan dilewati dari kompilasi ... jadi menekan panggilan untuk Asserthanya untuk kinerja bukan hanya optimasi prematur, itu omong kosong belaka.
Konamiman
@Konamiman itu intinya, saya hampir selalu ingin gagal dengan cara yang sama dalam mode rilis:. Debug.Assert tidak ada gunanya bagi saya 97% dari waktu
jk.
Apa itu 3% kalau begitu, @jk? Hanya kode lawas, atau contoh lain?
DougM
@DougM kinerja kode kritis, ini referensi ke kutipan knuth Saya juga menambahkan bahwa saya pikir bug heartbleed menunjukkan bahwa pandangan saya adalah yang benar, kecuali jika Anda tidak punya pilihan lain, jangan hilangkan pemeriksaan prekondisi dalam kode rilis Anda
jk.