测试驱动的异步任务

Ber*_*ryl 2 c# unit-testing asynchronous task-parallel-library async-await

我正在寻找关于该主题的一般想法和/或链接,尽管我目前的具体动机是与使用BackgroundWorker和/或TPL的进度报告相关的UI任务.我对异步编程的经验水平一般是新手.我最熟悉的测试工具是NUnit和Rhino.

一些头脑风暴突破了我的头脑:

  1. 不要打扰 - 它太复杂了,你只是最终测试BGW或TPL.
  2. 制作某种假货或假货.
  3. 使用EventWaitHandles

Ste*_*ary 6

单元测试异步代码并不是世界上最简单的事情,正如我在为Nito.Async库编写单元测试时所学到的.:)

首先,您要定义实际要测试的内容.您是否只想测试是否执行了异步操作,还是要确保您的BGW /任务正确同步其UI进度报告?

测试操作非常简单:只需等待操作完成,然后检查后置条件.(但是,请注意,除非您像下面的示例那样为其提供同步上下文,否则RunWorkerCompleted将在ThreadPool线程上引发BGW ).

测试正确的同步(例如,每条代码在正确的线程上运行)更复杂.

对于每个测试,您需要建立同步上下文.这将模拟UI同步上下文.我的Nito.Async库可能对此有所帮助; 它具有ActionThread一个单独的线程,其包含适合于拥有EAP组件(例如,BGW)和调度任务(例如TaskScheduler.FromCurrentSynchronizationContext)的同步上下文.

它可以像这样使用(使用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.
  }
}
Run Code Online (Sandbox Code Playgroud)

我发现Thread.CurrentThread.ManagedThreadId并且Thread.CurrentThread.IsThreadPoolThread是检查正确同步的最简单方法.如果您的测试代码是从内部运行的ActionThread.Do,那么它应该将其进度更新(和完成通知)与其同步ActionThread.

很多Nito.Async单元测试都ActionThread以这种方式使用,因此您可以在那里查看各种示例.

  • PS EAP = [基于事件的异步模式](http://msdn.microsoft.com/en-us/library/hkasytyf.aspx); TAP =基于任务的异步模式. (2认同)