Pregunta

Tengo una clase que procesa 2 archivos xml y produce un archivo de texto.

Me gustaría escribir un montón de pruebas de unidad / integración que pueden pasar o fallar individualmente para esta clase que hace lo siguiente:

  1. Para las entradas A y B, genere la salida.
  2. Compare el contenido del archivo generado con la salida esperada del contenido
  3. Cuando el contenido real difiere del contenido esperado, falla y muestra información útil sobre las diferencias.

A continuación se muestra el prototipo para la clase junto con mi primera puñalada en las pruebas unitarias.

¿Debo utilizar un patrón para este tipo de prueba o la gente suele escribir miles de funciones de TestX ()?

¿Hay una mejor manera de convencer a las diferencias de archivos de texto de NUnit? ¿Debo insertar un algoritmo de diferencia de archivos de texto?


class ReportGenerator
{
    string Generate(string inputPathA, string inputPathB)
    {
        //do stuff
    }
}

[TextFixture]
public class ReportGeneratorTests
{
     static Diff(string pathToExpectedResult, string pathToActualResult)
     {
         using (StreamReader rs1 = File.OpenText(pathToExpectedResult))
         {
             using (StreamReader rs2 = File.OpenText(pathToActualResult))
             {
                 string actualContents = rs2.ReadToEnd();
                 string expectedContents = rs1.ReadToEnd();                  

                 //this works, but the output could be a LOT more useful.
                 Assert.AreEqual(expectedContents, actualContents);
             }
         }
     }

     static TestGenerate(string pathToInputA, string pathToInputB, string pathToExpectedResult)
     {
          ReportGenerator obj = new ReportGenerator();
          string pathToResult = obj.Generate(pathToInputA, pathToInputB);
          Diff(pathToExpectedResult, pathToResult);
     }

     [Test]
     public void TestX()
     {
          TestGenerate("x1.xml", "x2.xml", "x-expected.txt");
     }

     [Test]
     public void TestY()
     {
          TestGenerate("y1.xml", "y2.xml", "y-expected.txt");
     }

     //etc...
}

Actualizar

No estoy interesado en probar la funcionalidad diff. Solo quiero usarlo para producir errores más legibles.

¿Fue útil?

Solución

En cuanto a las pruebas múltiples con datos diferentes, use la extensión NUnit RowTest:

using NUnit.Framework.Extensions;

[RowTest]
[Row("x1.xml", "x2.xml", "x-expected.xml")]
[Row("y1.xml", "y2.xml", "y-expected.xml")]
public void TestGenerate(string pathToInputA, string pathToInputB, string pathToExpectedResult)
 {
      ReportGenerator obj = new ReportGenerator();
      string pathToResult = obj.Generate(pathToInputA, pathToInputB);
      Diff(pathToExpectedResult, pathToResult);
 }

Otros consejos

Probablemente estés solicitando la prueba contra " oro " datos. No sé si hay un término específico para este tipo de pruebas aceptadas en todo el mundo, pero así es como lo hacemos.

Crea una clase de base. Básicamente, tiene "void DoTest (string fileName) " ;, que leerá un archivo específico en la memoria, ejecutará el método de transformación abstracta" string Transform (cadena de texto) ", luego leerá FileName.gold desde el mismo lugar y comparará el texto transformado Con lo que se esperaba. Si el contenido es diferente, arroja una excepción. La excepción lanzada contiene el número de línea de la primera diferencia, así como el texto de la línea esperada y real. Como el texto es estable, generalmente es suficiente información para detectar el problema de inmediato. Asegúrate de marcar las líneas con " Esperado: " y " Actual: " ;, o estará adivinando para siempre cuál es cuál cuando mira los resultados de las pruebas.

Luego, tendrá dispositivos de prueba específicos, donde implementará el método Transform que hace el trabajo correcto, y luego tendrá pruebas que se parecen a esto:

[Test] public void TestX() { DoTest("X"); }
[Test] public void TestY() { DoTest("Y"); }

El nombre de la prueba fallida le dirá instantáneamente lo que está roto. Por supuesto, puede usar la prueba de fila para agrupar pruebas similares. Tener pruebas separadas también ayuda en una serie de situaciones como ignorar pruebas, comunicar pruebas a colegas, etc. No es una gran cosa crear un fragmento que creará una prueba para usted en un segundo, dedicará mucho más tiempo a preparar los datos.

Luego, también necesitarás algunos datos de prueba y una forma en que tu dispositivo base lo encuentre, asegúrate de establecer reglas al respecto para el proyecto. Si la prueba falla, descargue la salida real al archivo cerca del dorado y bórrela si pasa la prueba. De esta manera puede utilizar la herramienta de diferencias cuando sea necesario. Cuando no se encuentran datos de oro, la prueba falla con el mensaje apropiado, pero la salida real se escribe de todos modos, por lo que puede verificar que sea correcto y copiarlo para que se convierta en " oro " ;.

Probablemente escribiría una prueba de una sola unidad que contenga un bucle. Dentro del bucle, leí 2 archivos xml y un archivo diff, y luego difumino los archivos xml (sin escribirlo en el disco) y lo comparé con el archivo diff leído del disco. Los archivos estarían numerados, por ejemplo. a1.xml, b1.xml, diff1.txt; a2.xml, b2.xml, diff2.txt; a3.xml, b3.xml, diff3.txt, etc., y el bucle se detiene cuando no encuentra el siguiente número.

Luego, puedes escribir nuevas pruebas simplemente agregando nuevos archivos de texto.

En lugar de llamar a .AreEqual, usted podría analizar las dos secuencias de entrada usted mismo, mantener un recuento de líneas y columnas y comparar los contenidos. Tan pronto como encuentre una diferencia, puede generar un mensaje como ...

  

Línea 32 Columna 12: se encontró 'x' cuando se esperaba 'y'

Opcionalmente, puede mejorar eso mostrando múltiples líneas de salida

  

Diferencia en la línea 32 Columna 12, primera diferencia mostrada
  A = esto es un t x st
  B = esto es un t e pts

Tenga en cuenta que, como regla, generalmente solo generaría a través de mi código una de las dos secuencias que tiene. ¡El otro tomaría de un archivo de prueba / texto, verificando a simple vista u otro método que los datos contenidos son correctos!

Probablemente usaría XmlReader para recorrer los archivos y compararlos. Cuando llego a una diferencia, mostraría un XPath a la ubicación donde los archivos son diferentes.

PS: Pero en realidad siempre fue suficiente para mí simplemente hacer una simple lectura de todo el archivo a una cadena y comparar las dos cadenas. Para el reporte es suficiente ver que la prueba falló. Luego, cuando hago la depuración, generalmente difiero los archivos utilizando Merge Araxis para ver exactamente dónde Tengo problemas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top