attività asincrone Test Driven
-
09-10-2019 - |
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:
- Non preoccupatevi - è troppo complicato e basta vento fino testare la BGW o TPL.
- fare una sorta di falso o finto.
- Usare EventWaitHandles
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.