2009-03-31 20 views
21

Ok, esto es molesto.MSTest ejecutando todas mis pruebas simultáneamente rompe pruebas - qué hacer

MSTest ejecuta todas mis pruebas al mismo tiempo, lo que hace que algunas fallen. No, esto no se debe a que mis pruebas son frágiles y susceptibles de compilación, sino porque es un proyecto de demostración en el que utilizo una base de datos de objetos Db4o que se ejecuta desde un archivo.

Así que tengo un par de pruebas de DataAccess comprobando que mis repositorios funcionan correctamente y auge, MSTest explota. Como intenta ejecutar todas sus pruebas al mismo tiempo, recibe un error cuando una prueba intenta acceder al archivo de la base de datos mientras otras pruebas lo están usando.

¿Alguien puede pensar en una forma rápida de evitar esto? No quiero deshacerme de MSTest (vale, lo hago, sino otra historia) y estoy seguro de que no quiero ejecutar un servicio de base de datos completo, así que tomaré cualquier forma para forzar a MSTest a no ejecutar simultáneamente o trucos con abriendo archivos.

¿Alguien tiene alguna idea?

Respuesta

30

Puede intentar usar un Monitor e ingresar en TestInitialize y salir en TestCleanup. Si todas las clases de prueba dependen del archivo externo, deberá usar un único objeto de bloqueo para todas ellas.

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

... 

[TestInitialize] 
public void TestSetup() 
{ 
    Monitor.Enter(LockClass.LockObject); 
} 

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

Esto debería obligar a todas las pruebas para funcionar en serie y el tiempo que pasan todas las pruebas de éxito/fracaso se debe ejecutar. Si alguno de ellos arroja una excepción inesperada, todo lo demás se bloqueará ya que el código de salida no se ejecutará para la prueba que explota.

+0

... ahora que es una buena idea –

+0

¿Qué quiere decir con "una excepción inesperada"? Traté de lanzar .NET y excepciones nativas (C++) y TestCleanup() parece ser llamado siempre. – mhenry1384

+0

Sin verificar, creo que es posible tener una excepción (digamos un desbordamiento de pila) que haría que el subproceso salga sin poder ejecutar el código de limpieza. En ese caso, el Monitor nunca saldría. – tvanfosson

4

He intentado usar bloqueos de esta manera. Lo que experimenté, sin embargo, fue que VS2010 hace no ejecuta las pruebas en paralelo de forma predeterminada, pero las ejecuta secuencialmente, en un solo hilo. (Sin embargo, la ejecución en paralelo podría activarse. Pero esto no evitaría el problema por completo)

Lo que me parece muy inquietante es que la ejecución secuencial tendrá lugar en orden arbitrario, ¡incluso en clases de prueba!

Así, por ejemplo, una orden de ejecución puede tener este aspecto:

  • Clase A - TestInitialize: Bloqueo se establecerá
  • Clase A - TestMethod1: Se ejecutará, OK
  • Clase B - TestInitialize: Se establecerá el bloqueo => El hilo se bloqueará => ¡Se bloquearán los exámenes de la unidad completa! La causa es que no hay otros subprocesos que seguirían ejecutando métodos de clase A. Por lo tanto, nunca se alcanzará Montor.Exit().

No entiendo por qué M $ lo está haciendo. Otros frameworks UnitTest (por ejemplo, JUnit) ejecutan los métodos de prueba según la clase. De lo contrario, habrá algún entrelazado del método SetUp/TearDown que causaría el caos descrito ...

¿Hay alguien por ahí que sepa cómo evitar el salto MSTest entre las clases de prueba? (Actualmente uso corredor de prueba Resharpers, que se comporta como se esperaba, la ejecución de todos los métodos de ensayo de una classe antes de proceder con la siguiente clase)

+6

Siete - Creo que uno de mis compañeros de trabajo lo expresó mejor: se debe a que MSTest no es un marco de prueba de unidades. Es un marco de prueba muy generalista que trata de hacer demasiadas cosas para demasiadas personas y falla en todas ellas. –

+0

Jep, tal vez esto es solo el paradigma de la solución all-in-one-thing M $ siempre conduce, lo que resulta en cosas capaces de todo, pero utilizables en vano. Entonces, probablemente necesitemos cambiar a NUnit, ya que algunos de mis colegas no usan el reafilamiento. – Seven

+1

"que intenta hacer demasiadas cosas para mucha gente y falla en todas ellas". se aplica a Microsoft como un todo, no solo a su "framework" de pruebas de unidades – Jeff

2
+0

Lo sentimos, no responde la pregunta. –

+0

¡Claro que sí, una prueba ordenada ejecuta todas las pruebas en una secuencia secuencial que es exactamente lo que quieres! –

+0

Sí, pero tienes que explicar por qué. De lo contrario, no está realmente respondiendo la pregunta, solo da una sugerencia – jgauffin

Cuestiones relacionadas