2008-10-03 7 views
6

меня попросили написать тестовую программу, которая должна проверить новую хранимую процедуру на несколько строк в базе данных, в сущности, я хочу сделать что-то вроде этого:NUnit: Выполнение нескольких утверждения в одном тесте

 

[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"]); 
    } 
} 
 

Когда я запускаю этот тест, если 1 строка не соответствует другой, весь тест завершается с ошибкой; вместо этого я хотел бы подсчитать, сколько раз было принято это утверждение и сколько раз оно провалилось. Есть ли способ сделать это с помощью NUnit?

Я понимаю, что NUnit может быть излишним, и это простая задача без него ... Я просто хотел изучить его. ;)

ответ

5

1) Если идентификаторы являются постоянными и не смотрел на время выполнения тестового , создайте отдельное тестовое устройство для каждого идентификатора. Таким образом, вы узнаете, какие идентификаторы на самом деле не работают. Смотрите здесь для записи до о проблемах с данными ведомых испытаний:
http://googletesting.blogspot.com/2008/09/tott-data-driven-traps.html

2) Если вам нужно динамически искать идентификатор делает невозможным создать приспособление для каждого идентификатора, предложение использовать akmad с одним изменением. Сохраните список идентификаторов, где значения не равны, и добавьте список в сообщение об ошибке. Было бы очень сложно диагностировать неудачный тест, в котором указывается только количество ошибок, так как вы не будете знать, какие ошибки вызывают ошибки.

3) Я не знаю, как это было бы трудно сделать в NUnit, но в PyUnit, когда нам нужно запускать тесты с динамически генерируемыми данными, мы динамически создаем тесты и присоединяем их к классу TestCase, чтобы у нас есть неудачный тест для каждой части данных, которая не проходит. Хотя я думаю, что это было бы намного сложнее без динамических возможностей python.

+0

Спасибо, что я действительно искал, был вашим # 3 ... но, как вы сказали ... это .net :( – mmattax 2008-10-03 21:04:46

0

Ну вы могли бы объявить счетчик, а затем утверждать значение счетчика, чтобы определить, годен/не годен

Кроме того, вы можете сделать большую часть работы в испытательной установке, а затем просто создать несколько тестов ,

Я не знаю, почему вам нужны все утверждения stmts в одном тесте.

+0

Я хочу утверждать, что хранимая процедура работает для каждой строки в базе данных. – mmattax 2008-10-03 16:03:01

1

Я бы подсчитал количество строк, которые не совпадают, и затем напишет утверждение, которое будет сравнивать это число с 0 и вернет количество несоответствующих строк в сообщении.

Вы также можете использовать Assert.Greater для этого.

P.S. В принципе вы должны попытаться сделать одно утверждение на единичный тест. В этом суть.

9

Похоже, вы просто утверждаете не то. Если вы хотите, чтобы проверить все значения, а затем утверждать, что нет никаких ошибок (или показать количество ошибок), то попробуйте следующее:

[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

На основании поставленной цели весь тест должен сбой, если одна строка не соответствует другой. Подсчитывая количество раз, когда утверждение проходит или терпит неудачу, вы получаете меньше информации, чем сравнение ожидаемого результата с результатом, который вы действительно получили.

4

Я знаю, что речь идет конкретно о NUnit, но интересно, Gallio/MbUnit имеет функцию, которая позволяет запускать и захватывать сразу несколько утверждений.

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

The Assert.Multiple догоняет все неисправного утверждений и собирается сообщать о них в конце испытания.

0

У меня недавно была та же проблема. Я объединил идею подсчета ошибок с упоминанием Yann Тревин о Assert.Multiple в метод расширения для IEnumberable, что позволяет мне делать такие вещи, как:

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

что приводит к выходу 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 

И решение проблемы в ФП был бы:

[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"]); 
} 

Вот метод расширения (обратите внимание, что я использовал «All» вместо «Multiple» для согласования с терминологией 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); 
      } 
     } 
    } 
}