Pregunta

Busco pensamientos y / o enlaces generales sobre el tema en general, aunque mi motivación específica por el momento son las tareas de interfaz de usuario relacionados con el progreso de informes utilizando BackgroundWorker y / o TPL. Mi nivel de experiencia con la programación asincrónica, en general, es novato. Las herramientas de prueba que mejor conozco son NUnit y Rhino.

Algunos de lluvia de ideas las ideas de la parte superior de mi cabeza:

  1. No se moleste - que es demasiado complicado y que sólo terminan probando el BGW o TPL.
  2. Hacer una especie de falso o simulado.
  3. Use EventWaitHandles
¿Fue útil?

Solución

Unidad de prueba del código asíncrono no es la cosa más sencilla del mundo, como he aprendido al escribir pruebas unitarias para mi Nito.Async biblioteca. :)

En primer lugar, se quiere definir lo que realmente quiere a prueba. ¿Usted sólo quiere comprobar si se realiza la acción asíncrona, o quiere asegurarse de que sus BGW / tareas se sincronizan correctamente sus informes progreso interfaz de usuario?

Pruebas de la acción es bastante sencillo: sólo tiene que esperar hasta que la acción se ha completado y luego comprobar si hay condiciones posteriores. (Sin embargo, tenga en cuenta que la RunWorkerCompleted BGW será levantado en un hilo ThreadPool a menos que darle una contexto de sincronización como el ejemplo a continuación).

Pruebas de sincronización adecuada (por ejemplo, que cada pieza de código se ejecuta en el hilo correcto) es más compleja.

Para cada prueba que necesita para establecer un contexto de sincronización. Esto se burlando el contexto de sincronización de interfaz de usuario. Mi biblioteca Nito.Async puede ayudar con eso; tiene un ActionThread que es un hilo separado que contiene un contexto de sincronización adecuado para ser dueño de los componentes de EAP (por ejemplo, BGW) y la programación de tareas (por ejemplo, TaskScheduler.FromCurrentSynchronizationContext).

Se puede utilizar como este (utilizando un ejemplo MSTest):

[TestMethod]
public void Test()
{
  using (ActionThread thread = new ActionThread())
  {
    thread.Start();

    // Anything passed to Do is executed in that ActionThread.
    thread.Do(() =>
    {
      // Create BGW or call TaskScheduler.FromCurrentSynchronizationContext.
    });

    // The thread is gracefully exited at the end of the using block.
  }
}

Me parece Thread.CurrentThread.ManagedThreadId y Thread.CurrentThread.IsThreadPoolThread ser las formas más sencillas para comprobar la correcta sincronización. Si su código de prueba se ejecuta desde ActionThread.Do, entonces se debe sincronizar sus actualizaciones de progreso (y la notificación de finalización) para que ActionThread.

Muchas de las pruebas unitarias Nito.Async utilizar ActionThread de esta manera, por lo que podía ver allí durante varios ejemplos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top