Question

Je cherche des pensées générales et / ou des liens sur le sujet en général, bien que ma motivation spécifique à l'heure actuelle sont des tâches liées à l'interface utilisateur rapports d'avancement utilisant BackgroundWorker et / ou TPL. Mon niveau d'expérience avec la programmation async en général est novice. Les outils de test que je connais le mieux sont NUnit et Rhino.

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

  1. Ne pas la peine - il est trop compliqué et vous vent juste au test de la BGW ou TPL.
  2. une sorte de faux ou faux.
  3. Utilisez EventWaitHandles
Était-ce utile?

La solution

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 mon Nito.Async bibliothèque . :)

Tout d'abord, vous voulez définir ce que vous voulez vraiment tester. Voulez-vous simplement pour vérifier si l'action asynchrone est effectuée, ou voulez-vous assurer que vos BGW / tâches sont correctement synchronisées leurs rapports d'avancement de l'interface utilisateur?

Test de l'action est assez simple: il suffit d'attendre jusqu'à ce que l'action soit terminée, puis vérifier postconditions. (Cependant, il faut savoir que le RunWorkerCompleted de BGW sera porté sur un fil de ThreadPool à moins que vous lui donnez un contexte de synchronisation comme dans l'exemple ci-dessous).

synchronisation correcte de test (par exemple, que chaque morceau de code est exécuté sur le fil correct) est plus complexe.

Pour chaque test, vous aurez besoin d'établir un contexte de synchronisation. Ce sera moqueur le contexte de synchronisation de l'interface utilisateur. Ma bibliothèque Nito.Async peut aider à cela; il a une ActionThread qui est un fil séparé qui contient un contexte de synchronisation adapté pour posséder des composants du PAE (par exemple, BGW), et la planification des tâches (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 progrès (et la notification d'achèvement) à cette ActionThread.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top