我想使用scalacheck使用基于属性的测试来测试我的scala程序.我写 :
class MyProperties extends PropSpec with PropertyChecks {
property("My property") {
val myProperty: org.scalacheck.Prop = new MyProperty
// some code I need to set myProperty
myProperty.check
}
}
Run Code Online (Sandbox Code Playgroud)
但这似乎是错的,因为当我使用ScalaTest运行这个类时,我进入控制台:
Run starting. Expected test count is: 1
MyProperties:
! Falsified after 51 passed tests.
> ARG_0: myGeneratedArgument
- My property
Run completed in 1 second, 623 milliseconds.
Total number of tests run: 1
Suites: completed 1, aborted 0
Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
All …
Run Code Online (Sandbox Code Playgroud) 我正在运行ScalaCheck
测试sbt
,如果测试失败,因为测试中的代码抛出异常,测试报告会显示失败的测试,抛出的异常和消息,但不会显示整个堆栈跟踪(请注意Exception: java.lang.NullPointerException: exception
下面的异常消息) .
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to scalacheck (in build file:/Users/jacek/sandbox/scalacheck/)
[info] Updating {file:/Users/jacek/sandbox/scalacheck/}scalacheck...
[info] Resolving jline#jline;2.11 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/scalacheck/target/scala-2.11/test-classes...
[info] ! String.throw exception: Exception raised on property evaluation.
[info] > ARG_0: ""
[info] > Exception: java.lang.NullPointerException: exception
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
[error] Error during tests:
[error] StringSpecification
[error] (test:test) sbt.TestsFailedException: Tests …
Run Code Online (Sandbox Code Playgroud) 我是第一次尝试ScalaCheck,我想生成一个有序的Ints数组.
我阅读了文档并做了一些搜索,但我找不到办法.
有人可以对此有所了解吗?
谢谢
在Scala中,我使用Parser Combinators库实现了语法.现在,我想要做的是从解析器组合器库中生成给定语法的随机字符串.
在我看来,ScalaCheck库在某种程度上与Parser Combinators相反,因为它结合了生成器而不是解析器.
是否已经有一种使用Parser Combinators或ScalaCheck生成字符串的方法,或者是否有直接的方法将Parser Combinator转换为生成器?
code-generation scala parser-generator quickcheck scalacheck
我正在使用标题中提到的框架,具有以下配置:
"com.typesafe.play" % "sbt-plugin" % "2.4.2"
"org.scalacheck" %% "scalacheck" % "1.12.4" % "test"
"org.scalatest" %% "scalatest" % "2.2.5" % "test"
"org.scalatestplus" %% "play" % "1.4.0-M4" % "test"
Run Code Online (Sandbox Code Playgroud)
通过简单的测试来演示:
class User
extends FlatSpec
with Matchers
with Checkers {
it should "do scala check stuff" in {
check( ( a: Int ) ? a > 100 )
}
it should "do scala check stuff II" in {
check( ( a: Int ) ? true )
}
}
Run Code Online (Sandbox Code Playgroud)
它看起来基本上可行,但sbt test
输出却异常混乱.
[project-id] …
Run Code Online (Sandbox Code Playgroud) 我想在ScalaCheck中创建一个生成器,生成介于1和100之间的数字,但是对于接近1的数字具有钟形偏向.
Gen.choose()
在最小值和最大值之间随机分配数字:
scala> (1 to 10).flatMap(_ => Gen.choose(1,100).sample).toList.sorted
res14: List[Int] = List(7, 21, 30, 46, 52, 64, 66, 68, 86, 86)
Run Code Online (Sandbox Code Playgroud)
并且Gen.chooseNum()
对上限和下限有额外的偏见:
scala> (1 to 10).flatMap(_ => Gen.chooseNum(1,100).sample).toList.sorted
res15: List[Int] = List(1, 1, 1, 61, 85, 86, 91, 92, 100, 100)
Run Code Online (Sandbox Code Playgroud)
我想要一个choose()
能给我一个看起来像这样的结果的函数:
scala> (1 to 10).flatMap(_ => choose(1,100).sample).toList.sorted
res15: List[Int] = List(1, 1, 1, 2, 5, 11, 18, 35, 49, 100)
Run Code Online (Sandbox Code Playgroud)
我看到了,choose()
并chooseNum()
采用隐含的选择特征作为参数.我应该用吗?
当我使用ScalaCheck的Gen.pic时,我观察到以下意外行为,对我而言,这表明它的选择并不是随机的,即使它的文档是这样说的:
/** A generator that picks a given number of elements from a list, randomly */
Run Code Online (Sandbox Code Playgroud)
在设置之后,我按顺序运行了以下三个小程序(在2天的时间内,在不同的时间,因为它可能很重要)
implicit override val generatorDrivenConfig = PropertyCheckConfig(
maxSize = 1000,
minSize = 1000,
minSuccessful = 1000)
Run Code Online (Sandbox Code Playgroud)
获得合适的样本量.
计划#1
val set = Set(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,37,38,39,40,
41,42,43,44,45,46,47,48,49,50)
// Thanks to @Jubobs for the solution
// See: http://stackoverflow.com/a/43825913/4169924
val g = Gen.pick(3, set).map { _.toList }
forAll (g) { s => println(s) }
Run Code Online (Sandbox Code Playgroud)
在2个不同的运行中生成的3000个数字中,我得到了一个惊人的相似,非常随机的分布(数字是四舍五入的,只列出前5个,从这里开始的所有列表):
我正在尝试为 scala 中的函子编写通用定律,格式可以在 scalacheck 测试中重用于许多函子。定律应该由构造函数 F[_] 和元素类型参数化,比如 A。
理想情况下,我会写这样的东西:
def functorLaw[A, F[_] :Arbitrary] (fn :Functor[F]) :Prop = forAll { (fa :F[A]) => true }
Run Code Online (Sandbox Code Playgroud)
(我使用 true 而不是法体,因为确切的计算对我的问题无关紧要)
然而,我能破解的最好方法是将它包装在一个抽象类中,为生成任意 F[A] 值提供一个隐含的抽象:
abstract class FunctorSpec[A :Arbitrary, F[_]] extends Properties("foo") {
implicit def arbitraryFA :Arbitrary[F[A]]
def functorLaw (fn :Functor[F]) :Prop = forAll { (fa :F[A]) => true }
}
Run Code Online (Sandbox Code Playgroud)
现在这可行,但并不理想。我需要为每个测试实例化我想要运行的类,并且需要在那里提供任意 FA 函数。当然,编译器需要这个函数,但是对于很多类型,它们存在应该执行它的隐式(例如对于 List[Int])。但是编译器将无法猜测这些隐式提供了任意FA,因此我需要自己实现这一点,这是非常重复的。例如:
object IntListFunctorSpec extends FunctorSpec[Int, List] {
def arbitraryFA :Arbitrary[List[Int]] = Arbitrary(arbitrary[List[Int]])
...
}
Run Code Online (Sandbox Code Playgroud)
我认为我不需要告诉 scalacheck 如何构建 int 列表。任何建议如何更优雅地做到这一点?
我尝试了其他关于更高级类型边界的问题,但我无法弄清楚如何使用它们,尽管它们听起来很接近。所以我想我会问。
我正在尝试使用 C 语言修复一个很好的数字生成器uint64_t
。这是我目前所拥有的。
def uInt64s : Gen[BigInt] = Gen.choose(0,64).map(pow2(_) - 1)
Run Code Online (Sandbox Code Playgroud)
这是一个好的开始,但它只生成数字2^n - 1
。有没有更有效的方法来生成随机 BigInts 同时保留数字范围0 <= n < 2^64
?
我试图确保我的ScalaCheck属性运行500次而不是默认的100次。我在配置它时遇到了麻烦。
class BlockSpec extends Properties("BlockSpec") with BitcoinSLogger {
val myParams = Parameters.default.withMinSuccessfulTests(500)
override def overrideParameters(p: Test.Parameters) = myParams
property("Serialization symmetry") =
Prop.forAll(BlockchainElementsGenerator.block) { block =>
logger.warn("Hex:" + block.hex)
Block(block.hex) == block
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我实际运行此测试时,它只说成功通过了100个测试
编辑:
$ sbt
[info] Loading project definition from /home/chris/dev/bitcoins-core/project
[info] Set current project to bitcoin-s-core (in build file:/home/chris/dev/bitcoins-core/)
> test-only *BlockSpec*
[info] + BlockSpec.Serialization symmetry: OK, passed 100 tests.
[info] Elapsed time: 1 min 59.775 sec
[info] ScalaCheck
[info] Passed: Total 1, Failed 0, Errors 0, …
Run Code Online (Sandbox Code Playgroud) scala ×10
scalacheck ×10
scalatest ×2
eclipse ×1
generics ×1
polymorphism ×1
quickcheck ×1
random ×1
sbt ×1