测试中的随机性

发表于:2014-08-25来源:uml.org.cn作者:Dr. James McCaffrey点击数: 标签:软件测试
创建和使用随机测试用例数据是一项基本的软件测试技能。尽管多数测试用例数据由所测试系统的特定输入数据以及特定预期值/状态组成,但您几乎始终都想让系统也受到随机测试用例
生成统一的随机数字
分析模式随机性
混排项目列表
生成正态/高斯数字
总结

  创建和使用随机测试用例数据是一项基本的软件测试技能。尽管多数测试用例数据由所测试系统的特定输入数据以及特定预期值/状态组成,但您几乎始终都想让系统也受到随机测试用例输入数据的测试。通常,您这样做是为了了解向应用程序发送大量不同的输入数据是否会导致系统崩溃或引发异常。在本月的专栏中,我将阐述在 Microsoft? .NET Framework 环境中处理随机测试用例数据时的四个常见任务:

  生成伪随机数字(Knuth 算法)

  分析模式随机性(Wald-Wolfowitz 检验)

  混排项目列表(Fisher-Yates 算法)

  生成高斯数字(Box-Muller 算法)

  让我们看一下图 1 中的示例。输出的第一部分显示了使用 .NET Framework 的 Random 对象生成基本随机数字的结果。尽管您可能很熟悉此方法,但我还是要指出如何避免常见缺陷。输出的第二部分体现了一个非常实用但却鲜为人知的方法,该方法用来分析由任意符号组成的模式是否具备随机性。通常,该方法广泛应用于软件开发中,而不只是应用于测试方面。图 1 的第三部分表明了混排项目列表的结果,该结果异常错综复杂。

  图 1 随机方法演示

  我将详细说明为什么许多混排实现方法表面上似乎正确,而事实上却完全错误。图 1 中输出的最后一部分表明了生成按正态钟形曲线分布的一组数字的结果。除了是一种非常实用的方法之外,该算法的实现细节凭其自身的性能而得以关注,将成为您个人编码工具箱的一个有价值的补充部分。

  生成统一的随机数字

  随机测试用例生成中的最基本任务是生成一个某特定值域内的随机数字(整数或浮点数)。这通常通过 System.Random 类来实现。假定有以下代码:

Random objRan = new Random(5);
int n = objRan.Next(7);
Console.WriteLine("[0,6] 值域中的随机整数是 " + n);

n = objRan.Next(3, 13);
Console.WriteLine("[3,12] 值域中的随机整数是 " + n);

  以 Random 对象为例,传入一个种子值(在本例中为 5)。该种子值用于为表现出真正随机数字许多特性的某个数字序列设置起点。序列是确定的(这些数字是从输入种子值或序列中前几个数字时所用的数学公式而生成),因此由 System.Random 生成的数字从技术角度来讲是伪随机数字,但在非正式使用情况下或上下文明确时,通常将其称为随机数字(如此例所示)。我选择的种子值具有任意性。如果我使用不接受种子值的重载 Random 构造函数,则将使用从系统时钟派生的值。如果在随后测试运行时,您需要重新创建随机数字序列(通常情况是这样),则应提供一个种子值。有关伪随机数字生成器种子值的讨论是一个重要且复杂的主题,抱歉的是,它不在本专栏的讨论范围内。

  生成随机整数的最简单方法是调用 Random.Next 方法,传入单个整数参数。返回值是伪随机列表中的下一个整数,此值大于或等于 0 且绝对小于该参数。因此,以下调用将返回一个介于 0 和 9 之间(包括 0 和 9)而不是介于 0 和 10 之间(包括 0 和 10)的数字:

int n = objRan.Next(10);

  Random.Next 方法的重载将接受两个整数参数并返回一个大于或等于第一个参数且绝对小于第二个参数的整数。如果您要模拟的测试用例数据类似于滚动的普通六面骰子,要得到一个介于 1 和 6 之间(包括 1 和 6)的随机数字,则调用可能如下所示:

int roll = objRan.Next(1, 7);

原文转自:http://www.uml.org.cn/Test/200611225.htm