我有一个案例类,我正在尝试通过ScalaCheck进行测试。案例类包含其他类。
以下是课程:
case class Shop(name: String = "", colors: Seq[Color] = Nil)
case class Color(colorName: String = "", shades: Seq[Shade] = Nil)
case class Shade(shadeName: String, value: Int)
我每个人都有发电机
implicit def shopGen: Gen[Shop] =
for {
name <- Gen.alphaStr.suchThat(_.length > 0)
colors <- Gen.listOf(colorsGen)
} yield Shop(name, colors)
implicit def colorsGen: Gen[Color] =
for {
colorName <- Gen.alphaStr.suchThat(_.length > 0)
shades <- Gen.listOf(shadesGen)
} yield Color(colorName, shades)
implicit def shadesGen: Gen[Shade] =
for {
shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
value <- Gen.choose(1, Int.MaxValue)
} yield Shade(shadeName, value)
当我编写测试并只需执行以下操作时:
property("Shops must encode/decode to/from JSON") {
"test" mustBe "test
}
我收到一个错误,并且在尝试51次后,测试挂起并停止。我得到的错误是Gave up after 1 successful property evaluation. 51 evaluations were discarded.
如果我从Gen.alphaStr.suchThat(_.length > 0)
中删除了shadesGen
,而只是将其替换为Gen.alphaStr
,那么它将起作用。
问题
Gen.alphaStr
对shadesGen
有用,但是Gen.alphaStr.suchThat(_.length > 0)
却不起作用? Gen.alphaStr
进行测试时,有些通过,有些则没有。为什么会这样?答案 0 :(得分:1)
由于实施listOf
的方式,您可能会看到此行为。里面是基于buildableOf
的,而buildableOfN
是基于shadeName
的,它具有以下注释:
...如果给定的生成器无法生成值,则 完整的容器生成器也会失败。
您的数据结构本质上是一个列表列表,因此,即使是坏的一代也会诅咒要丢弃的整个数据结构。显然,大多数失败都发生在底层。因此,删除Gen.alphaStr
的过滤器会有所帮助。因此,要使其正常工作,您应该生成更多有效的字符串。您可以将nonEmptyListOf
更改为基于def nonemptyAlphaStr:Gen[String] = Gen.nonEmptyListOf(alphaChar).map(_.mkString)
的某些定制生成器,例如:
retryUntil
解决此问题的另一种简单方法是使用suchThat
代替implicit def shadesGen: Gen[Shade] =
for {
//shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
shadeName <- Gen.alphaStr.retryUntil(_.length > 0)
value <- Gen.choose(1, Int.MaxValue)
} yield Shade(shadeName, value)
,例如:
var input = jQuery('<div><input id="edit-annotation-input" ' +
'style="z-index: 100; position: absolute; top:' + (this.textPosition.y - 9) + 'px; left:'+ (this.textPosition.x + 8) +'px; width: ' + (610 - 7 - this.textPosition.x) + 'px; border: none; color: #0bac3a; outline: none; background-color: transparent !important; padding: 0px; font-family: arial; font-size: 12pt; " ' +
'spellcheck="false" type="text" name="mytext[]" value="'+string+'"/></div>');
jQuery("div #pad").append(input);