2010-12-07 17 views
8

Estoy escribiendo algunas pruebas de unidad para la capa de persistencia de mi aplicación C# .NET. Antes y después de que se ejecuten las pruebas de una clase de prueba, quiero hacer algo de limpieza para borrar los valores ficticios posiblemente insertados, por lo tanto, esta limpieza ocurre en los métodos marcados con los atributos [ClassInitialize()] y [ClassCleanup()].Cómo escribir la salida en [ClassInitialize()] de una clase Unit Test?

(Sé que una mejor manera sería utilizar una base de datos en memoria, pero no es realmente factible la medida en que dependemos de una gran cantidad de procedimientos almacenados ....)

lo haría al igual que a mostrado información sobre los resultados de la limpieza hasta, pero no puedo encontrar una manera de obtener la salida de los resultados de las pruebas con Visual Studio 2010.

Esto es lo que estoy haciendo hasta ahora:

 ///... lots of stuff before ... 

     //global for the test run 
     private static TestContext context; 

     //for each test 
     private IRepository repo; 

     #region Initialisation and cleanup 

     /// <summary> 
     /// Execute once before the test-suite 
     /// </summary> 
     [ClassInitialize()] 
     public static void InitTestSuite(TestContext testContext) 
     { 
      context = testContext;  
      removeTestDataFromDb();  
     } 

     [ClassCleanup()] 
     public static void CleanupTestSuite() 
     { 
      removeTestDataFromDb(); 
     } 

     private static void removeTestDataFromDb() 
     { 
      context.WriteLine("removeTestDataFromDb starting"); 
      using (ISession session = NHibernateHelper.OpenSession()) 
      {  
       IDbConnection cn = session.Connection; 
       IDbCommand cmd = cn.CreateCommand(); 
       //remove anyt test data 
       cmd.CommandText = @"DELETE FROM SomeTable 
        WHERE somefield LIKE 'easyToFindTestData%Test'"; 
       int res = cmd.ExecuteNonQuery();  
       context.WriteLine("removeTestDataFromDb done - affected {0} rows", res); 
      } 
     } 


     [TestInitialize()] 
     public void InitTest() 
     { 
      repo = new MyRepositoryImplementation(); 
     } 

     [TestCleanup()] 
     public void CleanupTest() 
     { 
      //cleanup  
      repo = null; 
     } 

     #endregion 

estoy tratando de utilizar context.WriteLine() ...

que también trató simplemente usando Console.WriteLine() con los mismos resultados.

¿Cómo se escribe en la salida estándar en la parte ClassInitialize y dónde se puede acceder a esa salida?

Respuesta

12

El [ClassInitialize] y [ClassCleanup] se ejecutan solo una vez para todas las pruebas de esa clase. Sería mejor utilizar [TestInitialize] y [TestCleanUp] que se ejecutan antes y después de cada prueba. También trate de envolver la prueba completa en una transacción de base de datos. De esta forma, simplemente puede deshacer la operación (no comprometiendo la transacción) y su base de datos permanece en un estado constante (que es esencial para las pruebas automatizadas confiables).

Un truco que hago para las pruebas de integración es definir una clase base de la que todas mis clases de prueba de integración puedan heredar. La clase base garantiza que cada prueba se ejecute en una transacción y que esta transacción se retrotraiga. Aquí está el código:

public abstract class IntegrationTestBase 
{ 
    private TransactionScope scope; 

    [TestInitialize] 
    public void TestInitialize() 
    { 
     scope = new TransactionScope(); 
    } 

    [TestCleanup] 
    public void TestCleanup() 
    { 
     scope.Dispose(); 
    } 
} 

Buena suerte.

+0

Gracias por su consejo Steven, pero en realidad prefieren realice la limpieza solo una vez por clase, en realidad. Y como estoy usando NHibernate, no estoy muy seguro sobre el uso de TransactionScope ... Sin embargo, lo echaré un vistazo. De todos modos, esto realmente no responde mi pregunta acerca de cómo escribir en la salida :-) – tsimbalar

+1

No limpiar una vez por clase. Las pruebas deben ejecutarse de forma aislada, y cuando no se limpian los datos de prueba por prueba, la prueba depende uno del otro, lo que los hace poco confiables. Cuando deja de confiar en sus pruebas, se vuelven inútiles. por cierto. 'TransactionScope' funciona bien con NHibernate, porque NHibernate solo usa conexiones estándar ADO.NET. Además, cuando escribe en la consola en [TestCleanup] no tendrá este problema, pero por favor no escriba en la consola, simplemente revertir. – Steven

+0

Gracias, no sabía de TransactionScope ... ¡parece exactamente lo que necesito! No estoy seguro de entender lo que sucede debajo del capó, sin embargo ... Confía en MSDTC por lo que puedo ver ... ¡Gracias de nuevo! – tsimbalar

0

Puede ver la salida de la consola en cada prueba si hace doble clic en el método de prueba en el panel Resultados de la prueba. También está presente en el archivo de resultados .trx xml.

Además, si se especifica la opción "Definir constante DEBUG", se puede utilizar el System.Diagnostics.Debug.WriteLine("ClassInitialize Method invoked, yeah."); .. que terminará en el panel de "Salida".

+0

Los métodos ClassInitialize y ClassCleanup no se envían al resultado de pruebas individuales. Sin embargo, puede ver TestInitialize y TestCleanup en su salida. Además, no puedo encontrar los archivos .trx generados por Visual Studio en ninguna parte y tengo que ver la manera de hacerlos generar esos archivos. Sin embargo, una vez que lo haga, debería poder cargarlos en la ventana Resultados de la prueba de la que @ hjb417 estaba hablando. –

1

La salida de rastreo de ClassInitialize y ClassCleanup aparece en el resumen de resultados.

Puede acceder a ella de la siguiente manera

  1. Abrir los resultados de la prueba windw [Test -> Windows -> Resultados de la prueba]
  2. Debe haber un vínculo nombrado "Marcha de prueba completado" en la parte superior esquina izquierda de la ventana [Resultados de la prueba].
  3. Haga clic en el tintineo
  4. Se debe abrir una ventana con el título "Resumen Resultado" y se mostrará el seguimiento de depuración creado durante ClassInitialize y ClassCleanup
Cuestiones relacionadas