Scala Check/Scala 测试:编写生成器
Scala Check/Scala Test: Compose Generators
有什么方法可以让我在 scala 中编写生成器 test/scala 检查一下?
例如,这是我想写的示例测试用例:
"The classifier" when {
"given a string containing a state" should {
"classify it as a state" in {
val states = Seq(
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware",
"Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
"Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
"Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"
)
val inputData = for {
zip <- Gen.const("10001")
name <- Gen.oneOf(
Gen.oneOf(states) + "HARRINGTON, JOHN",
"HARRINGTON, JOHN " + Gen.oneOf(states),
"HARRINGTON, " + Gen.oneOf(states) + " MD,JOHN"
)
} yield (zip, name)
forAll (inputData) { case (zip: String, name: String) =>
Clasifier.classify(zip, name) shouldBe Classification.STATE
}
}
}
}
请注意 for comprehension 中的 name
生成器来导出 inputData
val
。
我怎样才能实现这样的目标?
更新:我已经让它工作了,但不确定我在这里做的是否正确。
val inputData = for {
zip <- Gen.const("10001")
name <- Gen.oneOf(
s"${Gen.oneOf(states).sample.get} HARRINGTON, JOHN",
s"HARRINGTON, JOHN ${Gen.oneOf(states).sample.get}",
s"HARRINGTON, ${Gen.oneOf(states).sample.get} MD,JOHN"
)
} yield (zip, name)
失败(预期失败)消息对我正在做的事情不是很有帮助:
TestFailedException was thrown during property evaluation.
Message: STATE was not equal to INDIVIDUAL
Location: (Classifier$Test.scala:142)
Occurred when passed generated values (
arg0 = (,) // 12 shrinks
)
PS:正如评论中所要求的,这是我期望输入数据的样子:
"Alabama Harringgon, John",
"Harriongton, Alabama John",
"Harrington, John Alabama",
"Maryland Harrington, John",
"Harrington, Maryland John",
"Harrington, John Maryland",
etc.
如果你想组合你的生成器,你可以像这样在 for comprehension 中包含状态:
val inputData = for {
zip <- Gen.const("10001")
state <- Gen.oneOf(states)
name <- Gen.oneOf(
state + "HARRINGTON, JOHN",
"HARRINGTON, JOHN " + state,
"HARRINGTON, " + state + " MD,JOHN"
)
} yield (zip, name)
如果样本的结果是 None 而不是您想要的结果,那么像您在更新的示例中那样执行 sample.get 将引发异常。
您收到无用的失败消息的原因是缩小,scalacheck 将尝试将值减少到失败的最小值,在这种情况下,两个值都是空字符串。在大多数情况下,我发现这不是您想要的行为,您可以通过包含如下隐式来阻止它缩小值:
implicit val noShrinkString: Shrink[String] = Shrink.shrinkAny
implicit def noShrinkList[A]: Shrink[List[A]] = Shrink.shrinkAny
第一行停止字符串收缩,第二行停止列表收缩,方法是为它们分配相同的 Any 类型的收缩实例,该实例根本不收缩。
回答有点晚了,我相信你现在已经解决了你的问题,但希望这能对处于类似情况的其他人有所帮助
有什么方法可以让我在 scala 中编写生成器 test/scala 检查一下?
例如,这是我想写的示例测试用例:
"The classifier" when {
"given a string containing a state" should {
"classify it as a state" in {
val states = Seq(
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware",
"Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
"New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
"Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
"Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"
)
val inputData = for {
zip <- Gen.const("10001")
name <- Gen.oneOf(
Gen.oneOf(states) + "HARRINGTON, JOHN",
"HARRINGTON, JOHN " + Gen.oneOf(states),
"HARRINGTON, " + Gen.oneOf(states) + " MD,JOHN"
)
} yield (zip, name)
forAll (inputData) { case (zip: String, name: String) =>
Clasifier.classify(zip, name) shouldBe Classification.STATE
}
}
}
}
请注意 for comprehension 中的 name
生成器来导出 inputData
val
。
我怎样才能实现这样的目标?
更新:我已经让它工作了,但不确定我在这里做的是否正确。
val inputData = for {
zip <- Gen.const("10001")
name <- Gen.oneOf(
s"${Gen.oneOf(states).sample.get} HARRINGTON, JOHN",
s"HARRINGTON, JOHN ${Gen.oneOf(states).sample.get}",
s"HARRINGTON, ${Gen.oneOf(states).sample.get} MD,JOHN"
)
} yield (zip, name)
失败(预期失败)消息对我正在做的事情不是很有帮助:
TestFailedException was thrown during property evaluation.
Message: STATE was not equal to INDIVIDUAL
Location: (Classifier$Test.scala:142)
Occurred when passed generated values (
arg0 = (,) // 12 shrinks
)
PS:正如评论中所要求的,这是我期望输入数据的样子:
"Alabama Harringgon, John",
"Harriongton, Alabama John",
"Harrington, John Alabama",
"Maryland Harrington, John",
"Harrington, Maryland John",
"Harrington, John Maryland",
etc.
如果你想组合你的生成器,你可以像这样在 for comprehension 中包含状态:
val inputData = for {
zip <- Gen.const("10001")
state <- Gen.oneOf(states)
name <- Gen.oneOf(
state + "HARRINGTON, JOHN",
"HARRINGTON, JOHN " + state,
"HARRINGTON, " + state + " MD,JOHN"
)
} yield (zip, name)
如果样本的结果是 None 而不是您想要的结果,那么像您在更新的示例中那样执行 sample.get 将引发异常。
您收到无用的失败消息的原因是缩小,scalacheck 将尝试将值减少到失败的最小值,在这种情况下,两个值都是空字符串。在大多数情况下,我发现这不是您想要的行为,您可以通过包含如下隐式来阻止它缩小值:
implicit val noShrinkString: Shrink[String] = Shrink.shrinkAny
implicit def noShrinkList[A]: Shrink[List[A]] = Shrink.shrinkAny
第一行停止字符串收缩,第二行停止列表收缩,方法是为它们分配相同的 Any 类型的收缩实例,该实例根本不收缩。
回答有点晚了,我相信你现在已经解决了你的问题,但希望这能对处于类似情况的其他人有所帮助