标签: scalacheck

使用scalacheck生成任意(合法)Unicode字符?

我正在尝试使用scalacheck 1.6.6和specs 1.7(scala 2.8.1)创建一个生成(非零长度)合法unicode字符串的生成器.

我希望我可以创建如下的生成器:

object Generators {
  def unicodeChar: Gen[Char] = 
    choose(Math.MIN_CHAR, Math.MAX_CHAR).map(_.toChar).filter(
      c => Character.isDefined(c))
  def unicodeStr: Gen[String] = for(cs <- listOf1(unicodeChar)) yield cs.mkString
}
Run Code Online (Sandbox Code Playgroud)

...然后从规格中使用它们:

import org.specs.Specification
import org.specs.matcher.ScalaCheckMatchers

object CoreSpec extends Specification with ScalaCheckMatchers {        
  "The core" should {    
    "pass trivially" in {
      Generators.unicodeStr must pass((s: String) => s == s)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,似乎在unicodeChar中使用过滤器会导致问题:

Specification "CoreSpec"
  The core should
  x pass trivially
    Gave up after only 64 passed tests. 500 tests were discarded.
Run Code Online (Sandbox Code Playgroud)

如果我从unicodeChar中删除过滤器,我的测试通过了,但我后来遇到其他问题,因为我的字符串并不总是定义良好的unicode.

提前感谢有关如何实现这一目标的任何建议.

specs scala scalacheck

4
推荐指数
2
解决办法
1512
查看次数

ScalaCheck 中的 suchThat 用法

我正在通过阅读 ScalaCheck 的代码来学习 scala,发现许多组合器都以suchThat. 然而,在很多情况下,这样的做法看起来并不是很有必要。我想知道为什么它们要这样设计。以下是GitHub上的一些摘录:

Example 1.

/** Picks a random value from a list */
def oneOf[T](xs: Seq[T]): Gen[T] =
    choose(0, xs.size-1).map(xs(_)).suchThat(xs.contains)
Run Code Online (Sandbox Code Playgroud)

map从 xs 中选择一个元素,因此xs.contains看起来是多余的。

--

Example 2.

def containerOfN[C[_],T](n: Int, g: Gen[T])
    (implicit evb: Buildable[T,C], evt: C[T] => Traversable[T]): Gen[C[T]] =
    sequence[C,T](Traversable.fill(n)(g)) suchThat { c =>
      c.size == n && c.forall(g.sieveCopy)
    }
Run Code Online (Sandbox Code Playgroud)

c.size == n既然成功sequence返回的长度为 n ,为什么需要这样做呢?

--

Example 3.

/** Generates a string of alpha characters */ …
Run Code Online (Sandbox Code Playgroud)

scala scalacheck

4
推荐指数
1
解决办法
1057
查看次数

如何减少ScalaCheck生成的测试用例数?

我正在尝试解决两个ScalaCheck(+ specs2)问题:

  1. 有没有办法改变ScalaCheck生成的案例数量?

  2. 如何生成包含某些Unicode字符的字符串?

例如,我想生成大约10个包含字母数字和Unicode字符的随机字符串.但是,此代码始终生成100个随机字符串,并且它们严格基于字母字符:

"make a random string" in {
    def stringGenerator = Gen.alphaStr.suchThat(_.length < 40)
    implicit def randomString: Arbitrary[String] = Arbitrary(stringGenerator)

    "the string" ! prop { (s: String) => (s.length > 20 && s.length < 40) ==> { println(s); success; } }.setArbitrary(randomString)
}
Run Code Online (Sandbox Code Playgroud)

编辑

我刚才意识到还有另一个问题:

  1. 通常,ScalaCheck放弃而不产生100个测试用例

当然,我不想要100,但显然我的代码试图生成一套过于复杂的规则.它最后一次运行,我看到"47次测试后放弃了".

unicode scala scalacheck specs2

4
推荐指数
1
解决办法
1621
查看次数

Scalacheck,适用于5到12之间列表的生成器

我可以找到许多为发生器设置最大尺寸的示例,但是如何在最小和最大长度之间生成列表?

unit-testing scalatest scalacheck property-based-testing

4
推荐指数
1
解决办法
763
查看次数

如何在scalatest中使用forAll仅生成生成器的一个对象?

我正在使用 scalatest 和 scalacheck,也正在使用 FeatureSpec。

我有一个生成器类,它为我生成对象,如下所示:

object InvoiceGen {

  def myObj = for {

    country <- Gen.oneOf(Seq("France", "Germany", "United Kingdom", "Austria"))
    type <- Gen.oneOf(Seq("Communication", "Restaurants", "Parking"))
    amount <- Gen.choose(100, 4999)
    number <- Gen.choose(1, 10000)
    valid <- Arbitrary.arbitrary[Boolean]

  } yield SomeObject(country, type, "1/1/2014", amount,number.toString, 35, "something", documentTypeValid, valid, "")
Run Code Online (Sandbox Code Playgroud)

现在,我有了与 FeatureSpec 一起使用的测试类以及运行测试所需的一切。

在这个类中,我有场景,在每个场景中我想生成一个不同的对象。据我了解,生成对象最好使用 forAll 函数,但 forall 不确定会给您带来一个对象,因此您可以添加 minSuccessful(1) 以确保您获得列表 1 obj... 。

我这样做了并且有效:

scenario("some scenario") {
      forAll(MyGen.myObj, minSuccessful(1)) { someObject =>
        Given("A connection to the system")
        loginActions shouldBe 'Connected

        When("something")
        //blabla …
Run Code Online (Sandbox Code Playgroud)

scala generator scalatest scalacheck

4
推荐指数
1
解决办法
3268
查看次数

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

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

从我的IntelliJ工作表,逐字广告:

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
Run Code Online (Sandbox Code Playgroud)

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

x =134, y =547
x =0, y =547
x =0, y =0
x =0, y =274
x =0, y =0
x …
Run Code Online (Sandbox Code Playgroud)

scala intellij-idea scalacheck

4
推荐指数
1
解决办法
198
查看次数

ScalaCheck无法将布尔值强制转换为Prop实例

我具有以下属性:

import org.scalacheck.Prop.propBoolean

def elementsAreReversed(list: List[Int], reversed: List[Int]): Boolean =
  if (list.isEmpty) true else {
    val lastIdx = list.size - 1
    list.zipWithIndex.forall { case (element, index) =>
      element == reversed(lastIdx - index)
    }
  }

val propReversed = Prop.forAll { list: List[Int] =>
  val reversed = list.reverse

  if (list.isEmpty)
    list == reversed
  else {
    val hasSameSize    = reversed.size == list.size
    val hasAllElements = list.forall(reversed.contains)

    // It works until  I add a label here:
    hasSameSize && hasAllElements && elementsAreReversed(list, reversed)
  }
Run Code Online (Sandbox Code Playgroud)

如果添加标签,则会中断: …

unit-testing scala scalacheck

4
推荐指数
1
解决办法
193
查看次数

了解ScalaChecks的"生成大小"

ScalaCheck的GenAPI 文档解释lazy val sized:

def size [T](f:(Int)⇒Gen[T]):Gen [T]

创建可以访问其生成大小的生成器

看下面的例子:

import org.scalacheck.Gen.{sized, posNum}

scala> sized( s => { println(s); posNum[Int] })
res12: org.scalacheck.Gen[Int] = org.scalacheck.Gen$$anon$3@6a071cc0

scala> res12.sample
100
res13: Option[Int] = Some(12)

scala> res12.sample
100
res14: Option[Int] = Some(40)
Run Code Online (Sandbox Code Playgroud)

是什么意思generation size,即上述输出中的100?

scala scalacheck

4
推荐指数
1
解决办法
593
查看次数

如何生成从集合中挑选的n个唯一元素的列表?

如何使用ScalaCheck从一组值(而不是生成器)生成n个唯一值(Gen[List[T]])的列表?这篇文章使用Gen[T]*而不是一组值,我似乎无法重写它以使其工作.

编辑

在@Jubobs的要求下,我现在可耻地展示了我到目前为止所做的一切,揭示了我在使用ScalaCheck时的全新状态:-)

我只是试图取代gs: Gen[T]重复参数到Set什么@Eric写的解决方案在这里:

def permute[T](n: Int, gs: Set[T]): Gen[Seq[T]] = {
    val perm = Random.shuffle(gs.toList)
    for {
        is <- Gen.pick(n, 1 until gs.size)
        xs <- Gen.sequence[List[T], T](is.toList.map(perm(_)))
    } yield xs
}
Run Code Online (Sandbox Code Playgroud)

但是is.toList.map(perm(_))用红色强调,IntelliJ IDEA告诉我"你应该在盲目(虽然直观)试验和错误之前首先阅读ScalaCheck API",或者"类型不匹配,预期:Traversable [Gen [T]],实际列表[T ]",我不记得了.

我还尝试了其他几种方法,其中大多数我觉得很荒谬(因而不值得发布),最天真的是使用@Eric的(其他有用和整洁的)解决方案:

val g = for (i1 <- Gen.choose(0, myList1.length - 1); 
  i2 <- Gen.choose(0, myList2.length - 1)) 
  yield new MyObject(myList1(i1), myList2(i2)) …
Run Code Online (Sandbox Code Playgroud)

testing scala unique scalacheck

4
推荐指数
1
解决办法
1192
查看次数

使用 scalacheck 生成任意 A =&gt; Date

我在 scalacheck 1.13.3 中遇到了一个奇怪的问题:任意实例A => java.util.Date根据调用时间生成不同的值。

这是一个具体的、可重现的示例:

import org.scalatest.FunSuite
import org.scalatest.prop.GeneratorDrivenPropertyChecks
import java.util.Date
import org.scalacheck._

class Repr extends FunSuite with GeneratorDrivenPropertyChecks {
  implicit val cogenDate: Cogen[Date] = Cogen(_.getTime)

  test("reproduce") {
    forAll { (s: String, g: String => Date) =>
      val d1 = g(s)
      Thread.sleep(100)
      val d2 = g(s)

      assert(d1 === d2)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这失败了。d1打印和的实际值d2显示日期确实不同,差异在 100 到 103 毫秒之间。

我猜问题出在我的Cogen实例上,但我必须承认我不明白为什么。

scala scalacheck

3
推荐指数
1
解决办法
701
查看次数