2011-02-18 9 views
28

Dado este conjunto de prueba:Forzar MSTest utilizar un solo hilo

[TestClass] 
public class MSTestThreads 
{ 
    [TestMethod] 
    public void Test1() 
    { 
     Trace.WriteLine(Thread.CurrentThread.ManagedThreadId); 
    } 

    [TestMethod] 
    public void Test2() 
    { 
     Trace.WriteLine(Thread.CurrentThread.ManagedThreadId); 
    } 
} 

Ejecución de la prueba con MSTest través de línea de comandos de Visual Studio o imprime dos números de los hilos diferentes (sin embargo, se ejecutan secuencialmente todos modos).

¿Hay alguna manera de obligar a MSTest a ejecutarlas con un solo hilo?

+3

automatizados de pruebas de interfaz de usuario que tendrán que funcionar con la misma hebra de aplicación de interfaz de usuario, ya que todos ellos tienen que usar una sola clase de aplicación WPF estática que no se puede instanciar más de una vez (restricción de WPF, no la mía). La técnica funciona en NUnit. –

+1

Lo resolví creando un nuevo dominio de aplicación para cada prueba, ejecutando el cuerpo de la prueba dentro de ese dominio de aplicación y creando una nueva instancia de aplicación en cada prueba. Puedo ver por qué esto sería doloroso en la mayoría de los casos, pero en mi caso, escribí mi propia clase de aplicación, así que no estaba realmente duplicando ninguna prueba al agregar ese texto repetitivo. –

+0

Además, si comparte una instancia de aplicación, teóricamente podría crear un hilo de interfaz de usuario para ella y compartir eso también. –

Respuesta

10

He luchado durante interminables horas para hacer que MSTest se ejecute en un único modo enhebrado en un proyecto grande que hizo un uso intensivo de nhibernate y no es seguro (no es un problema, simplemente no lo es) ISession.

Terminamos más tiempo escribiendo código para admitir la naturaleza de subprocesos múltiples de MSTest porque, según mi leal saber y entender, no es posible ejecutar MSTest en un único modo de subproceso.

+2

Gracias por la respuesta: me rendiré y volveré a NUnit –

+2

Estoy confundido. Si tus pruebas se ejecutan secuencialmente, ¿qué importa si están en diferentes hilos o no? ¿Cómo importa la seguridad del hilo incluso en este caso? –

+4

@Merlyn: Importa debido a las restricciones que pueden existir en componentes que no le pertenecen. Como mencionó Paul, la clase de la aplicación WPF es un gran ejemplo, la ejecución de casos de prueba en su contra puede fallar debido a problemas de propiedad del hilo. Este tipo de derrota el propósito de la prueba porque ahora se está ejecutando contra un escenario imposible. (Tu aplicación solo tendrá una instancia de aplicación, por lo que todos los hilos serán los mismos). –

1

Si bien es una respuesta de salida de policía, en realidad lo aliento a hacer que su código sea seguro para subprocesos. El comportamiento de MSTest es garantizar el aislamiento como lo ha señalado Richard. Al enfrentar problemas con las pruebas de su unidad, está demostrando que podría haber problemas en el futuro.

Puede ignorarlos, usar NUnit o tratar con ellos y continuar usando MSTest.

+2

En este caso, el problema se debe a WPF, por ejemplo, nueva MyApp(); nueva MyApp(); // segunda llamada lanza, pero cada uno está enlazado al hilo –

+2

Ah, veo el punto de dolor ahora. Sí, supongo que si está utilizando un marco de aplicación que alienta el uso de un solo hilo para funcionar (los marcos de UI son obviamente en esta categoría), entonces es posible que necesite hacer algo de gimnasia para que funcione. Solo un poco, ¿y si creaste un hilo que controlas e iniciaste todo tu código WPF en ese hilo, y clasificaste todo tu código de prueba en ese hilo? –

+0

En lugar de hacer una nueva MyApp(), puede intentar abstraerla de la siguiente manera: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/786d5c06-0511-41c0-a6a2-5c4e44f8ffb6 – Anastasiosyal

2

Tratamos de distinguir las pruebas aisladas entre sí. Muchos de ellos logran esto configurando el estado de una base de datos y luego restaurándola. Aunque la mayoría de las pruebas configuran datos diferentes, con unas 10.000 en una ejecución hay una buena probabilidad de una colisión a menos que el autor del código de una prueba se asegure de que sus datos iniciales sean únicos (es decir, no use las mismas claves primarias que otra). prueba haciendo algo similar). Esto es, francamente, inmanejable, y obtenemos fallas de prueba ocasionales que pasan la segunda vez. Estoy bastante seguro de que esto es causado por colisiones que se evitarían ejecutando las pruebas de forma estrictamente secuencial.

19

He resuelto este problema con bloqueo:

public static class IntegrationTestsSynchronization 
{ 
    public static readonly object LockObject = new object(); 
} 

[TestClass] 
public class ATestCaseClass 
{ 
    [TestInitialize] 
    public void TestInitialize() 
    { 
     Monitor.Enter(IntegrationTestsSynchronization.LockObject); 
    } 

    [TestCleanup] 
    public void TestCleanup() 
    { 
     Monitor.Exit(IntegrationTestsSynchronization.LockObject); 
    } 

    //test methods 
} 

// possibly other test cases 
+0

Has encontrado un problema que afecta las pruebas de _integración_. –

2

puede derivar su clase de prueba de

public class LinearTest 
{ 
    private static readonly object SyncRoot = new object(); 

    [TestInitialize] 
    public void Initialize() 
    { 
     Monitor.Enter(SyncRoot); 
    } 

    [TestCleanup] 
    public void Cleanup() 
    { 
     Monitor.Exit(SyncRoot); 
    } 
} 
0

probé un poco de un enfoque diferente, ya que el subyacente El problema es que los nombres de las tuberías son el problema. Así que hice un fakePipe, lo derivé del que uso en el programa. Y llamó a la tubería con el nombre de las pruebas.

[TestClass] 
public class PipeCommunicationContractTests { 
    private PipeDummy pipe; 

    /// <summary> 
    ///Gets or sets the test context which provides 
    ///information about and functionality for the current test run. 
    ///</summary> 
    public TestContext TestContext { get; set; } 

    [TestInitialize] 
    public void TestInitialize() { 
    pipe = new PipeDummy(TestContext.TestName); 
    pipe.Start(); 
    } 

    [TestCleanup] 
    public void TestCleanup() { 
    { 
    pipe.Stop(); 
    pipe = null; 
    } 
    ... 
    [TestMethod] 
    public void CallXxOnPipeExpectResult(){ 
     var result = pipe.Xx(); 
     Assert.AreEqual("Result",result); 
    } 
} 

Parece ser un poco más rápido, ya que puede ejecutarse en múltiples núcleos e hilos ...

Cuestiones relacionadas