ฉันควรใช้ Debug ยังคงยืนยันในวันนี้?


23

ฉันเพิ่งเจอรหัสที่เพิ่งเขียนใหม่ซึ่งมีจำนวน Debug.Assert (C #) มากมาย

เราควรใช้สิ่งนี้อย่างกว้างขวางแม้ว่าจะใช้ TDD, BDD และการทดสอบหน่วยโดยทั่วไปหรือไม่?


9
ฉันไม่เห็นว่าจะมีวิธีใดแยกอีก
superM

2
@superM ฉันได้เห็นนักพัฒนาที่ขี้เกียจเพิ่มการทดสอบตามที่อ้างไว้ก่อนหน้านี้เนื่องจากพวกเขาได้เขียนโค้ดของพวกเขาเพื่อให้มันยากที่จะเลียนแบบการอ้างอิง ไม่จำเป็นต้องบอกว่าฉันจะไม่แนะนำสิ่งนี้
jk

คำตอบ:


23

ฉันไม่เห็นเหตุผลใด ๆ ที่คุณไม่ควรใช้ Assert โดยการทำเพื่อให้คุณได้รับการยอมรับแล้วจำเป็นที่จะต้องยามเช่นปัจจัยพื้นฐานและค่าคงที่และมีการย้ายไปสู่การออกแบบโดยสัญญา ยืนยันเป็นเพียงวิธีหนึ่งในการบรรลุเป้าหมายนี้ ...

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

ทั้งหมดเป็นวิธีการบรรลุสิ่งเดียวกัน: ความแข็งแกร่งในรหัส มันเพิ่งจะมาถึงการเลือกตัวเลือกซึ่ง Assert เป็นตัวเลือกที่ถูกต้อง

โปรดทราบว่าฉันยังไม่ได้กล่าวถึงการทดสอบหน่วยเลยเพราะพวกเขาประสบความสำเร็จในสิ่งที่แตกต่างกันมาก การทดสอบหน่วยเป็นการพิสูจน์ความแข็งแกร่งของรหัสอย่างเป็นทางการโดยการใช้ตัวป้องกัน:

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

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

นี่เป็นประเภทที่แตกต่างอย่างสิ้นเชิงกับการยืนยัน ...

** โปรดสังเกตว่าในบางเฟรมเวิร์กนั้นยากที่จะทดสอบหน่วยสำหรับความล้มเหลวในการยืนยันเนื่องจากความล้มเหลวในการยืนยันสามารถทำให้รันไทม์ทั้งหมดลงดังนั้นตัวเลือกอื่นอาจเป็นที่ต้องการ ... *


10

ฉันถือว่าการทดสอบและการทดสอบหน่วยเป็นเครื่องมือสองแบบที่แตกต่างกันในกล่องเครื่องมือของฉัน บางสิ่งบางอย่างจะเหมาะกับคนหนึ่งและบางคนก็เหมาะกับคนอื่น

ตัวอย่างเช่นวันนี้ฉันส่วนใหญ่ใช้การยืนยันเพื่อตรวจสอบพารามิเตอร์สำหรับวิธีการที่ไม่ใช่แบบสาธารณะ


5

ฉันดู Debug.Assert เป็นการเพิ่มประสิทธิภาพก่อนวัยอันควรในปัจจุบัน ถ้าคุณไม่ต้องการประสิทธิภาพจริงๆการระงับ Assert ในโหมด release สามารถซ่อนบั๊กได้นานขึ้น

ในขณะที่ MattDavey ชี้ให้เห็นว่าการทำสัญญารหัสสามารถทำได้ดีกว่าให้การตรวจสอบแบบคงที่แทนการตรวจสอบแบบไดนามิกและหากไม่มีให้ใช้ฉันต้องการTrace.Assertหรือเก่าธรรมดาif(x) throw SomeException;


4
เป็นเรื่องที่ควรกล่าวถึงว่าการสร้างโค้ดด้วย Visual Studio ในโหมดการเปิดตัวจะทำให้การโทรไปยังวิธีการDebugเรียนทั้งหมดถูกข้ามจากการคอมไพล์ ... ดังนั้นการระงับการโทรเพื่อAssertประสิทธิภาพไม่ได้เป็นเพียงการเพิ่มประสิทธิภาพก่อนวัยอันควร
Konamiman

@ Konamiman นั่นคือจุดที่ฉันมักจะต้องการที่จะล้มเหลวในลักษณะเดียวกันในโหมดการเปิดตัว: Debug ขอยืนยันว่าไม่มีประโยชน์กับฉัน 97% ของเวลา
jk

ถ้าอย่างนั้น 3% คืออะไร @jk รหัสดั้งเดิมเท่านั้นหรืออินสแตนซ์อื่น ๆ
DougM

@DougM รหัสสำคัญประสิทธิภาพการอ้างอิงของ knuth quote ฉันยังเพิ่มว่าฉันคิดว่าข้อผิดพลาด heartbleed แสดงให้เห็นว่ามุมมองของฉันเป็นคนที่ถูกต้องเว้นแต่คุณจะไม่มีทางเลือกอื่น ๆ ไม่ต้องตรวจสอบเงื่อนไขเบื้องต้นในรหัสการเปิดตัวของคุณ
jk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.