2009-10-09 15 views
28

Estoy trabajando en una aplicación que es principalmente de un solo subproceso, un solo usuario. Hay algunos subprocesos de trabajo aquí y allá, y solo usan clases y objetos seguros para subprocesos. Las pruebas unitarias en realidad están probando aquellas con múltiples hilos (creadas explícitamente para las pruebas), y se prueban bien.¿Hay alguna forma de ejecutar las pruebas unitarias de forma secuencial con MSTests?

Las pruebas de la unidad VSTS fallan cuando se prueban objetos comerciales y subsistemas que no son seguros para subprocesos. Está bien que no sean seguros para subprocesos, así es como la aplicación los usa.

Pero el enfoque 'un hilo por TestMethod' de las pruebas de MS nos mata. Tuve que implementar bloqueos de objetos en muchas clases de prueba unitarias solo para asegurarme de que las pruebas se ejecutan una tras otra (en realidad no me importa el orden, pero no puedo tener dos métodos de prueba que toquen el mismo objeto en al mismo tiempo).

El código es el siguiente:

[TestClass] 
public class TestSomeObject 
{ 
    static object turnStile = new object(); 
... 
    [TestMethod] 
    public void T01_TestThis() 
    { 
     lock(turnStile) 
     { 
     .. actual test code 
     } 
    } 

    [TestMethod] 
    public void T02_TestThat() 
    { 
     lock(turnStile) 
     { 
     -- actual test code 
     } 
    } 

} 

¿Hay una manera mejor/más elegante para hacer la prueba de funcionamiento secuencial?

+0

por lo que parece que está reutilizando una instancia de algún objeto en todas sus pruebas? – BlackTigerX

+0

Sí, esencialmente. A veces es la base de datos, a veces es un singleton, se usa en la aplicación –

+1

ya que afirma que es * unit-testing * por su etiqueta, debe burlarse/anular sus dependencias, especialmente las dependencias que no son seguras – mxmissile

Respuesta

16

Existe la noción de una "Prueba solicitada" en la que puede listar las pruebas en secuencia. Está más orientado a garantizar un cierto orden secuencial, pero no veo cómo sería posible si B no espera a que A complete.

Aparte de eso, es lamentable que sus pruebas interfieran entre sí. Hay métodos de Configuración/TearDown que se pueden usar por prueba de modo que después de todo es posible aislar las pruebas entre sí.

+0

Desafortunadamente, MSTest ejecuta todas las pruebas en el mismo dominio de la aplicación, lo que permite que las pruebas interfieran entre sí en primer lugar. – Triynko

23

Utilice Ordered Test.

Prueba> Nueva prueba> Prueba

Test > New Test

Ordered Test

+0

cosas geniales. Sabía que TENÍA que haber una manera más fácil ... :) –

+0

¿Cómo se especifica un archivo .runsettings cuando se utiliza una prueba ordenada? Específicamente, necesito acceder al TestContext con los parámetros especificados en .runsettings. –

+0

@ajhuddy: suena como un buen candidato para una nueva pregunta de desbordamiento de pila. Busque primero para asegurarse de que su pregunta no haya sido formulada y respondida, y haga referencia a esta pregunta cuando escriba su nueva pregunta. –

8

ordenado finalmente utilizó el método de prueba ordenada. Funciona bien.

Sin embargo, me costó muchísimo hacer que funcione con la versión de NAnt. Ejecutando solo la lista de pruebas ordenadas en la compilación requiere el uso de los modificadores/testmetadata y/testlist en el bloque de invocación MSTest. La documentación sobre estos es incompleta, para usar una descripción de tipo. Busco en todo el mundo ejemplos de "MSTest/testmetadata/testlist" sin ningún efecto.

El truco es simple, sin embargo, y me siento obligado a devolverlo a la comunidad, en caso de que alguien más se encuentre con el mismo problema.

  1. Editar el archivo de metadatos de prueba (con una extensión .vsmdi), y añadir una nueva lista a la lista de pruebas (el primer nodo en el árbol en el panel de la izquierda . Darle el nombre que desea, por ejemplo 'SequentialTests'.
  2. Si utilizó un modificador/testcontainer para la invocación MSTest, elimínelo.
  3. Añadir un interruptor para MSTest ->/testmetadata:
  4. Añadir un interruptor para MSTEST /LISTAPRUEBA: SequentialTests (o el nombre que se utiliza)

Entonces MSTest sólo ejecuta las pruebas enumeradas en la prueba lista que has creado

Si alguien tiene un método mejor, ¡me gustaría escucharlo!

12

Puede requerir específicamente un mutex para cada ejecución de prueba, ya sea en las pruebas específicas que desea serializar, o para todas las pruebas en una clase (lo que comparta la misma cadena mutex).

Para una clase de prueba entera, se puede utilizar el TestInitialize y TestCleanup atributos de este modo:

private readonly Mutex testMutex = new Mutex(true, "MySpecificTestScenarioUniqueMutexString"); 

[TestInitialize] 
public void Initialize() 
{ 
    testMutex.WaitOne(TimeSpan.FromSeconds(1)); 
} 

[TestCleanup] 
public void Cleanup() { 
    testMutex.ReleaseMutex(); 
} 

Para que quede claro que esto no es una característica de las pruebas, cualquier estructura de bloqueo debería funcionar. Estoy usando el sistema previsto en este caso mutex: https://msdn.microsoft.com/en-us/library/system.threading.mutex(v=vs.110).aspx

+0

Hola, ¿podría dar más detalles? Por ejemplo, necesito una aclaración sobre esto "... lo que sea que comparta la misma cuerda mutex". Además, usted declara el TestMutex Private ReadOnly pero en Initialize and Cleanup está utilizando FileTestMutex ... thx – CTZStef

+0

¡Hola! El desajuste de referencia fue un error tipográfico, lo he solucionado. También agregué un enlace a la clase Mutex para aclararme. Mutex es una estructura de bloqueo proporcionada por Microsoft que utiliza una cadena de bloqueo de todo el sistema, por lo que desea que la cadena sea única por conjunto de cosas que quiera serializar, lo que podría ser por prueba o para una prueba entera diferente clases Si copia/pega la cadena en todas partes, se serializará cada uso de la misma. También tenga en cuenta las sugerencias 'OrderedTest' anteriores, que probablemente sea una mejor idea si le funciona. El enfoque Mutex (u otro bloqueo manual) es complicado. –

2
pruebas

he usado pidió, también les configurado fácilmente en Jenkins acaba de utilizar el comando

/testcontainer:"orderedtestfilename.orderedtest MSTest "/ resultsfile:" testresults .trx"

16

que es posible utilizar lista de reproducción

haga clic derecho en el método de ensayo -> Añadir a la lista de reproducción -> Nueva lista de reproducción

a continuación, puede especificar la orden de ejecución enter image description here

+0

Siento que esta es la mejor respuesta a la pregunta. – user969153

+1

Funcionó mejor y fue fácil de configurar en menos de un minuto. – Ruan

Cuestiones relacionadas