gpt4 book ai didi

scala - 如何在 Scalatest 中使用 forAll 只生成生成器的一个对象?

转载 作者:行者123 更新时间:2023-12-03 23:50:45 25 4
gpt4 key购买 nike

我使用 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, "")

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

在这个类中我有场景,在每个场景中我想生成一个不同的对象。
根据我的理解,生成对象最好使用 forAll func,但是对于所有人来说都不确定会给您带来一个对象,因此您可以添加 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
}
}

但我不确定它到底是什么意思。
我想要的是在每个场景中生成一张发票并对其进行一些操作...
我不知道为什么我在乎生成是否有效……我只想使用生成的对象。

最佳答案

TL;博士 :要获取一个对象,并且只有一个,请使用 myObj.sample.get .除非您的发电机正在做一些非常安全且不会爆炸的奇特事情。

我假设您的意图是使用一些随机生成的域对象运行某种集成/验收测试 - 换句话说(ab-)使用 scalacheck 作为一个简单的数据生成器 - 您希望 minSuccessful(1)将确保测试只运行一次。

请注意 事实并非如此 !。如果测试失败,scalacheck 将多次运行您的测试,以尝试将输入数据缩小到最小的反例。

如果您想确保您的测试只运行一次 必须使用 sample .

但是,如果多次运行测试没问题,则首选 minSuccessful(1)以“快速成功”,但仍然可以从最小化的反例中受益,以防测试失败。
Gen.sample返回一个选项,因为 generators can fail :

ScalaCheck generators can fail, for instance if you're adding a filter (listingGen.suchThat(...)), and that failure is modeled with the Option type.



但:

[…] if you're sure that your generator never will fail, you can simply call Option.get like you do in your example above. Or you can use Option.getOrElse to replace None with a default value.



通常,如果您的生成器很简单,即不使用可能会失败的生成器并且不使用任何过滤器,那么调用 .get 是绝对安全的。在 .sample 返回的选项上.我过去一直这样做,从来没有遇到过问题。如果您的生成器经常返回 None来自 .sample它们也可能使 scalacheck 无法成功生成值。

如果您想要的只是单个对象,请使用 Gen.sample.get .
minSuccessful有一个非常不同的含义:它是 最小 scalacheck 运行的成功测试的数量—其中 绝不是暗示
  • scalacheck 只从生成器中取出一个值,或者
  • 测试只运行一次。

  • minSuccessful(1) scalacheck 想要一个成功的测试。它将从生成器中取出样本,直到测试至少运行一次 - 即如果您使用 whenever 过滤生成的值在您的测试体中,scalacheck 将采样只要 whenever丢弃它们。

    如果测试通过 scalacheck 很高兴并且不会第二次运行测试。

    但是如果测试 失败 scalacheck 将尝试生成一个让测试失败的最小示例。只要它失败,它就会缩小输入数据并运行测试,然后为您提供最小化的计数器示例,而不是触发初始失败的实际输入。

    这是属性测试的一个重要特性,因为它可以帮助您发现错误:原始数据通常太大而无法进行调试。最小化它可以帮助您发现实际触发失败的输入数据,即您没有想到的空字符串等极端情况。

    关于scala - 如何在 Scalatest 中使用 forAll 只生成生成器的一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35016249/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com