2

Je cherche des idées générales et/ou des liens sur le sujet en général, bien que ma motivation spécifique pour le moment soit les tâches d'interface utilisateur liées aux rapports d'avancement utilisant BackgroundWorker et/ou TPL. Mon niveau d'expérience avec la programmation asynchrone en général est novice. Les outils de test que je connais le mieux sont NUnit et Rhino.Tâches asynchrones pilotées par test

Quelques idées de remue-méninges sur le haut de ma tête:

  1. Ne vous embêtez pas - il est trop compliqué et vous liquidez juste tester la BGW ou TPL.
  2. Faites une sorte de faux ou de faux.
  3. Utilisez EventWaitHandles
+0

Pouvez-vous être un peu plus précis? Peut-être poster du code afin que nous puissions voir comment votre code est structuré et répondre en conséquence ... – BFree

+0

@BFree. Oui, la question est délicate et peut-être trop vague, mais tout le code que j'ai maintenant ne se prête pas à un court message ou à une réponse rapide. Si la question était de commencer à utiliser des simulacres, par exemple, peut-être que quelqu'un suggèrerait Rhino avec le wiki et peut-être un bon post de blog sur le démarrage avec quelques conseils de leur propre expérience. Cheers – Berryl

Répondre

6

tests unitaires du code asynchrone n'est pas la chose la plus simple du monde, comme je l'ai appris lors de l'écriture des tests unitaires pour ma bibliothèque Nito.Async. :)

D'abord, vous voulez définir ce que vous voulez réellement tester. Voulez-vous simplement tester si l'action asynchrone est effectuée ou voulez-vous vous assurer que vos tâches/tâches BGW synchronisent correctement leurs rapports d'avancement de l'interface utilisateur?

Le test de l'action est assez simple: attendez que l'action soit terminée et vérifiez les postconditions. (Cependant, sachez que le BGW RunWorkerCompleted sera déclenché sur un thread ThreadPool sauf si vous lui donnez un contexte de synchronisation comme dans l'exemple ci-dessous).

La vérification d'une synchronisation correcte (par exemple, que chaque partie du code s'exécute sur le bon thread) est plus complexe.

Pour chaque test, vous devez établir un contexte de synchronisation. Cela se moquera du contexte de synchronisation de l'interface utilisateur. Ma bibliothèque Nito.Async peut aider avec cela; il a un ActionThread qui est un thread séparé qui contient un contexte de synchronisation approprié pour posséder des composants EAP (par exemple, BGW) et des tâches de planification (par exemple, TaskScheduler.FromCurrentSynchronizationContext).

Il peut être utilisé comme celui-ci (en utilisant un exemple 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. 
    } 
} 

je trouve Thread.CurrentThread.ManagedThreadId et Thread.CurrentThread.IsThreadPoolThread être les moyens les plus faciles à vérifier pour la synchronisation appropriée. Si votre code de test est exécuté à partir de ActionThread.Do, il doit synchroniser ses mises à jour de progression (et la notification d'achèvement) à ActionThread.

Un grand nombre de tests unitaires Nito.Async utilisent ActionThread de cette manière, vous pouvez donc y rechercher divers exemples.

+0

Maintenant * c'est * ce dont je parle! Je suppose que vous avez écrit ceci pour rendre la vie async plus facile et il n'y a pas de véritable alternative. Vos tests sont-ils inclus dans le téléchargement? A quel point doit-on connaître TPL pour comprendre votre code? Je regarde votre blog maintenant. Bravo – Berryl

+0

En regardant votre code ProgressReporter sur votre blog, par exemple, et comment cela pourrait être testé sans avoir besoin de faire un formulaire de victoire ou d'un autre projet ui. Des trucs géniaux !! – Berryl

+0

La bibliothèque a été écrite à l'origine pour aider à écrire des composants EAP. Cependant, notez que les directions futures de VS (comme indiqué par le VS CTC Async) introduisent des TAP qui remplaceront (j'espère) EAP. Certaines parties de Nito.Async ne s'appliqueront donc plus dans quelques années. Il a toujours plusieurs composants utiles, tels que 'ActionThread'. La classe a deux buts: permettre aux programmes de service de console/Windows d'avoir un contexte de synchronisation; et pour rendre mes tests unitaires plus faciles à écrire. :) –

Questions connexes