加特林执行块和会话变量

问题描述 投票:0回答:1

我尝试构建多种加特林模拟,以便在构建不同场景时重用低级调用(即HTTP调用)。因此,我具有以下结构(为了解释当前状态,使用了echo函数):

// File UserAction.scala contains all low-level actions like load a specific page, login, logout etc. All functions return HttpRequestBuilder so that each simulation can perform its own set of checks on the responses.
object UserAction {
    ...
    def echo(): HttpRequestBuilder = {
        http("Postman Echo Service Call")
            .get("https://postman-echo.com/get")
            .headers(headers("headers_0"))
    }
    ...
}

// File TestSimulation.scala
class TestSimulation extends ParameterizedSimulation {
    private val accountFeeder = csv("data/accounts.csv")

    private val testScenario = scenario("Test Simulation")
        .feed(accountFeeder)
        .exec { session =>
            session.set("attributes", session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
        }
        .doIfOrElse(session => session("schema_attributes").as[Map[String, String]].isEmpty) {
            exec(
                echo()
                    .check(bodyString.saveAs("responseBody"))
            )
        } {
            exec(
                echo()
                    .formParamMap("${schema_attributes}")
                    .check(bodyString.saveAs("responseBody"))
            )
        }
        .exec { session => println(session("responseBody").as[String]); session }
    ...
}

在上面提供的测试模拟中,我们从文件中获取数据,然后选择属性的子集,将其存储为Map到Session中。如果在文件中找到此类属性,则在提交回显请求时,我们会将它们作为表单参数添加。否则我们不会。在这两种情况下,我们都存储响应主体并也将其打印出来。效果很好。

[当我尝试将Map作为参数传递给echo()时,就是问题开始了。假设我具有以下回显实现:

def echo(extraParameters: Map[String, Any]): HttpRequestBuilder = {
    val request = http("Postman Echo Service Call")
        .get("https://postman-echo.com/get")
        .headers(headers("headers_0"))

    if (extraParameters.nonEmpty) {
        request.formParamMap(extraParameters)
    }

    request
}

并且模拟执行以下操作:

.exec { session =>
            session.set("schema_attributes", session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
}
.exec { session =>
    echo(session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
        .check(bodyString.saveAs("responseBody"))
    session
}
.exec { session => println(session("responseBody").as[String]); session }

请求不会触发,并且我收到有关bodyString丢失的以下错误

[ERROR] i.g.c.a.b.SessionHookBuilder$$anon$1 - 'hook-1' crashed with 'j.u.NoSuchElementException: No attribute named 'responseBody' is defined', forwarding to the next one

[我尝试过的另一种方法是使echo接受Expression[Map[String, Any]]并使用普通的exec块(即,不是带有注入会话的那个)。在这种情况下,我无法从会话中获取实际地图!

似乎bodyString仅在使用exec()而不是exec {session => ...;时才可用。会话}表单。我对Scala的了解很少,这使我更加困惑。

我觉得我缺少一些非常基本的东西。任何帮助将不胜感激。

UPDATE#1

基于到目前为止所收到的评论,据我了解,使用exec(sessionFunction: Expression[Session])函数会在运行时创建ActionBuilders,因此不使用它们(它们只是创建并丢弃的。)>

为了将所有检查保留在方案中,同时将HTTP请求的定义保留在其他函数上,我尝试了以下替代方法:

def echo(): HttpRequestBuilder = {
    http("Postman Echo Service Call")
        .get("https://postman-echo.com/get")
        .headers(headers("headers_0"))
        .formParamMap("${schema_attributes}")
}

// Used as
.feed(myFeeder)
.exec { session => session.set("schemaAttributes", session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
}
.exec(
    echo()
        .check(bodyString.saveAs("responseBody"))
)

这样,如果映射为空(即文件中不存在该信息),则formParamMap将不起作用。如果地图实际包含数据,是否可以选择添加formParamMap?

通常,是否存在将参数传递给从场景中返回HttpRequestBuilder的函数的首选模式/方法?例如,如果我有另一个函数,该函数将Int作为参数,并使用要发送的请求中的数字创建一个HTTP请求,那么我该怎么做?

我尝试构建多种加特林模拟,以便在构建不同场景时重用低级调用(即HTTP调用)。因此,我具有以下结构...

testing gatling scala-gatling
1个回答
0
投票

在您的示例中,echo返回HttpRequestBuilder。加特林的工作方式是,构建器应该全部在启动时构建,然后用于发出请求,因此,当您将其包含在会话函数中时,构建器在执行期间会得到[[created

© www.soinside.com 2019 - 2024. All rights reserved.