2008-10-03 23 views
6

Tôi đã được yêu cầu viết một ứng dụng thử nghiệm cần thử nghiệm một quy trình mới được lưu trữ trên nhiều hàng trong cơ sở dữ liệu, về bản chất tôi muốn làm như sau:NUnit: Chạy nhiều xác nhận trong một thử nghiệm duy nhất

 

[Test] 
public void TestSelect() 
{ 
    foreach(id in ids) 
    { 
     DataTable old = Database.call("old_stored_proc",id); 
     DataTable new_ = Database.call("new_stored_proc",id); 

     Assert.AreEqual(old.Rows[0]["column"],ne_.Rows[0]["column"]); 
    } 
} 
 

Khi tôi chạy thử nghiệm này, nếu 1 hàng không khớp với nhau, toàn bộ thử nghiệm không thành công; thay vào đó tôi muốn đếm số lần xác nhận đã được thông qua và bao nhiêu lần nó đã thất bại. Có cách nào để làm điều này với NUnit?

Tôi nhận ra rằng NUnit có thể quá mức cần thiết và đây là một nhiệm vụ đơn giản mà không có nó ... Tôi chỉ muốn học nó. ;)

Trả lời

5

1) Nếu id không đổi và không được tra cứu tại thời gian chạy thử , tạo một đơn vị thử nghiệm riêng biệt cho từng id. Bằng cách đó bạn sẽ biết id nào đang thực sự thất bại. Xem ở đây cho một ghi lên trên những vấn đề với dữ liệu kiểm tra lái xe:
http://googletesting.blogspot.com/2008/09/tott-data-driven-traps.html

2) Nếu bạn cần phải tự động tìm kiếm của id làm cho nó không thể tạo ra một vật cố cho từng id, đề nghị sử dụng akmad với một sự thay đổi. Giữ một danh sách các id nơi các giá trị không bằng nhau và thêm danh sách vào thông báo lỗi. Nó sẽ vô cùng khó khăn để chẩn đoán một bài kiểm tra thất bại mà chỉ nói số lỗi, vì bạn sẽ không biết id nào gây ra lỗi.

3) Tôi không biết nó sẽ khó khăn như thế nào trong NUnit, nhưng trong PyUnit, khi chúng ta cần chạy thử nghiệm trên dữ liệu được tạo động, chúng ta sẽ tự động tạo các thử nghiệm và đính kèm chúng vào lớp TestCase để chúng tôi có kiểm tra không thành công cho từng phần dữ liệu không vượt qua. Mặc dù tôi tưởng tượng điều này sẽ khó khăn hơn nhiều nếu không có khả năng năng động của python.

+0

Cảm ơn, những gì tôi thực sự đang tìm kiếm là # 3 của bạn ... nhưng như bạn đã nói ... đây là .net :( – mmattax

0

Vâng, bạn có thể tuyên bố một bộ đếm và sau đó khẳng định giá trị của bộ đếm để xác định đạt/không đạt

Ngoài ra, bạn có thể làm phần lớn công việc trong thiết lập kiểm tra, và sau đó chỉ cần tạo nhiều bài kiểm tra .

Tôi không rõ ràng tại sao bạn cần tất cả các xác nhận xác nhận trong cùng một thử nghiệm.

+0

Tôi muốn khẳng định rằng quy trình được lưu trữ đang hoạt động với mọi hàng trong cơ sở dữ liệu. – mmattax

1

Tôi sẽ đếm số hàng không khớp và sau đó viết một xác nhận sẽ so sánh số này với 0 và sẽ trả lại số chuỗi không khớp trong thư.

bạn cũng có thể sử dụng Assert.Greater cho việc này.

P.S. Trong chính bạn nên cố gắng làm một khẳng định cho mỗi bài kiểm tra đơn vị. Đó là ý chính của nó.

9

Dường như bạn chỉ đang khẳng định điều sai. Nếu bạn muốn kiểm tra tất cả các giá trị và sau đó xác nhận rằng không có lỗi nào (hoặc hiển thị số lỗi) thì hãy thử điều này:

[Test] 
public void TestSelect() 
{ 
    int errors = 0; 
    foreach(id in ids) 
    { 
     DataTable old = Database.call("old_stored_proc",id); 
     DataTable new_ = Database.call("new_stored_proc",id); 

     if (old.Rows[0]["column"] != new_.Rows[0]["column"]) 
     { 
      errors++; 
     }    
    } 

    Assert.AreEqual(0, errors, "There were " + errors + " errors."); 
} 
0

Dựa trên mục tiêu bạn đặt ra, toàn bộ thử nghiệm nên không thành công nếu một hàng không khớp với nhau. Đếm số lần xác nhận vượt qua hoặc thất bại cung cấp cho bạn ít thông tin hơn so với so sánh kết quả bạn mong đợi với kết quả bạn thực sự có.

4

Tôi biết rằng câu hỏi cụ thể về NUnit, nhưng thú vị đủ, Gallio/MbUnit có một tính năng cho phép chạy và nắm bắt nhiều xác nhận cùng một lúc.

[Test] 
public void MultipleTest() 
{ 
    Assert.Multiple(() => 
    { 
     Assert.IsTrue(blabla); 
     Assert.AreEqual(pik, pok); 
     // etc. 
    } 
} 

Các Assert.Multiple đang bắt tất cả các khẳng định thất bại và sẽ báo cáo vào cuối của thử nghiệm.

0

Gần đây tôi có cùng một vấn đề. Tôi kết hợp các ý tưởng về đếm lỗi với đề cập đến Assert.Multiple Yann Trevin của thành một phương pháp mở rộng cho IEnumberable cho phép tôi làm những việc như:

[Test] 
public void TestEvenNumbers() 
{ 
    int[] numbers = new int[] { 2, 4, 12, 22, 13, 42 }; 
    numbers.AssertAll((num) => Assert.That((num % 2) == 0, "{0} is an odd number", num)); 
} 

nào dẫn đến sản lượng NUnit:

TestEvenNumbers: 
    5 of 6 tests passed; 0 inconclusive 
FAILED: 13: 13 is an odd number 
    Expected: True 
    But was: False 

    Expected: 6 
    But was: 5 

Và giải pháp cho vấn đề của OP sẽ là:

[Test] 
public void TestSelect() 
{ 
    ids.AssertAll(CheckStoredProcedures); 
} 

private void CheckStoredProcedures(Id id) 
{ 
    DataTable old = Database.call("old_stored_proc",id); 
    DataTable new_ = Database.call("new_stored_proc",id); 

    Assert.AreEqual(old.Rows[0]["column"], new_.Rows[0]["column"]); 
} 

Đây là phương pháp mở rộng (lưu ý rằng tôi đã sử dụng "Tất cả" thay vì "Nhiều" để nhất quán với thuật ngữ LINQ):

using System; 
using System.Text; 
using System.Collections.Generic; 
using NUnit.Framework; 

public static class NUnitExtensions 
{ 
    public static void AssertAll<T>(this IEnumerable<T> objects, Action<T> test) 
    { 
     int total = 0; 
     int passed = 0; 
     int failed = 0; 
     int inconclusive = 0; 
     var sb = new StringBuilder(); 
     foreach (var obj in objects) 
     { 
      total++; 
      try 
      { 
       test(obj); 
       passed++; 
      } 
      catch (InconclusiveException assertion) 
      { 
       inconclusive++; 
       string message = string.Format("INCONCLUSIVE: {0}: {1}", obj.ToString(), assertion.Message); 
       Console.WriteLine(message); 
       sb.AppendLine(message); 
      } 
      catch (AssertionException assertion) 
      { 
       failed++; 
       string message = string.Format("FAILED: {0}: {1}", obj.ToString(), assertion.Message); 
       Console.WriteLine(message); 
       sb.AppendLine(message); 
      } 
     } 

     if (passed != total) 
     { 
      string details = sb.ToString(); 
      string message = string.Format("{0} of {1} tests passed; {2} inconclusive\n{3}", passed, total, inconclusive, details); 
      if (failed == 0) 
      { 
       Assert.Inconclusive(message); 
      } 
      else 
      { 
       Assert.AreEqual(total, passed, message); 
      } 
     } 
    } 
} 
Các vấn đề liên quan