测试选择技巧,提供大量测试用例

软件测试 自动化测试
2022-01-21 00:09:44

我有大量的测试用例(输入)。我想选择一个可能捕获大多数错误的小子集。测试文献中是否有任何标准或已知技术可以做到这一点?


(如果相关,这是为了帮助进行模糊测试,您可以在其中向程序提供输入并查看它是否崩溃。我可以编译大量种子文件,其中许多可能在他们测试时大致“等效”程序的相同功能集;我想选择其中的一小部分具有良好的多样性,并且它们之间将尽可能多地测试程序,消除重复。我知道一种基于评估语句覆盖率和使用的技术最小集覆盖,但我想知道这是否是测试文献中研究过的那种问题。)

4个回答

您在这里有几个选择。实施和有效性会有所不同,但 IME 都是可行的解决方案。

  1. 覆盖率 - 运行测试更改代码的测试。如果您在给定的构建上运行相同的测试套件两次,您应该得到相同的结果(否则,我们应该讨论不同的东西)。减少测试套件大小的一种技术是只运行那些遇到更改代码的测试。您可以使用代码覆盖率(跟踪哪些测试命中哪些代码行)获得超准确,但即使是功能区域的一些元数据也可以帮助您使用类似的东西。

  2. 随机抽样 - 从整个产品中选择一组随机测试 - 或者更好的是,从每个功能区域中选择一组随机测试。我已经运行了多个实验(并鼓励您自己运行),这些实验表明组成测试套件的 10-15% 测试的随机样本可以高度预测整个测试套件的通过率。如果特定区域的通过率低于预期,您可以选择在该区域运行更多测试。

  3. 您可以对始终通过的测试(尤其是与上面的 #1 结合使用)进行较小的负权重。鉴于之前发现过错误的测试和从未发现过产品问题的测试,我可能会选择之前发现过问题的测试。

还有其他的(测试年龄、产品存在已知错误的区域等),但以上三个是我用于测试选择的主要启发式方法。

如果以下假设成立,您可能需要尝试选择一组满足成对标准的测试用例:

  1. 你可以用一组独立的参数来描述你想测试的行为,每个参数都有一组你想尝试的可能值。
  2. 您可以根据这些参数来描述每个测试用例,例如参数 1 = X,参数 3 = Y。

如果假设 #1 为真,您可以将您的测试计划视为一个组合问题,其中每个测试用例都是(参数 1 的值,参数 2 的值,...,参数 N 的值)的元组。如果有很多参数,并且每个参数都有几个可能的值,那么测试用例的总数(元组的总数)可能会变得难以管理。

成对标准基于这样的想法,即大多数错误来自单个参数值或一对参数的特定值之间的相互作用。这是标准:选择您的测试,以便每对可能的值都至少练习一次。要了解更多信息,请在此论坛中搜索组合测试(我们应该为此制作标签)或在 Google 中搜索“成对测试”。

如果假设 #2 为真,您可能能够选择满足成对标准的测试。

德威,

背景评论

为了回答您提出的问题,我进入了软件测试行业。从那时起,我一直在研究如何(a)创建数量相对较少的最强大的软件测试集,以及(b)测量这些测试集的实际有效性。这是我热衷的话题。(我一定是充满激情或疯狂或两者兼而有之,因为现在是凌晨 5 点 45 分,因为我正在写这篇文章......)

实验设计是一个有数十年历史的领域,致力于回答您的问题,例如,“如果我不能测试所有内容,我应该测试什么?如何在尽可能少的测试中尽可能多地学习?” 基于实验的设计测试设计方法广泛应用于农业、营销、制造和许多其他行业。这些基于实验设计的选择高效测试子集的方法绝对适用于软件测试领域,但只有不到 5% 的软件测试人员使用它们来选择他们的测试。

大约 6 年以来,我一直在软件测试领域强烈地应用来自实验设计的技术。许多论文和经验报告,包括我与 3 位博士在 IEEE Computer 上共同发表的一篇论文,表明这些选择相对少量软件测试的方法效果很好。这些技术(其中大部分在 user246 对此问题的回答中有所提及)包括:

  • 成对测试
  • 组合测试
  • 正交阵列测试 / OATS

针对您的具体问题提出的解决方案

假设您有一个正在测试的系统,其中包含一万亿个可能的测试,您可以考虑执行这些测试,但时间限制不是问题。

情景 1: 您没有关于以下方面的任何信息:

  • 哪些代码刚刚被更改(例如,您想测试整个系统并且它都是从头开始构建的,尚未进行测试),
  • 哪些测试在之前的运行中定期通过(因为在这种情况下,根据定义,之前没有运行过任何测试)

在这种情况下,我强烈建议您使用基于实验设计的组合方法来选择您的测试。(免责声明:我在测量基于实验设计的测试用例选择方法的有效性之后创建了测试用例生成工具 Hexawise,因此我可以公平地指责我有偏见)。

从成对选择的测试开始,在您执行这些测试时,了解更多关于系统、它是如何工作的、它的弱点在哪里等,以及您想到的其他测试想法,然后通过以下方式编辑这些测试: (a) 添加新的测试输入和 (b) 调整测试输入的权重以更多地关注问题区域,以及 (c) 在时间允许的情况下,将生成的测试的覆盖强度提高到 3 路(三个测试的所有可能组合输入将在至少一个测试用例中一起测试)或更高的覆盖强度,如果您正在自动化测试执行。

你会发现这种选择测试用例的方法是:

  • 比手工选择的测试用例集效率更高,因为(a)基于实验的测试设计将大大减少一次又一次测试组合的意外重复,并且(b)基于实验的测试设计将远将覆盖更少的覆盖间隙(例如,100% 的双模故障(AKA 成对缺陷))。

场景 2: 您正在测试同一个被测系统(您可以想到理论上可以执行的一万亿个可能的测试),但这次您确实掌握了以下信息:

  • 哪些代码刚刚被更改(例如,您想测试整个系统并且它都是从头开始构建的,尚未进行测试),
  • 哪些测试在之前的运行中经常通过和失败

在这种情况下,我建议您:

从刚才提到的基于实验设计的选择测试的方法开始,正如 Alan 所提出的,还

  • 更改的代码:特别注意确保您在测试套件中包含测试,以彻底测试最近更改的代码。您可以通过指示您的测试生成工具播种/包含您在它生成的基于实验的测试设计中识别的特定测试来做到这一点。
  • 在之前的运行中比其他测试更经常失败的测试:考虑在你生成的测试集中播种这些测试。

这些方法将为您提供:

  • 在尽可能少的测试中实现最大覆盖率*(两种情况)
  • 最小浪费重复(两种情况)
  • 额外关注高优先级领域(仅限场景 2 - 例如,代码被更改的地方以及已知的问题点在哪里

*值得指出的是,当您使用这种方法选择测试时,您可以选择适合您的彻底性目标和时间限制的覆盖强度。您可以生成几十个 2-way 测试(AKA 成对测试或 allpairs 测试),例如,如果您非常匆忙,或者如果您想要非常彻底的测试,则可以生成几千个 6-way 测试或几百个 4-way 测试。或者介于两者之间的任意数量的测试。

如果您确实必须使用子集,请使用过去最有效地捕获错误的测试用例。

加入一批与系统中风险最大的部分特别相关的测试用例(因为它们变化最大,或者与故障相关的成本更高)。

添加少量其他代表上述案例未涵盖的区域。