2013-12-16 23 views
32

Khi nào tôi nên debug.assert qua hợp đồng mã hoặc ngược lại? Tôi muốn kiểm tra điều kiện tiên quyết cho một phương pháp và tôi đang bối rối để chọn một cái khác. Tôi có các bài kiểm tra đơn vị mà tôi muốn kiểm tra các tình huống thất bại và mong đợi các ngoại lệ.Debug.Assert vs Code Hợp đồng sử dụng

Thực tiễn tốt là sử dụng Debug.Assert và hợp đồng Mã trên cùng một phương pháp. Nếu vậy thì thứ tự trong đó mã sẽ được viết là gì?

Debug.Assert(parameter!= null); 
Contract.Requires<ArgumentNullException>(parameter != null, "parameter"); 

hoặc

Contract.Requires<ArgumentNullException>(parameter != null, "parameter"); 
Debug.Assert(parameter!= null); 

Có bất kỳ lý do đằng sau nó?

Trả lời

28

Đây là những thứ khác nhau. Một xác nhận gỡ lỗi chỉ được thực hiện khi mã được biên dịch như là gỡ lỗi và do đó sẽ chỉ kiểm tra/xác nhận dưới gỡ lỗi. Ý tưởng là sử dụng điều này cho "kiểm tra sanity" cho mã bạn đang phát triển. Các hợp đồng mã có thể được sử dụng trong việc gỡ rối hoặc phát hành. Họ đảm bảo rằng trước và sau điều kiện của phương pháp thực hiện theo sự mong đợi của phương pháp (đáp ứng các hợp đồng). Ngoài ra còn có một khung kiểm tra cung cấp chức năng tương tự, được thiết kế để kiểm tra sự tuân thủ kiểm tra.

Sử dụng Debug.Assert khi bạn muốn đảm bảo rằng một số thứ nhất định như bạn mong đợi khi phát triển mã (và trong quá trình phát triển bảo trì sau này).

Sử dụng hợp đồng mã khi bạn muốn đảm bảo rằng các điều kiện là đúng trong cả gỡ lỗi và phát hành. Các hợp đồng cũng cho phép một số dạng phân tích tĩnh nhất định có thể hữu ích trong việc xác minh rằng chương trình của bạn là "đúng".

Sử dụng xác nhận khung kiểm tra khi tạo kiểm tra đơn vị.

+0

Tôi hoàn toàn đồng ý, nhưng nếu tôi chọn sử dụng debug.assert và hợp đồng mã trên cùng một vị trí thì nó sẽ theo thứ tự nhất định? – CarbineCoder

+0

Không chắc chắn lý do tại sao bạn sẽ làm một kiểm tra đôi theo cách đó. Đặt hàng không nên theo cách. Nếu tôi đã làm điều đó tôi tin rằng tôi muốn đặt Debug.Assert đầu tiên như là một trợ giúp gỡ lỗi phát triển. – Dweeberly

+0

Debug.Assert sẽ không có trong Mã phát hành, nhưng hợp đồng mã sẽ. Vì vậy, tôi cảm thấy có những trường hợp debug.assert sẽ được cần thiết song song với các hợp đồng Code- tôi có thể sai. Do đó câu hỏi. – CarbineCoder

22

Cá nhân, tôi sẽ không sử dụng cả hai Debug.Assert VÀ Hợp đồng mã để thực thi điều kiện tiên quyết trong mã mới được viết - Hợp đồng mã IMO supercede Debug.Assert, vì chúng cung cấp một bộ kiểm tra toàn diện hơn, chưa kể đến lợi ích có thể thu được từ kiểm tra tĩnh có thể được thực hiện trước khi mã được chạy thời gian. Việc duy trì kiểm tra điều kiện trùng lặp trùng lặp trong cả hai số Debug.AssertContracts sẽ rất cồng kềnh.

Lý do:

  • Bạn không cần phải tái mã bất kỳ điều kiện tiên quyết di sản bạn có thể đã được mã hóa trong Debug.Assert hoặc throw mã - bạn có thể giữ mã kiểm tra điều kiện tiên quyết hiện hành và terminate it with Contract.EndContractBlock()
  • Bạn có thể nhận được cùng một hành vi 'chế độ phát hành' không được kiểm tra khi System.Diagnostics.Debug được tạo mà không cần /d:DEBUG nếu bạn xây dựng với kiểm tra thời gian chạy hợp đồng được đặt thành None. Ref 6.2.1 in the Docs
  • Hợp đồng cho phép người sáng tạo hiểu rõ hơn về mã là 'lý do' trạng thái không hợp lệ đã được phát hiện - ví dụ: trực tiếp là do tham số ngoài băng tần (Contract.Requires). Nếu không, Contract.Assert hoặc Contract.Assume có thể kiểm tra trạng thái chung và "trạng thái được đảm bảo" của trạng thái khi có phương pháp có thể được biểu thị bằng cách sử dụng Contract.Ensures. Và Invariants thể hiện rằng nhà nước phải được tổ chức mọi lúc. Và tốt nhất là kiểm tra tĩnh có thể thực thi các Hợp đồng này khi bạn xây dựng mã của bạn - theo cách này bạn có cơ hội nhận lỗi thông qua thời gian thiết kế hoặc cảnh báo thời gian biên dịch thay vì phải đợi thời gian chạy. Quay lại đầu trangKiểm tra hợp đồng có thể được thêm vào tích hợp liên tục của bạn để tìm kiếm sự không tuân thủ.

Một caveat: Nếu bạn đang đi để viết đơn vị xét nghiệm mà cố tình vi phạm hợp đồng, bạn có thể cần để đối phó với ContractException - Jon Skeet giải thích tốt này here. ví dụ. Kết nối một số Contract.ContractFailed handler trong thiết lập thử nghiệm của bạn với một trình xử lý gọi số SetHandled và sau đó ném ngoại lệ công khai mà bạn có thể nắm bắt và xác nhận trong UT của mình.

+2

Giải thích hay. Giờ thì tôi đã hiểu. Nếu được sử dụng nhất quán, nó mang lại sự rõ ràng cho những gì nhà phát triển giả định về trạng thái của ứng dụng trên đường đi. Và đó chỉ là đóng băng trên bánh, bánh là các thói quen xử lý ngoại lệ chi tiết và đầy đủ hơn, dễ dàng đặt ngay từ đầu. – jeremcc

+0

Chỉ khi có một cài đặt cấu hình toàn bộ giải pháp để đảm bảo 'Contract.Assert's không kết thúc trong bản dựng Xây dựng, tôi sẽ sử dụng chúng. Nếu không, tôi sử dụng 'Debug.Assert' bởi vì tôi biết họ sẽ không bao giờ bị rò rỉ vào bản phát hành Release. Bảo trì cấu hình của các Hợp đồng Mã là IMO hạn chế lớn nhất của nó. – orad

+0

Thêm vào nhận xét trước của tôi, về các điều kiện trước và sau điều kiện trên các giao diện công cộng Tôi thấy lý do tại sao chúng tôi muốn đưa chúng vào chế độ phát hành để sử dụng mã người tiêu dùng. Nhưng tôi không thấy lý do nào tại sao chúng tôi muốn bao gồm các xác nhận trong chế độ phát hành trong mọi trường hợp. Tôi có thể không được thông báo đủ về điều đó. – orad

Các vấn đề liên quan