从多个线程进行单元测试的最佳方法是什么?

时间:2020-03-05 18:46:59  来源:igfitidea点击:

这种情况是我的另一个问题引起的。

基本上,一旦我有了访问文件的代码(将在一分钟内查看答案),什么是测试它的最佳方法?

我正在考虑创建一个仅产生许多BackgroundWorker或者某些东西的方法,并告诉它们全部加载/保存文件,并使用不同的文件/对象大小进行测试。然后,从线程返回响应,以查看它是否失败/成功/使世界崩溃等。

你们能提供关于解决此问题的最佳方法的任何建议吗?正如我之前说过的,这对我来说有点新:)

编辑

在阿贾玛修(Ajmastrean)的帖子之后:

我正在使用控制台应用程序来测试Debug.Asserts :)

更新

我最初使用BackgroundWorker来处理线程(因为我习惯于Windows开发人员),所以我很快意识到,当我执行需要完成多个操作(线程)才能继续的测试时,我意识到这将是可以做到这一点。

然后,我继续关注ajmastrean的帖子,意识到我确实应该使用Thread类进行并发操作。我现在将使用此方法进行重构(尽管使用其他方法)。

解决方案

回答

你的想法应该很好。基本上,我们只希望生成一堆线程,并确保编写该文件的线程花费足够的时间才能真正使读者等待。如果所有线程返回都没有错误,并且没有永远阻塞,则测试成功。

回答

在.NET中,如果不设置ManualResetEvents或者AutoResetEvents,ThreadPool线程将不会返回。对于快速测试方法(更不用说创建,设置和管理的复杂性了),我发现这些方法有些过分了。后台工作者在回调等方面也有点复杂。

我发现可行的方法是

  • 创建线程数组。
  • 设置每个线程的" ThreadStart"方法。
  • 启动每个线程。
  • 在所有线程上联接(阻塞当前线程,直到所有其他线程完成或者中止)
public static void MultiThreadedTest()
{
    Thread[] threads = new Thread[count];

    for (int i = 0; i < threads.Length; i++)
    {
        threads[i] = new Thread(DoSomeWork());
    }

    foreach(Thread thread in threads)
    {
        thread.Start();
    }

    foreach(Thread thread in threads)
    {
        thread.Join();
    }
}

回答

@ajmastrean,因为单元测试结果必须是可预测的,所以我们需要以某种方式同步线程。我看不到不使用事件的简单方法。

我发现ThreadPool.QueueUserWorkItem为我提供了一种测试此类用例的简便方法

ThreadPool.QueueUserWorkItem(x => { 
    File.Open(fileName, FileMode.Open);
    event1.Set(); // Start 2nd tread;
    event2.WaitOne(); // Blocking the file;
});
ThreadPool.QueueUserWorkItem(x => { 
    try
    {
        event1.WaitOne(); // Waiting until 1st thread open file
        File.Delete(fileName); // Simulating conflict
    }
    catch (IOException e)
    {
        Debug.Write("File access denied");
    }
});