3

摘自《Java Concurrency in Practice 》一书,第 12.1 章测试正确性,特别是第 12.1.3 节测试安全性(作者希望设置测试用例以测试有界缓冲区类的数据竞争安全性)

为确保您的测试实际测试您认为它所做的事情,重要的是校验和本身不能被编译器猜到。使用连续整数作为测试数据是个坏主意,因为结果总是相同的,并且可以想象智能编译器可以预先计算它。

为了避免这个问题,应该随机生成测试数据,但是许多其他有效的测试会因随机数生成器 (RNG) 的选择不当而受到影响。随机数生成可以在类和计时工件之间创建耦合,因为大多数随机数生成器类是线程安全的,因此引入了额外的同步。为每个线程提供自己的 RNG 允许使用非线程安全的 RNG。

我不明白作者反对使用随机数生成器生成测试输入的观点。具体来说,随机数生成可以在类和时序工件之间创建耦合对我来说不是很清楚。

  1. 他在这里指的是哪些类和计时工件?
  2. RNG 可以创建什么样的耦合?
4

1 回答 1

7

随机数生成可以在类之间创建耦合,我不清楚计时工件。

考虑到下一句,这一点会更清楚:

因为大多数随机数生成器类都是线程安全的,因此引入了额外的同步

内存同步可能会改变程序的时间。如果您仔细研究Random,您会发现它AtomicInteger在幕后使用了 an ,因此使用它会导致读取和写入内存屏障作为测试数据生成的一部分,这可能会改变其他线程查看数据的方式以及整个应用程序的时序。 .

他在这里指的是哪些类和计时工件?

任何使用线程并依赖内存同步的类都可能受到影响。基本上他们调用的所有线程和类。

RNG 可以创建什么样的耦合?

正如@Bill the Lizard 所评论的那样,这本书是说通过使用 RNG,程序的时间依赖于或受 RNG 同步的影响。

这里真正的教训是,如果可能的话,你注入程序的测试数据应该改变程序的时间。这通常很困难并且可能是不可能的,但目标是在测试中尽可能多地模拟应用程序行为(时序、输入、输出……)。

就解决方案而言,您可以使用另一种不同步的简单随机算法。您还可以生成一个预先存储 10000 个随机数(或您需要的任意数量)的类,然后在不同步的情况下将它们分发出去。但是通过在你的测试中使用一个进行内存同步的类,你正在改变你的程序的时间。

于 2013-09-11T17:45:19.893 回答