通过扩展盖特林来定制DSL:如何扩展Scala? [英] Custom DSL by extending Gatling: How to Scala?

查看:107
本文介绍了通过扩展盖特林来定制DSL:如何扩展Scala?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用加特林(Gatling)对应用程序进行负载测试(效果很好).我们正在尝试通过对Gatling类进行可组合扩展来干燥某些代码(例如

We're using Gatling to load test our application (and it works great). We're attempting to DRY up some of the code by making composable extensions on the Gatling classes (like ScenarioBuilder / ChainBuilder / etc. found in io.gatling.core.structure).

以下是我们其中一种情况的示例:

Here is an example of one of our scenarios:

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())
  }

我们希望 要做的是使其中一些可组合成为可能,以便我们可以在其他情况下重新使用它们.像这样:

What we'd like to do is start to make some of that composable so we can re-use them in other scenarios. Something like this:

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上,因为那时它正在与ChainBuilder相对于ScenarioBuilder一起工作.

Full disclosure; I'm not super familiar with Scala. This works, but the problem is in the uploadFor in that at that point it's working with a ChainBuilder vs. a ScenarioBuilder.

我想

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

除了我无法使其工作:(它看起来像大多数

Except I cannot get it to work :( It looks like most of these extend StructureBuilder[T] but I cannot seem to get a generic definition defined where I can use my WhateverScenarios in any context of a StructureBuilder[T].

在此先感谢您提供的任何信息.

Thanks in advance for any information that can be provided.

推荐答案

所以我能够解决我的问题,但是我不确定为什么我必须这样做.解决我的问题的方法如下:

So I was able to get past my issue, but I'm not entirely sure why I had to do this. What fixed my issue is the following:

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())
    }
  }
}

最初让我陷入困境的东西是 我试图这样定义它:

The thing that was throwing me for a loop, was originally I tried to define it like this:

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

但是当我这样做时,它并没有将loginuploadFor识别为ScenarioBuilderChainBuilder的一部分.不知道为什么,但是我指定了完全合格的软件包名称来使它工作¯\ _(ツ)_/¯

But when I did that, it didn't recognize login or uploadFor as being part of either ScenarioBuilder or ChainBuilder. Not sure why, but I had the specify the fully qualified package name for it to work ¯\_(ツ)_/¯

事实证明,完全合格的软件包名称是我在计算机上拥有的一些奇怪的工件.进行./gradlew clean解决了该问题,我不再需要使用完全限定的路径名​​.

Turns out that the fully qualified package name was some weird artifact that I had on my machine. Doing a ./gradlew clean fixed the issue and I no longer have to use the fully qualified path name.

这篇关于通过扩展盖特林来定制DSL:如何扩展Scala?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆