38

Estoy buscando formas de ejecutar suites de prueba en paralelo.¿Cómo ejecutar las pruebas unitarias (MSTest) en paralelo?

Entiendo .testrunconfig estableciendo. Esto le permite múltiplex en el número de CPU.

Quiero ejecutar 1000 pruebas en paralelo. Esto tiene sentido porque estoy probando un servicio web, por lo que el 90% del tiempo dedicado a una prueba está esperando que el servicio responda.

¿Alguna idea sobre cómo llevarlo a cabo? Las pruebas están escritas para VS, pero estoy abierto a ejecutarlas fuera de VS.

Edición posterior: el equipo de prueba de Visual Studio lo ha agregado en VS 2015 Actualización 1. Consulte la respuesta de Mark Sowul a continuación.

+0

Hablando aquí acerca de 1000 hilos. –

+0

Correcto, me pregunto si hay un marco de precompilación para administrar esto. O si alguien construye su propio marco. –

+2

Necesita un simulador de carga. MSTest no está destinado a ser utilizado como una prueba de carga. 1000 hilos es una locura, por cierto, lo que debe hacer es buscar en diferentes tecnologías de prueba, esto está fuera de los límites de una prueba unitaria. – Aren

Respuesta

20

La actualización 1 de Visual Studio 2015 agrega esto. https://www.visualstudio.com/en-us/news/releasenotes/vs2015-update1-vs#a-idmisc-a-miscellaneous

Para la Actualización 2, hay un botón de alternar UI en la barra de herramientas en la parte superior del panel del Explorador de pruebas (entre los cuadros 'agrupación' y 'búsqueda').

Para la actualización 1, establecer lo siguiente en los .runsettings

<?xml version="1.0" encoding="utf-8"?> 
<RunSettings> 
    <RunConfiguration> 
    <MaxCpuCount>0</MaxCpuCount> 
    </RunConfiguration> 
</RunSettings> 

El valor para MaxCpuCount tiene la semántica siguiente:

• 'n' (donde 1 < = n = número < de núcleos): se lanzarán procesos 'upto' n '.

• 'n' de cualquier otro valor: el número de procesos iniciados será tantos como los núcleos disponibles en la máquina.

+2

Tenemos archivos DLL de prueba con cientos de pruebas, algunos pueden ejecutar en paralelo, otros no. ¿Hay alguna manera de atribuir clases/métodos de prueba seguros y no seguros? Por lo general, quiero seleccionar una o más de estas enormes DLL y dejar que se rasgue. – GilesDMiddleton

+2

Una cosa a tener en cuenta es que el paralelismo está en el nivel de clase, no en el nivel de prueba. No veo una forma integrada de hacer lo que desea, pero puede hacerlo usted mismo, p. con Mutexes con nombre en 'ClassInitialize' /' ClassCleanup'. Desafortunadamente, puede terminar con esas pruebas que bloquean el paralelismo por un tiempo (por ejemplo, las cuatro "pruebas paralelas" son las que usan el mutex), pero eso es tan bueno como creo que puede obtener. –

+4

Las pruebas se paralelizan en el nivel del contenedor (en el caso de C#, eso es Ensamblaje), por lo que ejecutará pruebas de diferentes ensamblajes en paralelo. Las pruebas en el mismo ensamblaje se ejecutan en secuencia en el nuevo modelo. – jessehouwing

27

Usted puede obtener hasta 5 usando el método from the Visual Studio Team Test Blog

Tenga en cuenta que puede haber problemas de concurrencia utilizando esto, como MSTest no aísla completamente cada prueba (la estática se transfieren, por ejemplo, haciendo las cosas interesante para el código destinado a ejecutarse una vez).

(Ni idea de por qué el límite es 5, pero no los MSTest se ejecutará en paralelo si parallelTestCount se establece en más de 5. De acuerdo con los comentarios a continuación, esta regla aparentemente cambia con Visual Studio 2013)

+0

Sí, lo encontré de la manera difícil :) - Ejecuté mi suite en un núcleo 8 y todo las pruebas se abortaron ... –

+0

No debe limitarse a 5 en total, sino a 5 pruebas suspendidas. Comentario de Bruce Taimana: "Si la limpieza se" cuelga "o tarda demasiado, dejamos que continúe la limpieza, pero iniciamos la siguiente prueba en paralelo. Si llega a 5 pruebas" suspendidas ", abortamos". Lea el comentario completo [aquí] (http://blogs.msdn.com/b/vstsqualitytools/archive/2009/12/01/executing-unit-tests-in-parallel-on-a-multi-cpu-core- machine.aspx # 10091555). – Anttu

+0

@Anttu Me gustaría ver una solución que está configurada para ejecutar más de 5 a la vez y hacer que realmente los ejecute en lugar de fallar. Cada vez que intenté tener más de 5 para esa configuración, simplemente fallaría. Tal vez el momento de la caída se considera demasiado pequeño? Realmente no lo sé – Rangoric

8

Lo Encontré que C: \ Archivos de programa (x86) \ Microsoft Visual Studio 11.0 \ Common7 \ IDE \ CommonExtensions \ Microsoft \ TestWindow \ vstest.console.exe ejecutará pruebas paralelas con un archivo .testsettings que se ve así:

<?xml version="1.0" encoding="UTF-8"?> 
<TestSettings name="TestSettings1" id="21859d0f-7bdc-4165-b9ad-05fc803c9ee9" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010"> 
    <Description>These are default test settings for a local test run.</Description> 
    <Deployment enabled="false" /> 
    <Execution parallelTestCount="8"> 
    <TestTypeSpecific> 
     <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b"> 
     <AssemblyResolution> 
      <TestDirectory useLoadContext="true" /> 
     </AssemblyResolution> 
     </UnitTestRunConfig> 
    </TestTypeSpecific> 
    <AgentRule name="Execution Agents"> 
    </AgentRule> 
    </Execution> 
</TestSettings> 

La referencia se puede encontrar aquí http://msdn.microsoft.com/en-us/library/vstudio/jj155796.aspx

+1

También funciona si usa 'Test Explorer' cuando está dentro de Visual Studio. Solo necesita seleccionar '.testsettings' configurado con' parallelTestCount'. Más detalles aquí: http://ardalis.com/run-your-unit-tests-in-parallel-to-maximize-performance Por cierto: para seleccionar '.testsettings', haga clic en el menú' TEST' en VS 2013 luego 'Test Settings => Select Test Settings File'. –

+0

Nunca he visto una bestia así. En 2013 tuve que crear mi propio archivo de configuración de prueba (Agregar elemento en el nivel de Solución), luego modificarlo para compatibilidad en paralelo según las instrucciones de Igor. –

4

Las respuestas anteriores sin duda contribuyeron a clarificar las cosas para mí, pero, este punto del blog de John Koerner: https://johnkoerner.com/vs2015/parallel-test-execution-in-visual-studio-2015-update-1-might-not-be-what-you-expect/ era la parte que nos faltaba. "La ejecución de prueba paralela aprovecha los núcleos disponibles en la máquina y se realiza iniciando el motor de ejecución de prueba en cada núcleo disponible como un proceso distinto y entregándole un contenedor (ensamblado, DLL o artefacto relevante que contiene las pruebas ejecutar), pena de pruebas para ejecutar."

->" La broca del contenedor separado es la pieza que me faltaba. Para que mis pruebas se ejecuten en paralelo, necesitaba dividir mis pruebas en ensamblajes de prueba separados. Después de hacer eso, vi que las pruebas en diferentes ensamblajes se ejecutaban en paralelo. "

Así que sí, las pruebas se ejecutaron en paralelo en VSTS utilizando su práctico indicador 'ejecutar en paralelo', pero no fue lo suficiente, tuvimos que dividir nuestras pruebas arriba en proyectos de prueba independientes. agrupados de forma lógica, por supuesto, no es un proyecto-por-ensayo, que sería ridículo

0
  1. Asegúrese de que la primera columna de la DataTable es un identificador único.
  2. Cree un delegado AsyncExecutionTask que acepte un DataRow y no devuelva nada.
  3. Cree una clase estática (ParallelTestin g) con un método AsyncExecutionContext que acepta un DataRow y un delegado AsyncExecutionTask.
  4. En la clase estática, agregue una propiedad BatchStarted estática.
  5. En la clase estática, agregue una propiedad estática AsyncExecutionTests Dictionary.
  6. En el método AsyncExecutionContext agregar lo siguiente:

    public static void AsyncExecutionContext(DataRow currentRow, AsyncExecutionTask test) 
    { 
        if(!BatchStarted) 
        { 
         foreach(DataRow row in currentRow.Table) 
         { 
          Task testTask = new Task(()=> { test.Invoke(row); }); 
          AsyncExecutionTests.Add(row[0].ToString(), testTask); 
          testTask.Start(); 
         } 
         BatchStarted = true; 
        } 
        Task currentTestTask = AsyncExecutionTests[row[0].ToString()]; 
        currentTestTask.Wait(); 
        if(currentTestTask.Exception != null) throw currentTestTask.Exception; 
    } 
    
  7. Ahora utiliza la clase de este modo:

    [TestMethod] 
    public void TestMethod1() 
    { 
        ParallelTesting.AsyncExecutionContext(TestContext.DataRow, (row)=> 
         { 
          //Test Logic goes here. 
         } 
        ); 
    } 
    

Nota: Usted tendrá que hacer un poco de retoques con excepciones para hacer que burbujeen correctamente (puede tener una excepción agregada aquí, necesitará la primera excepción). La cantidad de tiempo que muestra ejecutar cada prueba ya no será precisa. También querrá limpiar la clase ParallelTesting después de que se complete la última fila.

Cómo funciona: La lógica de prueba se envuelve en una lambda y se pasa a una clase estática que ejecutará la lógica una vez para cada fila de datos de prueba la primera vez que se invoca. Las llamadas sucesivas a la clase estática simplemente esperan a que finalice la tarea de prueba prearrancada.

De esta forma, cada llamada que realiza el marco de prueba al TestMethod simplemente recopila los resultados de la prueba correspondiente que ya se ejecutó.

mejoras posibles:

  • Hacer AsyncExecutionContext toman un parámetro maxSynchronousTasks.
  • Mire cómo el marco mueve trazas de pila completas a través del código no administrado para ver si la excepción Task.Exception se puede pasar al marco de prueba visual studio sin reiniciar y destruir la pila stacktrace.
Cuestiones relacionadas