Pregunta

En algunos de mis proyectos, observo que durante la ejecución de pruebas unitarias bajo VSTS2008, el consumo de memoria de VSTestHost aumenta. Como tengo muchas pruebas en mi solución, esto lleva a OutOfMemroyException eventualmente. Eso me parece muy extraño, ya que estaba seguro de que MSTest crea un nuevo AppDomain para cada prueba unitaria. De lo contrario, ¿cómo restablecería los campos estáticos? Pero si se crea AppDomain para cada prueba, la memoria no debería perder. Pero lo hace.

Entonces, la pregunta es: ¿Debería VS crear un dominio de aplicación para cada clase de prueba o no? Si es así, ¿cómo puedo comprobar que lo hace? Intenté rastrear a través de ProcessExpolorer y el complemento de rendimiento. Un valor de " Total appdomain descargado " siempre es 0 durante la ejecución de prueba.

¿Fue útil?

Solución

No creo que el motor de prueba de unidad cree un nuevo dominio de aplicación para cada prueba. Dado que crear un dominio de aplicación es una operación relativamente costosa, hacerlo para cada prueba ralentizaría considerablemente la ejecución de las pruebas unitarias.

Visual Studio 2008 usa un ejecutable separado llamado vstesthost.exe para ejecutar pruebas unitarias. VS se comunica con vstesthost.exe (no sé cómo hacerlo) para indicarle qué pruebas ejecutar. vstesthost.exe devuelve los resultados de ejecución a VS, que muestra esos resultados.

Si está obteniendo OutOfMemoryExceptions cuando ejecuta las pruebas de su unidad, diría que es un claro indicador de que su código bajo prueba en realidad no está limpiando las cosas. ¿Está seguro de que no está reteniendo identificadores a objetos / memoria no administrados? Recomendaría ejecutar sus pruebas de unidad en un Análisis de rendimiento (puede hacerlo encontrando la prueba de unidad en la "Vista de prueba", haga clic con el botón derecho y seleccionando "Crear sesión de rendimiento"). Esto podría arrojar algo de luz al menos en las asignaciones de objetos.

Otros consejos

MsTest crea un dominio de una aplicación por Ensamblado , a menos que esté utilizando noisolation, en cuyo caso no hay Aislamiento de dominio de aplicación.

Si está viendo fugas, es probable que se encuentre en el código de prueba o en el código del producto. Asegúrese de no meter cosas en los diccionarios y dejarlas allí.

Me equivoqué al tener AppDomains separados para cada prueba de unidad.

Aquí hay evidencia: un singleton

public class Singleton
{
    public static Singleton Instance = new Singleton();

    private Guid _token;
    private Singleton()
    {
        _token = Guid.NewGuid();
    }

    public Guid Token
    {
        get { return _token; }
    }
}

y dos pruebas:

[TestClass]
public class UnitTest2
{
    [TestMethod]
    public void TestMethod1()
    {
        Console.WriteLine(Singleton.Instance.Token);
    }
}
[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Console.WriteLine(Singleton.Instance.Token);
    }
}

Durante la ejecución de ambas pruebas, sale el mismo guid.

Visto el mismo problema con las grandes pruebas ejecutadas. Mi teoría es la siguiente. El agotamiento de la memoria en este caso se debe al hecho de que los archivos de resultados de prueba de MSTest son XML. Por lo tanto, debe mantener todos los resultados del registro en la memoria hasta el final de la ejecución de la prueba antes de serializar en el disco. Hurra para XML :-)

He publicado este problema como problema de conexión hace un tiempo y debería haberse solucionado en MSTest 10 (con 64 bits), pero aún no he podido verificarlo debido a todos los demás problemas que hemos tenido con VS2010 y .NET 4.0.

La única forma de deshacerse de un singleton es disponer del dominio de aplicación. Un singleton es una retención estática sobre sí mismo, por lo que es básicamente una referencia circular. Los verdaderos singletons no se eliminan hasta que el appdomain se va.

Esto no parece resolverse en MSTest 2010. Estoy experimentando muchos problemas similares como este. ¿Por qué la recolección de basura no funciona en la prueba unitaria?

Mi entendimiento fue que el marco de trabajo de UT se encargó de eliminar todas las pruebas ejecutadas, pero este no parece ser el caso con algunos patrones singleton que tenemos en código.

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