2008-10-03 14 views
6

Se me ha pedido que escriba una aplicación de prueba que necesita para probar un nuevo procedimiento almacenado en múltiples filas en una base de datos, en esencia, lo que quiero hacer algo como esto:NUnit: La ejecución de varias afirmaciones en una sola prueba

 

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

Cuando ejecuto esta prueba, si 1 fila no coincide con la otra, la prueba completa falla; en cambio, me gustaría contar cuántas veces se aprobó la afirmación y cuántas veces ha fallado. ¿Hay alguna manera de hacer esto con NUnit?

Me doy cuenta de que NUnit puede ser excesivo y esta es una tarea sencilla sin él ... Solo quería aprenderlo. ;)

Respuesta

5

1) Si los identificadores son constantes y no levantó la vista en tiempo de ejecución de pruebas , crea un accesorio de prueba unitaria por separado para cada identificación. De esta forma sabrá qué identificadores están fallando realmente. Vea aquí un escribir sobre los problemas con los datos de las pruebas conducidas:
http://googletesting.blogspot.com/2008/09/tott-data-driven-traps.html

2) Si es necesario mirar dinámicamente de la Identificación por lo que es imposible crear un accesorio para cada ID, sugerencia uso de Akmad con un cambio. Guarde una lista de identificadores donde los valores no son iguales y agregue la lista al mensaje de error. Será extremadamente difícil diagnosticar una prueba fallida que solo indique el número de errores, ya que no sabrá qué ID causa los errores.

3) No sé lo difícil que sería hacer en NUnit, pero en PyUnit, cuando necesitamos ejecutar pruebas en datos generados dinámicamente, creamos dinámicamente los dispositivos de prueba y los conectamos a la clase TestCase para que tenemos una prueba fallida para cada pieza de datos que no pasa. Aunque imagino que esto sería mucho más difícil sin las habilidades dinámicas de Python.

+0

Gracias, lo que realmente estaba buscando era tu # 3 ... pero como dijiste ... esto es .net :( – mmattax

0

Bien se podría declarar un mostrador y luego afirmar el valor del contador para determinar pasa/no pasa

Además, se puede hacer la mayor parte del trabajo en la configuración de la prueba, y luego simplemente crear varias pruebas .

No tengo claro por qué necesita todas las afirmaciones en la misma prueba.

+0

Quiero afirmar que el procedimiento almacenado funciona para cada fila en la base de datos. – mmattax

1

Yo contaría el número de filas que no coinciden y luego escribiría una afirmación que comparará este número con 0 y devolvería el número de cadenas que no coinciden en el mensaje.

También podría usar Assert.Greater para esto.

P.S. En principio, debe intentar hacer una afirmación por prueba unitaria. Esa es la esencia de eso.

9

Parece que usted está simplemente afirmando algo equivocado. Si desea comprobar todos los valores y luego afirmar que no hay errores (o mostrar el número de errores) a continuación, intente esto:

[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

Según el objetivo que ha establecido, la prueba completa debe fallar si una fila no coincide con otra. Contar el número de veces que una aseveración pasa o falla le da menos información que una comparación del resultado esperado con el resultado que realmente recibió.

4

Sé que la pregunta es específicamente sobre NUnit, pero curiosamente, Gallio/MbUnit tiene una característica que permite ejecutar y atrapar varias afirmaciones a la vez.

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

El Assert.Multiple es la captura de todos los las afirmaciones que fallan y se va a informar de ellos al final de la prueba.

0

Recientemente tuve el mismo problema. Combiné la idea de contar con errores mención Assert.Multiple de Yann Trevin en un método de extensión para IEnumberable que me permite hacer cosas como:

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

lo que resulta en la salida 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 

Y la solución al problema de la OP sería:

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

Aquí es el método de extensión (tenga en cuenta que he utilizado "todos" en lugar de "múltiple" para mantener la coherencia con la terminología 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); 
      } 
     } 
    } 
} 
Cuestiones relacionadas