草庐IT

关于 scala:ScalaCheck: Gen.choose 输出超出指定范围的值

codeneng 2023-03-28 原文

ScalaCheck: Gen.choose outputting values beyond a specified range

我正在使用 Scalacheck 来查找缺陷,作为作业的一部分。也许令人难以置信的是,我被卡住了,因为它正在生成一对非零整数。

来自我的 IntelliJ 工作表,逐字逐句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.scalacheck._
    import Arbitrary._
    import Gen._
    import Prop._

    implicit lazy val genUnequalIntPairs = for {
      i <- Gen.choose(1,1000)
      j <- Gen.choose(i+1,1000)
      if (i < j)
    } yield (i,j)

    val kk = forAll (genUnequalIntPairs)  {
      case (x,y) => println("x =" + x +", y =" + y)
        x == y
    }

kk.check

因为,我明确提到所选值的最小值为非零,所以我不应该在属性内看到任何零,对吧?至少,这是我的理解。但这就是我所看到的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
x =134, y =547
x =0, y =547
x =0, y =0
x =0, y =274
x =0, y =0
x =0, y =137
x =0, y =0
x =0, y =69
x =0, y =0
x =0, y =35
x =0, y =0
x =0, y =18
x =0, y =0
x =0, y =9
x =0, y =0
x =0, y =5
x =0, y =0
x =0, y =3
x =0, y =0
x =0, y =2
x =0, y =0
x =0, y =1
x =0, y =0
! Falsified after 0 passed tests.
> ARG_0: (0,1)
> ARG_0_ORIGINAL: (134,547)
res0: Unit = ()

这些零是从哪里来的?我错过了什么?也许,一些显而易见的东西,但我的眼睛没有捕捉到它们。

我使用的是 Scalcheck 1.12.1 版

1
Seq("org.scalacheck" %%"scalacheck" %"1.12.1")

任何帮助,不胜感激。

更新 I:正如@samar 所建议的(我还在 gitbook 中找到了相同的参考),我尝试使用这样的过滤器过滤生成器。但运气不佳(代码如下):

1
2
3
4
5
6
7
8
9
10
11
12
implicit lazy val genUnequalIntPairs = for {
  i <- Gen.choose(1,1000).suchThat(_ > 0)
  j <- Gen.choose(i+1,1000).suchThat(_ > 0)
  if (i < j)
} yield (i,j)

val kk = forAll (genUnequalIntPairs)  {
  case (x,y) => println("x =" + x +", y =" + y)
    x == y
}

kk.check

我运行了这段代码大约 6-7 次。这是一个随机输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
x =536, y =730
x =0, y =730
x =0, y =0
x =0, y =365
x =0, y =0
x =0, y =183
x =0, y =0
x =0, y =92
x =0, y =0
x =0, y =46
x =0, y =0
x =0, y =23
x =0, y =0
x =0, y =12
x =0, y =0
x =0, y =6
x =0, y =0
x =0, y =3
x =0, y =0
x =0, y =2
x =0, y =0
x =0, y =1
x =0, y =0
! Falsified after 0 passed tests.
> ARG_0: (0,1)
> ARG_0_ORIGINAL: (536,730)
res0: Unit = ()

更新二:为了确认,我已经按照 Eric 的建议做了这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
implicit lazy val genUnequalIntPairs = for {
  i <- Gen.choose(1,1000)
  j <- Gen.choose(i+1,1000)
  if (i != 0 && j != 0)
} yield {
  (i,j)
}

val kk = forAllNoShrink(genUnequalIntPairs)  {
  case (x,y) => println("x =" + x +", y =" + y)
    x < y
}

kk.check

这行得通:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
x =805, y =1000
x =742, y =926
x =772, y =919
x =219, y =686
x =999, y =1000
x =752, y =792
x =163, y =585
x =721, y =735
x =251, y =866
x =383, y =887
x =797, y =939
x =925, y =947
x =291, y =951
x =502, y =619
x =422, y =756
x =159, y =886
x =49, y =955
x =624, y =819
x =922, y =979
x =881, y =894
x =936, y =952
x =908, y =975
x =802, y =976
x =918, y =946
x =564, y =823
x =544, y =751
x =916, y =938
x =57, y =762
x =614, y =963
x =497, y =986
x =102, y =332
x =264, y =643
x =611, y =720
x =542, y =797
x =704, y =784
Output exceeds cutoff limit.

更新三:
FWIW,我发现通过迁移到 Scalacheck 版本 1.13.1(最初是 1.12.x),我得到以下行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
implicit lazy val genUnequalIntPairs = for {
  i <- Gen.choose(1,1000)
  j <- Gen.choose(1,1000)
  if (i < j)
} yield {
  (i,j)
}

val kk = forAll(genUnequalIntPairs)  {
  case (x,y) => println("x =" + x +", y =" + y)
    x < y
}

kk.check

产生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
x =56, y =752
x =395, y =532
x =468, y =828
x =326, y =749
x =203, y =973
x =294, y =393
x =589, y =975
x =44, y =75
x =406, y =533
x =33, y =381
x =405, y =767
x =13, y =883
x =201, y =341
x =593, y =991
x =636, y =913
x =508, y =782
x =333, y =861
x =306, y =863
x =428, y =537
x =373, y =775
x =74, y =462
x =196, y =299
x =245, y =535
x =312, y =993
x =940, y =989
x =12, y =708

但是通过将条件从小于更改为相等,会发生这种情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
implicit lazy val genUnequalIntPairs = for {
  i <- Gen.choose(1,1000)
  j <- Gen.choose(1,1000)
  if (i < j)
} yield {
  (i,j)
}

val kk = forAll(genUnequalIntPairs)  {
  case (x,y) => println("x =" + x +", y =" + y)
    x == y
}

kk.check

产生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
x =370, y =585
x =0, y =585
x =0, y =0
x =0, y =293
x =0, y =0
x =0, y =147
x =0, y =0
x =0, y =74
x =0, y =0
x =0, y =37
x =0, y =0
x =0, y =19
x =0, y =0
x =0, y =10
x =0, y =0
x =0, y =5
x =0, y =0
x =0, y =3

显然,所应用的条件会覆盖我在生成器中留下的显式指令。这不是有点不直观吗?别人怎么看?

  • 我认为这是一个错误,我提出了它:github.com/rickynils/scalacheck/issues/253
  • 奇怪的。你可以试试: Gen.choose(1,1000) suchThat (_ > 0)
  • @Samar,范围意味着谓词,所以实际上它不应该是必要的。顺便说一句,它也不能解决问题。
  • @Mika\\'il:是的,我知道它有些可疑。只是想看看如果我们增加一个额外的守卫会发生什么。
  • 我在这里添加了另外两个测试用例:github.com/rickynils/scalacheck/issues/253


它可能来自于属性的收缩。改用 forAllNoShrink 试试。

  • 刚刚尝试过 - 甚至没有通过第一次测试。
  • 好吧,如果 x < y,您的测试预计会失败,不是吗?
  • 其实这不是我的代码。还评论说 if 条件仍然会产生问题。
  • 如果您删除条件并使用 forAllNoShrink,您应该不会看到任何带有 0 的值。我仍然认为您遇到了这个问题:stackoverflow.com/questions/20037900/...。
  • 抱歉,回复晚了(这里是清晨)。我提供的代码是一个示例;它只是启动引擎,并没有真正检查任何有意义的事情。这个想法是为了证明它不符合我提供的生产范围。我的理解是"Gen"应该产生测试值,而"Prop"应该把它们放到测试中!为什么 Gen 应该依赖于稍后应用的条件类型?我错过了什么吗?
  • 我已经更新了原始帖子,以确认通过使用"forAllNoShrink"(正如@Eric 所建议的,谢谢),我可以解决最初的问题。但是,我仍然无法解释为什么生成器的行为取决于它应该帮助测试的属性。
  • 这确实是一个错误。"自动缩小属性" - 找到表现出错误行为的最小输入:不应将它们缩小到明确选择的范围以下。
  • 感谢@Samar,确认我的疑问。另外,我接受。埃里克的建议,因为它可以让人摆脱刺激。到目前为止,mikai'l 的 Github 票证包含我在这里分享的所有测试用例。
  • Ricky (github.com/rickynils) 在此处添加了 Scalacheck 行为背后的清晰解释:github.com/rickynils/scalacheck/issues/253。非常感谢,瑞奇@rickard-nillson

有关关于 scala:ScalaCheck: Gen.choose 输出超出指定范围的值的更多相关文章

  1. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  2. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  3. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  4. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  5. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  6. ruby - 如何进行排列以有效地定制输出 - 2

    这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][

  7. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  8. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  9. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  10. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

随机推荐