定制DSL通过扩展Gatling:如何Scala?

时间:2018-05-22 19:48:29

标签: scala generics gatling scala-gatling

我们正在使用Gatling来加载测试我们的应用程序(并且效果很好)。我们试图通过在Gatling类(例如io.gatling.core.structure中找到的ScenarioBuilder / ChainBuilder /等)上创建可组合扩展来干掉部分代码。

以下是我们的一个场景的示例:

val scn = scenario("Whatever")
  .exec(Authentication.FeederLogin(userCsvFile, password))
  .exec(User.ExtractId(User.SignIn()))
  .exec(FindPeople(50, "personIds"))

  // SPA load
  .exec(User.FetchLandingPageFor("${userId}"))

  .during(durationSeconds.seconds) {
    pace(3.seconds, 8.seconds)
      .exec(Person.Search("${personIds.random()}"))
      .pause(3.seconds, 10.seconds)

      // start the upload
      .exec(Upload.create())
  }

我们喜欢做的是开始制作一些可组合的内容,以便我们可以在其他场景中重复使用它们。像这样:

val scn = scenario("Whatever")
  .login()

  .during(durationSeconds.seconds) {
    pace(3.seconds, 8.seconds)
      .uploadFor("${personIds.random()}")
  }

// ...

object WhateverScenarios {
  implicit class ScenarioBuilderWithWhatevers(b: ScenarioBuilder) {

    def login() : ScenarioBuilder = {
      b.exec(Authentication.FeederLogin(userCsvFile, password))
      .exec(User.ExtractId(User.SignIn()))
      .exec(FindPeople(50, "personIds"))
    }

    def uploadFor(whom : String) : ScenarioBuilder {
      b.exec(Person.Search("${personIds.random()}"))
      .pause(3.seconds, 10.seconds)

      // start the upload
      .exec(Upload.create())
    }
  }
}

全面披露;我对Scala并不是很熟悉。这是有效的,但问题在于uploadFor,因为此时它正在使用ChainBuilderScenarioBuilder

我想

  

哦,简单!只需使用泛型!

除了我无法让它工作:(它看起来就像大多数extend StructureBuilder[T]一样,但我似乎无法定义通用定义,我可以使用WhateverScenarios StructureBuilder[T]的任何上下文中。

提前感谢您提供的任何信息。

1 个答案:

答案 0 :(得分:0)

所以我能够解决我的问题,但我不能完全确定为什么我必须这样做。我的问题解决了以下问题:

object WhateverScenarios {
  implicit class StructureBuilderWithWhatevers[B <: io.gatling.core.structure.StructureBuilder[B]](b: B) {

    def login() : B = {
      b.exec(Authentication.FeederLogin(userCsvFile, password))
      .exec(User.ExtractId(User.SignIn()))
      .exec(FindPeople(50, "personIds"))
    }

    def uploadFor(whom : String) : ScenarioBuilder {
      b.exec(Person.Search("${personIds.random()}"))
      .pause(3.seconds, 10.seconds)

      // start the upload
      .exec(Upload.create())
    }
  }
}

那个让我失去循环的东西是最初我试图像这样定义它:

object WhateverScenarios {
  implicit class StructureBuilderWithWhatevers[B <: StructureBuilder[B]](b: B) {
  // ...
}

但是当我这样做时,它不会将loginuploadFor视为ScenarioBuilderChainBuilder的一部分。不知道为什么,但我已经指定了完全合格的包名称才能工作¯\ _(ツ)_ /¯

修改

事实证明,完全限定的包名是我机器上的一些奇怪的工件。执行./gradlew clean修复了问题,我不再需要使用完全限定的路径名​​。