你为什么需要scalacheck中的Arbitraries?
我想知道为什么需要Arbitrary因为自动化属性测试需要属性定义,比如
val prop = forAll(v: T => check that property holds for v) 和价值v发电机.用户指南说您可以为自定义类型创建自定义生成器(例如,树的生成器).然而,它并没有解释为什么你需要最重要的仲裁. 这是一本手册 implicit lazy val arbBool: Arbitrary[Boolean] = Arbitrary(oneOf(true,false))
它清楚地表明,我们需要在Gen之上任意.任意的理由不尽如人意
IMO,要使用生成器,您需要导入它们而不是将它们包装到仲裁中!否则,我们可以争辩说,我们需要将仲裁包装到其他东西中以使它们可用(等等无限制地无限地包装包装器). 您还可以解释任意[Int]如何将参数类型转换为生成器.这很奇怪,我觉得这些是相关的问题. 解决方法
forAll {v:T => …}是在Scala implicits的帮助下实现的.这意味着类型T的生成器是隐式发现的,而不是由调用者显式指定.
Scala隐含很方便,但如果您不确定当前隐含值或转换的范围,它们也会很麻烦.通过使用特定类型(任意)进行隐式查找,ScalaCheck尝试约束使用implicits的负面影响(这种使用也使其类似于某些用户熟悉的Haskell类型类). 所以,你是完全正确的,不需要任意.通过隐式Gen [T]值可以实现相同的效果,可以说更隐含的范围混淆. 作为最终用户,您应该将Arbitrary [T]视为类型T的默认生成器.您可以(通过作用域)定义和使用多个任意[T]实例,但我不推荐它.相反,只需跳过Arbitrary并明确指定您的生成器: val myGen1: Gen[T] = ... val mygen2: Gen[T] = ... val prop1 = forAll(myGen1) { t => ... } val prop2 = forAll(myGen2) { t => ... } 任意[Int]就像forAll {n:Int => …},它只是查找隐式的Arbitrary [Int]实例并使用它的生成器.实现很简单: def arbitrary[T](implicit a: Arbitrary[T]): Gen[T] = a.arbitrary 任意的实现在这里也可能有所帮助: sealed abstract class Arbitrary[T] { val arbitrary: Gen[T] } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |