¿Por qué los marcos xUnit no permiten que las pruebas se ejecuten en paralelo?

15

¿Conoces algún marco de xUnit que permita ejecutar pruebas en paralelo para utilizar múltiples núcleos en la máquina actual?

Si ninguno (o muy pocos) lo hace, tal vez haya una razón ... ¿Es que las pruebas suelen ser tan rápidas que las personas simplemente no sienten la necesidad de paralelizarlas?

¿Hay algo más profundo que impida distribuir (al menos algunas de) las pruebas en múltiples hilos?

Xavier Nodet
fuente
Las pruebas unitarias son definitivamente lentas. Incluso si cada prueba en sí misma es rápida, se acumularían ya que las personas literalmente tienen millones de casos de prueba.
Pacerier

Respuestas:

6

NUnit 2.5 paquete pNUnit que permite la ejecución de pruebas en paralelo.

Esta versión incluye pNUnit, un corredor NUnit extendido para pruebas paralelas distribuidas. El programa pNUnit se desarrolló en Codice Software para su uso en las pruebas de Plastic SCM y se ha contribuido a NUnit. Para obtener más información sobre el uso de pNUnit, consulte el sitio pNUnit.

El lado JUnit tiene paralelo-junit así como amino .

Aaron McIver
fuente
Entonces, ¿la única razón para los otros marcos sería 'todavía no implementada'?
Xavier Nodet
1
@Xavier Sí; Esa es una declaración justa.
Aaron McIver
10

Para responder a la segunda parte de su pregunta: ¿Hay algo más profundo que impida distribuir (al menos algunas de) las pruebas en múltiples hilos?

Una gran cantidad de código solo funciona cuando se ejecuta un solo subproceso. Es trivial producir accidentalmente contención de recursos y puntos muertos cuando se escriben programas bajo el supuesto de que se ejecutarán con un solo subproceso. Y esto funciona bien porque la mayoría de los programas realmente funcionan con un solo subproceso. El paralelismo se obtiene al ejecutar múltiples copias o diferentes programas al mismo tiempo (los scripts web son un ejemplo común: muchos usuarios que acceden a una sola página significan muchas copias de los scripts para esa página ejecutándose al mismo tiempo).

Imagine una clase simple de "registro a archivo". Cuando crea una instancia, abre el archivo para escribir, cuando libera la instancia, cierra el archivo. Entonces, la primera prueba crea una instancia y comienza a ejecutar una prueba. La segunda prueba hace lo mismo en un segundo hilo. Y falla, porque la segunda instancia no puede obtener acceso de escritura al archivo. Pero si se ejecuta uno a la vez, todas las pruebas pasarían.

Todo esto puede codificarse, y el simple ejemplo podría modificarse para que funcione. Pero hacer eso probablemente sea innecesario para el programa original . Tener que escribir código seguro para subprocesos solo para poder ejecutar pruebas unitarias no es razonable para muchas personas. Por lo tanto, las pruebas unitarias multiproceso deberían seguir siendo un extra opcional.


fuente
+1 Esta debería ser la respuesta exceptuada porque en realidad responde el por qué.
Oliver Weiler
4

Si las pruebas necesitan configurar y consultar una base de datos, las pruebas que se ejecutan en paralelo interferirían entre sí, a menos que haya una base de datos separada para cada prueba que se ejecute en paralelo.

Clint Miller
fuente
Eso no es para que la plataforma de prueba (xUnit) se preocupe; Ese es un detalle de implementación.
Aaron McIver
Y no todas las pruebas escritas en un marco de pruebas unitarias son pruebas unitarias, al igual que la que accede a la base de datos no es realmente una prueba unitaria, más bien una prueba de integración.
c_maker
El hecho de que una prueba toque una base de datos no significa que sea una prueba de integración. Un método que se ejecuta parcialmente en C # y parcialmente en una base de datos sproc, por ejemplo, sigue siendo conceptualmente una prueba unitaria, siempre que no se espere una preconfiguración (es decir, el esquema de datos está presente, pero no hay datos). Dichas pruebas pueden crear datos para una ejecución individual, pero deben restablecerse a un estado en blanco cuando haya terminado) Esta es probablemente una opinión controvertida, pero tales pruebas no pueden considerarse pruebas de integración, porque son explícitamente pruebas de configuración cero y despliegue cero que prueban unidades de código pequeñas.
Triynko
2

Si bien JUnit per se puede no permitirlo (aunque no estoy íntimamente familiarizado con sus últimas versiones), Maven con su complemento Surefire tiene una opción para ejecutar pruebas en paralelo. Sin embargo, aún no lo he probado.

No estoy muy presionado para investigar esta opción, ya que solo tenemos un poco más de mil pruebas y se ejecutan lo suficientemente rápido. Sin embargo, sé que algunos de los accesorios de prueba tienen dependencias implícitas entre (hemos encontrado algunas de esas dependencias cuando algunas pruebas se rompieron inesperadamente en el pasado), por lo que existe el riesgo de que la paralelización de las pruebas haga que algunas de ellas fallen de manera impredecible. Puede decir que esto está bien, ya que hace que el problema sea explícito. Sin embargo, estamos lidiando con un sistema heredado y tenemos muchos problemas más importantes con los que lidiar: el tiempo es un recurso escaso (como de costumbre).

Péter Török
fuente
0

La codificación multiproceso no es trivial. Incluso cuando lo hacen personas que saben lo que están haciendo, pueden ocurrir errores dependientes del tiempo. Son difíciles de arreglar. Habiendo tratado con el que pueden producirse unos pocos miles de errores de tipo multicapa, preferiría no tenerlos en mi marco de prueba. La primera solución que obtuve parecía funcionar, pero en pruebas posteriores se descubrió que se había convertido en un error de uno en decenas de miles.

Las técnicas para realizar subprocesos múltiples en procesadores múltiples están mejorando con la llegada de las PC con múltiples procesadores. Sin embargo, tomará tiempo antes de que se usen ampliamente.

Algunas suites de prueba tienen dependencias entre las pruebas que no necesitan ser declaradas explícitamente cuando las pruebas se ejecutan en una sola secuencia. Sin embargo, en una máquina de vapor múltiple, tendrían que especificarse explícitamente. (Donde tales dependencias deberían existir es una pregunta diferente).

Desde otro punto de vista, algunas cosas simplemente no necesitan ejecutarse en paralelo. Si el proceso se ejecuta adecuadamente rápido, puede ser mejor enfocar los esfuerzos en otras cosas que no sean la implementación de subprocesos múltiples.

BillThor
fuente
0

MBUnit puede ejecutar pruebas en paralelo simplemente especificando algunos atributos de nivel de ensamblaje.

[assembly: DegreeOfParallelism(6)]
[assembly: Parallelizable(TestScope.All)]

He estado usando ese proyecto para ejecutar pruebas de selenio en paralelo con bastante éxito durante algún tiempo. Lamentablemente, el proyecto ya no está muy vivo.

xUnit 2.0 también debería admitir pruebas de unidades paralelas, pero aún no lo he probado.

Ivo Grootjes
fuente