Joe*_*Joe 4 scala generator scalatest scalacheck
我正在使用 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
Then("something should happened")
//blabla
}
}
Run Code Online (Sandbox Code Playgroud)
但我不确定这到底是什么意思。我想要的是为每个场景生成一张发票并对其执行一些操作...我不确定为什么我关心生成是否有效...我只想使用生成的对象。
小智 5
TL;DR:要获取一个且仅一个对象,请使用myObj.sample.get
. 除非你的发电机正在做一些奇特的事情,否则是完全安全的并且不会爆炸。
我认为您的意图是使用一些随机生成的域对象\xe2\x80\x94运行某种集成/验收测试,换句话说(ab-)使用scalacheck作为简单的数据生成器\xe2\x80\x94并且您希望这minSuccessful(1)
会确保测试只运行一次。
请注意,事实并非如此!如果失败,scalacheck 将多次运行您的测试,以尝试将输入数据缩小到最小的反例。
\n\n如果您想确保测试仅运行一次,则必须使用sample
.
但是,如果多次运行测试就可以,那么更愿意minSuccessful(1)
“快速成功”,但在测试失败时仍然可以从最小化的反例中获益。
Gen.sample
返回一个选项,因为生成器可能会失败:
\n\n\nScalaCheck 生成器可能会失败,例如,如果您添加过滤器 (listingGen.suchThat(...)),并且该失败是使用 Option 类型建模的。
\n
但:
\n\n\n\n\n[\xe2\x80\xa6] 如果您确定您的生成器永远不会失败,您可以像上面的示例中那样简单地调用 Option.get 。或者您可以使用 Option.getOrElse 将 None 替换为默认值。
\n
.get
一般来说,如果您的生成器很简单,即不使用可能失败的生成器并且本身不使用任何过滤器,则仅调用. 返回的选项是完全安全的.sample
。我过去一直这样做,从来没有遇到过问题。如果您的生成器频繁返回None
,.sample
则可能会使 scalacheck 也无法成功生成值。
如果您想要的只是单个对象,请使用Gen.sample.get
.
minSuccessful
有一个非常不同的含义:这是scalacheck 运行的最小成功测试数\xe2\x80\x94,这绝不意味着
使用minSuccessful(1)
scalacheck 想要一次成功的测试。它将从生成器中取出样本,直到测试至少运行一次\xe2\x80\x94,即 如果您在测试主体中过滤生成的值,whenever
scalacheck 将采样并丢弃whenever
它们。
如果测试通过,scalacheck 会很高兴并且不会再次运行测试。
\n\n然而,如果测试失败, scalacheck 将尝试生成一个最小的示例来使测试失败。只要失败,它就会缩小输入数据并运行测试,然后为您提供最小化的计数器示例,而不是触发初始失败的实际输入。
\n\n这是属性测试的一个重要属性,因为它可以帮助您发现错误:原始数据通常太大而无法进行调试。最小化它可以帮助您发现实际触发故障的输入数据,即您没有想到的诸如空字符串之类的极端情况。
\n