2010-04-18 19 views
8

Tôi có khách sạn này:Tôi có thể định cấu hình NUnit để Debug.Fail không hiển thị hộp thông báo khi tôi chạy thử nghiệm của mình không?

public SubjectStatus Status 
    { 
     get { return status; } 
     set 
     { 
      if (Enum.IsDefined(typeof(SubjectStatus), value)) 
      { 
       status = value; 
      } 
      else 
      { 
       Debug.Fail("Error setting Subject.Status", "There is no SubjectStatus enum constant defined for that value."); 
       return; 
      } 
     } 
    } 

và kiểm tra đơn vị này

[Test] 
    public void StatusProperty_StatusAssignedValueWithoutEnumDefinition_StatusUnchanged() 
    { 
     Subject subject = new TestSubjectImp("1"); 

     // assigned by casting from an int to a defined value 
     subject.Status = (SubjectStatus)2; 
     Assert.AreEqual(SubjectStatus.Completed, subject.Status);    

     // assigned by casting from an int to an undefined value 
     subject.Status = (SubjectStatus)100; 
     // no change to previous value 
     Assert.AreEqual(SubjectStatus.Completed, subject.Status);    
    } 

Có cách nào tôi có thể ngăn chặn Debug.Fail hiển thị một hộp thông báo khi tôi chạy thử nghiệm của tôi, nhưng cho phép nó để hiển thị tôi khi tôi gỡ lỗi ứng dụng của mình?

+0

Tôi đã cập nhật câu trả lời của mình để chứa trình theo dõi trình lắng nghe theo dõi cho NUnit, nếu bạn quan tâm. –

+0

Tuyệt vời, chỉ là loại thông tin tôi đang tìm kiếm! – Grokodile

Trả lời

2

Cách chuẩn mà tôi đã luôn luôn làm điều này là để tạo ra một plugin cho NUnit. Plugin chỉ đơn giản là hủy đăng ký trình theo dõi mặc định và đăng ký một thay thế mà ném một ngoại lệ khi Assert/Trace.Fail được kích hoạt. Tôi thích cách tiếp cận này bởi vì các thử nghiệm sẽ vẫn thất bại nếu một chuyến đi khẳng định, bạn không nhận được bất kỳ hộp thông báo nào xuất hiện và bạn không phải sửa đổi mã sản xuất của mình.

Chỉnh sửa - đây là toàn bộ mã plugin. Bạn đang ở trên của riêng bạn để xây dựng các plugin thực tế mặc dù - kiểm tra các trang web NUnit :)

[NUnitAddin] 
public class NUnitAssertionHandler : IAddin 
{ 
    public bool Install(IExtensionHost host) 
    { 
     Debug.Listeners.Clear(); 
     Debug.Listeners.Add(new AssertFailTraceListener()); 
     return true; 
    } 

    private class AssertFailTraceListener : DefaultTraceListener 
    { 
     public override void Fail(string message, string detailMessage) 
     { 
      Assert.Fail("Assertion failure: " + message); 
     } 

     public override void Fail(string message) 
     { 
      Assert.Fail("Assertion failure: " + message); 
     } 
    } 
} 
+0

Nghe hay, có dễ viết một phích cắm NUnit không? – Grokodile

+0

Nó không quá tệ, có một vài điều bạn phải làm liên quan đến thiết lập các tập tin để sao chép local = false và một số quirks khác, nhưng tôi không có dự án ở phía trước của tôi ngay bây giờ vì vậy tôi không thể đăng chính xác các bước. Đó là nghĩa đen là một plugin .dll với một lớp trong nó, mặc dù :) –

0

Thay vì gọi Debug.Assert trực tiếp, bạn có thể gọi một phương thức trình bao bọc để kiểm tra xem trình gỡ rối có được đính kèm trước khi gọi Debug.Assert hay không. (Có lẽ, nó sẽ ném một ngoại lệ nếu không có chương trình gỡ rối kèm theo để kiểm tra của bạn sẽ thất bại.) Ví dụ .:

[Conditional("DEBUG")] 
public static void Assert(bool condition) 
{ 
    if (Debugger.IsAttached) 
    { 
     Debug.Assert(condition); 
    } 
    else 
    { 
     throw new SomeException(); 
    } 
} 
+0

Cảm ơn tôi sẽ tự viết cho mình một lớp bao bọc mà tôi có thể chuyển đổi, ý tưởng hay. – Grokodile

8

Một cách khác mà không yêu cầu thay đổi mã sản xuất của bạn hoặc viết một tùy chỉnh NUnit add-in, sẽ là để thay thế trình theo dõi trong một thiết lập.

Ví dụ: Thêm lớp sau vào trong không gian tên mà các bài kiểm tra của bạn có trong:

using System; 
using System.Diagnostics; 
using NUnit.Framework; 

[SetUpFixture] 
public class NUnitSetup 
{ 
    // Field to hold exisitng trace listeners so they can be restored after test are run. 
    private TraceListener[] originalListeners = null; 

    // A trace listener to use during testing. 
    private TraceListener nunitListener = new NUnitListener(); 

    [SetUp] 
    public void SetUp() 
    { 
     // Replace existing listeners with listener for testing. 
     this.originalListeners = new TraceListener[Trace.Listeners.Count]; 
     Trace.Listeners.CopyTo(this.originalListeners, 0); 
     Trace.Listeners.Clear(); 
     Trace.Listeners.Add(this.nunitListener); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     // Restore original trace listeners. 
     Trace.Listeners.Remove(this.nunitListener); 
     Trace.Listeners.AddRange(this.originalListeners); 
    } 

    public class NUnitListener : DefaultTraceListener 
    { 
     public override void Fail(string message) 
     { 
      Console.WriteLine("Ignoring Debug.Fail(\"{0}\")", message); 
     } 

     public override void Fail(string message, string detailMessage) 
     { 
      Console.WriteLine("Ignoring Debug.Fail(\"{0},{1}\")", message, detailMessage); 
     } 
    } 
} 
+1

Bạn thậm chí không cần một trình theo dõi tùy chỉnh, chỉ cần cài đặt ConsoleTraceListener. Sau đó tất cả các tin nhắn Debug.Assert/Fail của bạn đi đến tab đầu ra văn bản NUnit, mà không ảnh hưởng đến các bài kiểm tra khác. – yoyo

+0

Cập nhật cho NUnit 3.0: [SetupFixture] xung đột với [SetUp] và [TearDown]. Nhưng điều đó không sao - chỉ cần chèn cả lớp, không có [SetUpFixture] ban đầu, bên trong TextFixture của bạn. Tốt hơn, hãy thay đổi [Thiết lập] thành [OneTimeSetUp] (tương tự như vậy cho TearDown) và nó sẽ chỉ thực hiện thay thế một lần! Điều này hoạt động thực sự ngọt ngào! – shipr

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