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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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 如何保证FsCheck的再现性_Unit Testing_F#_Nunit_Fscheck - Fatal编程技术网

Unit testing 如何保证FsCheck的再现性

Unit testing 如何保证FsCheck的再现性,unit-testing,f#,nunit,fscheck,Unit Testing,F#,Nunit,Fscheck,我们希望在持续集成中使用FsCheck作为单元测试的一部分。因此,这种确定性和可再现性行为对我们来说非常重要 FsCheck作为一个随机测试框架,可以生成可能有时会中断的测试用例。关键是,我们不仅使用必须为每个输入保存的属性,比如说List.rev>>List.rev==id。但是,我们做一些数字运算,一些测试用例可能会因为条件恶劣而导致测试中断 问题是:我们如何保证,一旦测试成功,它将永远成功 到目前为止,我看到了以下选项: 硬编码种子,例如0。这将是最简单的解决办法 制作非常具体的自定义生

我们希望在持续集成中使用FsCheck作为单元测试的一部分。因此,这种确定性和可再现性行为对我们来说非常重要

FsCheck作为一个随机测试框架,可以生成可能有时会中断的测试用例。关键是,我们不仅使用必须为每个输入保存的属性,比如说
List.rev>>List.rev==id
。但是,我们做一些数字运算,一些测试用例可能会因为条件恶劣而导致测试中断

问题是:我们如何保证,一旦测试成功,它将永远成功

到目前为止,我看到了以下选项:

  • 硬编码种子,例如0。这将是最简单的解决办法
  • 制作非常具体的自定义生成器,避免出现不好的示例。当然有可能,但结果可能相当困难,特别是当有许多对象要生成时
  • 请接受它,在某些情况下,由于病理情况,构建可能是红色的,只需重新运行即可
在这种情况下使用FsCheck的惯用方法是什么

某些测试用例可能由于条件恶劣而导致测试中断

听起来您需要一个条件属性:

let isOk x =
    match x with
    | 42 -> false
    | _ -> true

let MyProperty (x:int) = isOk x ==> // check x here...
(假设你不喜欢42这个数字。)

(我开始写评论,但评论太长了,我想它应该有自己的答案)

使用FsCheck测试属性是很常见的,但它并不适用于每个输入。例如,如果您为
List
运行FsCheck,它将很容易地驳斥您的
List.rev
示例

数值稳定性本身就是一个棘手的问题——这里没有任何非确定性的FsCheck(FsCheck是完全确定性的,它只是一个输入生成器…)。您所指的“非确定性”可能是某些处理器中浮点运算中的错误等。但即使是那样,你不想知道他们吗?若你们的算法对于一类输入是数值不稳定的,你们不想知道吗?如果你不这么做,在我看来,你是在为一些真正的非决定论做准备……在生产中

在FsCheck中编写不适用于给定类型的所有输入的属性的惯用方法是编写生成器和收缩器。您可以使用
==>
作为实现这一点的一个步骤,但它不能很好地扩展到复杂的前提条件。你说这可能会变得相当困难——这是真的,因为我保证你会学到一些关于你的代码的东西。一件好事


修复种子是个坏主意,除了复制以前发现的bug。我的意思是,在实践中,您会怎么做:继续重新运行测试,直到测试通过,然后修复种子并声明“工作完成”

如果生成的大部分值被前提条件拒绝,这不是一个好主意-这使得测试用例生成非常低效。改用自定义生成器。此外,对于复杂的测试,请确保前提条件不真正属于测试。这种方法适用于我的特定情况。它可能在运行100个测试的20次中有一次失败。但我知道不要用它来过滤可能的案例。不,它不是“完成任务”。通常,我们使用比实际需要更具攻击性的测试用例。是的,更多地了解细微的bug,或者知道它何时会崩溃,这绝对是一件好事。事实上,我很感兴趣的是什么是正确的处理方法。但是,是的,我想发电机+收缩机是最好的选择。如果没有其他原因,那么就要确切地知道什么是有效的,什么是无效的。很抱歉,重读时我听起来像个巨魔。我试图通过陈述一个明显的坏习惯来挑衅,而不是暗示你真的会那样做。。。