65.000.000.000运行测试


50

我被问到如何运行一套65.000.000.000个测试,而我想知道拥有如此大量测试的项目是否正常?

您是否从事过具有这种特征的项目?


32
650 亿(10e9)测试?这是实际问题还是面试问题?

40
我非常想知道谁编写了650亿份测试以及花了多少年时间。
钻机

46
如果有650亿个测试,那么如果您每秒可以运行1000个测试,则大约需要2年才能运行。10,000次测试/秒要花两个月的时间。每秒100,000次测试大约需要一周。这说明了在合理的时间范围内运行测试的一些严肃处理能力。

20
我不想成为编写可追溯性矩阵的人……
mouviciel 2013年

23
@DanPichelman-显然,您需要再编写十亿个测试,以测试测试生成器正确生成了测试。
Bobson

Answers:


103

有了650亿次测试,听起来就像是被要求测试所有可能的输入。这没有用-实际上,您实际上是在测试处理器是否正常运行,而不是代码正确。

您应该改为测试等效类。这将大大减少您的测试输入范围。

还要考虑是否可以将系统细分为更小的部分。每一块都很容易进行隔离测试,然后您可以执行一些集成测试,将所有部分组合在一起。

如果您仍然希望其中一些输入组合有效,可以尝试进行模糊测试。测试很多不同的输入将获得一些好处,但是无需运行全部650亿个输入。


12
+1,特别是对于“您实际上将测试处理器是否正常运行”
Doc Brown,

4
对于足够简单的功能(位摆弄等),我确实倾向于测试所有可能的值。它是万无一失的,因此比测试(派生的,因此有可能错误的)对等类提供了更多的信心。当然,当您可能投入数十亿美元时,这将不再起作用。
康拉德·鲁道夫

39

如果这是一个真正的测试套件,那么您就不想在任何地方进行开发。

测试人员的整个工作是在充分测试以确保您获得“正确”结果与编写足够可以在合理的时间内运行的测试之间取得平衡。

许多测试可以抽象为“等价类”,这意味着您运行1而不是运行30亿个测试,如果您决定浪费等价物,则可以给您一个合理的置信度,即该等价类中的所有其他测试都能成功运行。运行它们。

您应该告诉正在考虑运行650亿个测试的人,他们需要做得更好,才能将测试抽象为等效类。


彻底但有效地进行+1测试。
Marco Marco

23

通过计算被测系统中所有可能的输入组合,或者通过计算循环复杂度,并假设必须为每个唯一的执行路径编写测试,您很可能得出了650亿个测试的数字。

这不是真正的测试的编写方式,因为正如其他发布者和评论者所指出的那样,执行650 亿个代码所需的技术能力测试是惊人的。这就像编写一个测试,该测试通过插入两个32位值的每个可能排列并检查结果来练习一种将两个整数相加的方法。太疯狂了。您必须划清界限,并确定所有可能的测试用例的子集,这将确保系统在整个输入范围内都能按预期运行。例如。您测试添加一些“普通”数字,测试一些负数方案,测试技术限制(例如溢出方案),以及测试任何会导致错误的方案。如前所述,这些各种类型的测试都具有“等效性等级”。它们使您可以对可能的输入以及任何已知的“异常值”进行代表性采样,

考虑一种基本的代码katas,罗马数字生成器。使用TDD技术以“ dojo”风格执行的任务是编写一个函数,该函数可以接受1到3000之间的任何数字,并为该数字值生成正确的罗马数字。

您不能通过一次编写3000个单元测试并依次传递它们来解决此问题。这太荒谬了;该练习通常需要一到两个小时,并且您需要花费数天的时间测试每个单独的值。相反,您会变得聪明。您从最简单的基本情况(1 ==“ I”)开始,使用“最少代码”策略(return "I";)实施该代码,然后查看所拥有的代码在另一种预期情况下的行为是否不正确(2 ==“ II”)。冲洗并重复;您很有可能用了一些必要的重复替换“ I”字符的方式(例如return new String('I',number);)来替换您的初始实现。显然,这将通过III的测试,因此您无需理会。相反,您编写4 ==“ IV”的测试,您知道当前的实现将不会

或者,以更具分析性的方式,检查代码(或需要这样做)做出的每个条件决策,并编写一个旨在为每个决策的每个可能结果输入代码的测试。如果您有5条if语句(每条语句都具有正确和错误的分支),则每个语句都完全独立于另一个,则您将编写10个测试而不是32个测试。首先,要做出正确的决定,然后在给定条件的情况下输入的代码是正确的。您不必为独立决策的每个可能排列编写测试。如果决策是相关的,则您必须组合测试更多的决策,但是此类组合的测试较少,因为某些决策只有在另一个决策具有特定结果时才会做出。


5

这是“正常”吗?“正常”的定义是平均经验或典型经验。不能说我曾经从事过这样的项目,但是我从事过的项目每百万比特中就有一个被翻转。测试一个人是一个挑战。

可能需要吗?好吧,这取决于项目的保证和细节。首先要理解有点不可思议,但是您的问题只是细节。

正如其他人(MichaelT)所指出的那样,用串行测试来完成此任务的时间使这变得不切实际。因此,并行化成为您的首要考虑。您可以针对这个问题使用多少个测试系统,以及对这些多个系统的结果进行汇总有哪些支持?

您有什么保证可以可靠地复制您正在测试的设备或算法?软件在复制方面相当可靠,但是硬件设备(尤其是第一代)可能会遇到制造问题。在这种情况下,错误的测试失败可能表明算法错误或设备未正确组装。您是否需要区分这两种情况?

您还需要考虑如何验证测试系统本身。假定有这么多测试用例的合理原因,您将需要大量自动化。需要检查该自动化,以确保不会在生成测试用例时出错。抽查错误确实等于在大海捞针。

astechnica链接可能无法了解您的测试注意事项。GPU群集通常用于暴力破解密码。本文引用的内容可以can cycle through as many as 350 billion guesses per second,这样可以使您的65B测试更加直观。这可能是一个不同的领域,但它显示了从不同角度处理任务可能如何产生可行的解决方案。


3

我认为将6.5e + 10测试保持在第一位并不可行,因此运行它们可能没有意义。即使是最大的项目,例如Debian及其所有软件包,也总共只有数亿个SLOC。

但是,无论如何,如果您必须运行大量测试,则有一些策略。

  • 不要全部运行。很有可能不是每个测试都取决于每个代码路径。定义子系统及其测试之间以及测试套件之间的依赖关系,您将只能运行与特定更改相关的单元测试,而只能运行取决于这些单元测试的集成测试,等等。

  • 并行运行它们。拥有如此庞大的代码库,您可能会有一个庞大的构建服务器场(回到JetBrains,这是一个相对较小的操作,过去我们仅在IDEA连续构建/集成服务器场上运行40-50个构建代理)。由于单元测试是独立的,并且集成测试可以重用已经构建的代码,因此测试相对容易并行化。

  • 尽早停止跑步。如果您知道某个特定的测试套件的合理功能取决于另一个测试套件的正确性,则一旦看到一个链接失败,就可以切断整个链。

免责声明:我不是专业的测试工程师。上面撒一粒盐。


5
...当然,在JetBrains,这些构建代理是免费的,因为他们开发TeamCity并完全拥有它。考虑到大约$ 15,000的初始成本,其他“相对较小的操作”可能会引起心脏病(仅针对软件;添加40-50个刀片安装单元和其他硬件,甚至使用免费的Linux发行版托管所有内容)再说一句高级开发人员的年薪)和6500美元的年度维护费,再加上IT人员的时间和技能,使建造场保持嗡嗡作响。
KeithS

0

尽管这里有关于如何通过更少的测试来偷偷摸摸的好建议,但我严重怀疑您的系统只有650亿个输入组合。少于36位输入。假设您已经接受了上面给出的所有建议。

如果每个测试运行大约一毫秒,并且您仅将测试分布在10个处理器(一台普通PC)上,则该测试将运行69天多一点。那是一段时间,但并非完全不合理。分布在100个处理器(一打普通PC或一台合理的服务器PC)上,测试将在7天内完成。您可以每周运行一次以检查回归。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.