为什么.NET单元测试覆盖了与硬件相关的Parallel.foreach循环?

Ste*_*ers 7 .net c# unit-testing moq parallel.foreach

我正在使用Moq对包含Parallel.foreach循环的一些代码进行单元测试.

排列相套最多4个例外的环内被抛出,然后包装在一个AggregateException.

这传递了我的i7处理器,我检查了代码.

之后,一位同事抱怨说他没有过世.事实证明Parallel.foreach,在轰炸之前,他的Core2duo上只产生了2个线程,因此只有2个例外被包含在内AggregateException.

问题是如何处理这个问题,以便单元测试不依赖于处理器架构?几点想法: -

  1. 一篇关于手动添加例外的微软文章,AggregateException但我们并不热衷于这样做,因为如果出现问题,循环应尽早退出.
  2. ParallelOptions.MaxDegreeOfParallelism可以对使用的线程数设置上限.但除非将其调低为1(这似乎更像是作弊而不是正确的单元测试),单元测试如何知道实际使用了多少线程,从而设置了安排断言阶段?

Jar*_*rek 6

你不应该测试类似的东西 - 它的实现细节.

事情是 - Parallel.ForEach将处理元素,直到它获得异常.当异常发生时,它将停止处理任何新元素(但将完成当前处理的元素的处理)然后抛出AgregateException.

现在 - 你的i7 CPU有4个核心+超线程,这导致产生更多的线程进行处理,因此你可以获得更多的异常(因为例如当发生异常时可以同时处理4件事情).但是在只有2个核心的Core2Duo上,只会同时处理2个项目(这是因为TPL足够智能,只能创建足够的线程进行处理,而不是可用的核心).

测试实际发生4个异常会让您不知情.它取决于机器.您应该测试是否至少发生了一个异常 - 因为这是您所期望的.如果未来的用户将在旧的单核机器上运行您的代码,他将收到这个例外AggregateException.

抛出异常的数量是特定于机器的,例如计算时间 - 您不会断言计算某些内容的长度,因此在这种情况下您不应断言异常数量.

  • 顺便说一句,这不仅仅是关于CPU.具体的行为,还可以根据什么其他的在同一过程中的线程池,其他进程正在使用的CPU是什么,在循环中的操作是否阻塞和其他可能的事物运行时更改. (2认同)