2008-10-10 19 views
9

Estoy usando MSTEST en Visual Studio 2008. ¿Cómo puedo hacer que cada método de prueba de una determinada clase de prueba actúe como si fuera la primera prueba que se ejecuta para que se restablezca todo el estado global antes de ejecutar cada prueba? No quiero para limpiar de manera explícita el mundo a través de TestInitialize, ClassInitialize, AssemblyInitialize, etc. Por ejemplo:¿Cómo forzar a MSTEST TestMethod a restablecer todos los singleton/estáticos antes de ejecutar?

[TestClass] 
public class MyClassTests 
{ 
    [TestMethod] 
    public void Test1() 
    { 
     // The "Instance" property creates a new instance of "SomeSingleton" 
     // if it hasn't been created before. 
     var i1 = SomeSingleton.Instance; 
     ... 
    } 
    [TestMethod] 
    public void Test2() 
    { 
     // When I select "Test1" and "Test2" to run, I'd like Test2 
     // to have a new AppDomain feel so that the static variable inside 
     // of "SomeSingleton" is reset (it was previously set in Test1) on 
     // the call to ".Instance" 
     var i2 = SomeSingleton.Instance; 
     // some code 
    } 

Aunque un similar question apareció sobre este tema, sólo se aclaró que las pruebas no se ejecutan en paralelo. Me doy cuenta de que las pruebas se ejecutan en serie, pero no parece haber una manera de forzar explícitamente un nuevo dominio de aplicación para cada método (o algo equivalente a borrar todo el estado).

Idealmente, me gustaría especificar este comportamiento solo para un subconjunto pequeño de las pruebas de mi unidad para no tener que pagar la penalización de una nueva creación de AppDomain para las pruebas que no se preocupan por el estado global (la gran mayoría de mis pruebas).

Respuesta

6

Al final, escribí una ayuda que usó AppDomain.CreateDomain y luego usé la reflexión para llamar a la prueba de unidad bajo un Dominio de aplicación diferente. Proporciona el aislamiento que necesitaba.

This post en los foros de MSDN muestra cómo manejar la situación si solo tiene algunas estadísticas que deben restablecerse. It menciona algunas opciones (por ejemplo, usando Reflection y PrivateType).

Continúo recibiendo cualquier idea adicional, especialmente si me falta algo obvio de MSTEST.

+2

¿Tiene un ejemplo de código Jeff? – DevDave

+1

Sí, una muestra de código por favor – Harindaka

0

Tuvimos un problema similar con nuestros MSTests. Lo manejamos llamando a una función al principio y al final de las pruebas específicas que lo necesitaban.

Estamos almacenando una fecha de caducidad de prueba en la configuración de nuestra aplicación. Tres pruebas necesitaron que esta fecha cayera dentro de un rango específico para determinar los valores apropiados. La forma en que se configura nuestra aplicación, los valores de configuración solo se restablecerían si no hubiera un valor asignado en la sesión. Por lo tanto, creamos dos nuevas funciones estáticas privadas: una para establecer explícitamente el valor de configuración en una fecha específica y otra para borrar esa fecha de la sesión después de la ejecución de la prueba. En nuestras tres pruebas, llamamos a estas dos funciones. Cuando se ejecuta la siguiente prueba, la aplicación ve un valor vacío para la fecha y vuelve a buscarlo desde el archivo de configuración.

No estoy seguro si eso es útil, pero así fue como trabajamos con nuestro problema similar.

+0

Parece que podrías usar [TestInitialize] en tu clase de prueba? –

0

Creo que está buscando el atributo TestIntialize y el atributo TestCleanUp. Aquí hay un blog de MSDN que muestra la orden de ejecución link text

+0

Gracias por la respuesta. Estaba buscando algo que limpiara el mundo sin tener que eliminar explícitamente cada variable, pero no estoy seguro si eso es posible. –

3

Agregue un ayudante en sus pruebas que use reflexión para eliminar la instancia de singleton (también puede agregar un método de reinicio al singleton, pero me preocuparía su uso). Algo como:

public static class SingletonHelper { 
      public static void CleanDALFactory() 
      { 
        typeof(DalFactory) 
         .GetField("_instance",BindingFlags.Static | BindingFlags.NonPublic) 
         .SetValue(null, null); 
      } 
} 

Llamar esto en su método TestInitialize. [Sé que esto es "limpiar el mundo", pero solo tienes que escribir el método una vez en un helper por singleton, es muy trivial y te da un control explícito]

+0

Gracias por la respuesta. Creo que tendré que usar una combinación de Reflection para iterar sobre los campos estáticos y más o menos lo que describes aquí. Algo así como un "NullifyStaticFields (Type t)" para hacerlo reutilizable –

Cuestiones relacionadas