Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 使用随机输入测试最佳实践_Unit Testing_Language Agnostic - Fatal编程技术网

Unit testing 使用随机输入测试最佳实践

Unit testing 使用随机输入测试最佳实践,unit-testing,language-agnostic,Unit Testing,Language Agnostic,注意:我将以下几段作为背景。如果你只是想要一个TL;博士,请随意跳到编号的问题,因为它们只与此信息间接相关 我目前正在编写一个python脚本,该脚本可以处理POSIX日期(以及其他内容)。不过,单元测试似乎有点困难,因为可能会遇到如此广泛的日期和时间 当然,对我来说,尝试测试每一个可能的日期/时间组合是不切实际的,所以我想我将尝试一个单元测试,将输入随机化,然后在测试失败时报告输入是什么。从统计学上讲,我认为如果我试着考虑所有潜在的问题区域(由于缺少内容)或测试所有案例(由于完全不可行),假设

注意:我将以下几段作为背景。如果你只是想要一个TL;博士,请随意跳到编号的问题,因为它们只与此信息间接相关

我目前正在编写一个python脚本,该脚本可以处理POSIX日期(以及其他内容)。不过,单元测试似乎有点困难,因为可能会遇到如此广泛的日期和时间

当然,对我来说,尝试测试每一个可能的日期/时间组合是不切实际的,所以我想我将尝试一个单元测试,将输入随机化,然后在测试失败时报告输入是什么。从统计学上讲,我认为如果我试着考虑所有潜在的问题区域(由于缺少内容)或测试所有案例(由于完全不可行),假设我运行了足够的时间,那么我可以实现比我所能实现的更完整的测试

因此,这里有几个问题(主要与上述间接相关):

  • 什么类型的代码适合随机测试?哪些类型的代码不可用?
    • 如何确定使用随机输入运行代码的次数?我问这个问题是因为我想有一个足够大的样本来确定任何bug,但我不想等待一周才能得到结果
    • 这些类型的测试是否非常适合于单元测试,或者是否有其他类型的测试可以配合使用
    • 做这类事情还有其他的最佳实践吗
  • 相关主题:

    关于第三个问题,我认为随机测试不适合单元测试。如果应用于同一段代码,单元测试应该总是成功的,或者总是失败的(即,由于bug导致的错误行为应该是可复制的)。然而,您可以使用随机技术生成一个大型数据集,然后在单元测试中使用该数据集;这没什么问题。

    哇,好问题!一些想法:

    • 随机测试总是一种很好的建立信心的活动,尽管正如您所提到的,它最适合于某些类型的代码
    • 这是一种很好的方法,可以对任何性能可能与执行次数或输入顺序有关的代码进行压力测试
    • 对于相当简单的代码,或者需要有限类型输入的代码,我更喜欢系统测试,它明确地覆盖所有可能的情况、每个不可能的或病理性的情况的样本以及所有边界条件

    我同意费德里科的观点——随机测试会适得其反。如果测试不能可靠地通过或失败,那么很难修复它并知道它已修复。(当然,当引入不可靠的依赖项时,这也是一个问题。)

    然而,您可能希望确保在其他方面具有良好的数据覆盖率。例如:

    • 确保在1900年到2100年之间的每个月的开始、中间和结束都有测试(当然,如果这些测试适合您的代码)
    • 使用多种文化,或“所有文化”,如果已知的话
    • 尝试“第0天”和“每个月底后的一天”等
    简言之,仍然尝试许多值,但要以编程和重复的方式进行。您不需要在测试中尝试将每个值都作为文本-可以围绕测试的一个轴循环所有已知值,等等

    你永远不会得到完整的覆盖,但至少是可以重复的

    编辑:我确信有些地方随机测试是有用的,尽管可能不适用于单元测试。但是,在本例中,我想提出一些建议:使用一个RNG创建一个随机但已知的种子,然后使用该值为一个新的RNG种子,并记录它。这样,如果发生了有趣的事情,您将能够通过使用记录的种子启动RNG来复制它。

    Q1)我发现具有大量并发性的分布式系统是随机测试的良好候选。很难为此类应用程序创建所有可能的场景,但随机测试可能会暴露出您从未想过的问题

    问题2)我想你可以尝试使用统计数据来建立一个关于发现所有“bug”的置信区间。但实际的答案是:尽可能多地进行随机测试

    问题3)我发现随机测试很有用,但在编写了单元、集成和回归测试的常规电池之后。您应该将随机测试作为普通测试套件的一部分进行集成,尽管可能只是一次小规模运行。如果没有其他问题,那么您可以避免测试本身中的比特腐烂,并在团队使用不同的随机输入运行测试时获得少量的覆盖

    Q4)编写随机测试时,请确保将随机种子与测试结果一起保存。没有什么比发现您的随机测试捕获了一个bug,并且无法使用相同的输入再次运行测试更令人沮丧的了。确保您的测试也可以使用保存的种子执行。

    以下几点:

    • 使用随机测试,您无法真正判断一段代码有多好,但可以判断它有多差
    • 随机测试更适合于具有随机输入的东西——一个主要的例子是向用户公开的任何东西。因此,例如,在你的应用程序(或操作系统)上随机点击和键入的东西是对总体健壮性的一个很好的测试
    • 同样,开发人员也算作用户。因此,从您的框架中随机组装GUI的东西是另一个很好的选择
    • 同样,你不会以这种方式找到所有的bug——你要寻找的是“如果我做了一百万件古怪的事情,它们中的任何一件会导致系统损坏吗?”如果不是,你会感到某种程度的自信,你的应用程序/OS/SDK/任何东西可能会在几天内暴露给用户
    • …但更重要的是
      if (a > 0)
          // Do Foo
      else (if b < 0)
          // Do Bar
      else
          // Do Foobar