Domanda

Sto cercando i pensieri generali e / o link sul tema in generale, anche se la mia motivazione specifica al momento sono compiti UI connessi al progresso segnalazione utilizzando BackgroundWorker e / o di TPL. Il mio livello di esperienza con la programmazione asincrona in generale è alle prime armi. Gli strumenti di test che conosco meglio sono NUnit e Rhino.

Alcuni brain storming idee fuori dalla parte superiore della mia testa:

  1. Non preoccupatevi - è troppo complicato e basta vento fino testare la BGW o TPL.
  2. fare una sorta di falso o finto.
  3. Usare EventWaitHandles
È stato utile?

Soluzione

Test delle unità di codice asincrono non è la cosa più semplice del mondo, come ho imparato durante la scrittura di unit test per il mio Nito.Async biblioteca . :)

In primo luogo, si vuole definire che cosa si vuole realmente prova. Vuoi solo per verificare se l'azione viene eseguita asincrono, o vuoi per assicurare che i vostri BGW / compiti vengono sincronizzate correttamente i loro rapporti progresso UI?

Test l'azione è piuttosto semplice: basta aspettare fino a quando l'azione è completa e quindi verificare la presenza di post-condizioni. (Tuttavia, essere consapevoli del fatto che la RunWorkerCompleted BGW verrà sollevata su un thread ThreadPool a meno che non si dà un contesto di sincronizzazione, come nell'esempio qui sotto).

Test corretta sincronizzazione (per esempio, che ogni pezzo di codice viene eseguito sul thread corretto) è più complesso.

Per ogni test è necessario stabilire un contesto di sincronizzazione. Questo sarà scherno contesto sincronizzazione UI. La mia biblioteca Nito.Async può aiutare in questo; ha un ActionThread che è un thread separato che contiene un contesto di sincronizzazione adatto per possedere componenti EAP (ad esempio, BGW) e compiti di programmazione (ad esempio, TaskScheduler.FromCurrentSynchronizationContext).

Può essere utilizzato in questo modo (con un esempio 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.
  }
}

Trovo Thread.CurrentThread.ManagedThreadId e Thread.CurrentThread.IsThreadPoolThread ad essere il modo più semplice per verificare il corretto sincronizzazione. Se il codice di prova viene eseguito dall'interno ActionThread.Do, allora dovrebbe sincronizzare i propri aggiornamenti sui progressi (e la notifica di completamento) a quella ActionThread.

Un sacco di test di unità Nito.Async utilizzare ActionThread in questo modo, così si potrebbe cercare lì per vari esempi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top