Tôi có nên sử dụng Debug.Assert ngày hôm nay không?


23

Gần đây tôi đã bắt gặp một số mã mới được viết xen kẽ với rất nhiều Debug.Assert (C #).

Chúng ta vẫn nên sử dụng rộng rãi mặc dù sử dụng TDD, BDD và Kiểm tra đơn vị nói chung?


9
Tôi không thể thấy cái này loại trừ cái kia.
superM

2
@superM Tôi chắc chắn đã thấy các nhà phát triển lười biếng thêm các bài kiểm tra như các xác nhận trước đây vì họ đã viết mã của họ sao cho khó có thể chế nhạo các phụ thuộc. không cần phải nói tôi sẽ không đề nghị điều này
jk.

Câu trả lời:


23

Tôi không thấy bất kỳ lý do tại sao bạn không nên sử dụng Assert. Bằng cách đó, bạn đã thừa nhận cần một người bảo vệ, như điều kiện tiên quyết & bất biến, và đang tiến tới Thiết kế theo Hợp đồng . Khẳng định chỉ là một cách để đạt được điều này ...

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

Tất cả đều là cách để đạt được điều tương tự: sự mạnh mẽ trong mã. Chỉ cần chọn một tùy chọn, trong đó Assert là một lựa chọn hợp lệ.

Lưu ý rằng tôi đã không đề cập đến các bài kiểm tra đơn vị cho đến nay, vì họ hoàn thành một cái gì đó rất khác nhau. Một thử nghiệm đơn vị chính thức chứng minh sự mạnh mẽ của mã bằng cách thực hiện một người bảo vệ:

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

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

Đây là một loại khẳng định hoàn toàn khác ...

** Lưu ý rằng trong một số khung, thực sự rất khó để kiểm tra đơn vị cho lỗi xác nhận, vì lỗi xác nhận có thể làm giảm toàn bộ thời gian chạy, do đó, một trong các tùy chọn khác có thể được ưu tiên ... *


10

Tôi coi các khẳng định và kiểm tra đơn vị là hai công cụ khác nhau trong hộp công cụ của mình. Một số thứ phù hợp hơn với cái này, và một số thứ phù hợp hơn với cái khác.

Ví dụ, những ngày này tôi chủ yếu sử dụng các xác nhận để xác nhận các tham số cho các phương thức không công khai.


5

Tôi xem Debug.Assert là tối ưu hóa sớm hiện nay. Trừ khi bạn thực sự cần hiệu năng, việc loại bỏ Assert trong chế độ phát hành có thể ẩn lỗi lâu hơn.

Như MattDavey chỉ ra các hợp đồng mã có thể là ưu việt, cung cấp kiểm tra tĩnh thay vì kiểm tra động và nếu không có sẵn, tôi thích Trace.Assert hoặc cũ hơnif(x) throw SomeException;


4
Điều đáng nói là việc tạo mã với Visual Studio trong chế độ phát hành sẽ khiến tất cả các lệnh gọi đến các phương thức của Debuglớp bị bỏ qua khỏi quá trình biên dịch ... vì vậy việc loại bỏ các cuộc gọi thành Assertđơn giản để thực hiện không chỉ là tối ưu hóa sớm, nó là một điều vô nghĩa.
Konamiman

@Konamiman đó là điểm chính, tôi hầu như luôn muốn nó thất bại theo cách tương tự trong chế độ phát hành :. Debug.Assert không hữu dụng với tôi 97% thời gian
jk.

3% đó là gì vậy, @jk? Chỉ mã di sản, hoặc một số trường hợp khác?
DougM

@DougM hiệu suất mã quan trọng, nó là một tham chiếu đến trích dẫn knuth. Tôi cũng nói thêm rằng tôi nghĩ rằng lỗi nghiêm trọng chứng minh rằng quan điểm của tôi là chính xác, trừ khi bạn không có lựa chọn nào khác, đừng bỏ qua các kiểm tra điều kiện tiên quyết trong mã phát hành của bạn
jk.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.