У меня есть несколько симуляций Гатлинга, которые я пытаюсь структурировать таким образом, чтобы повторно использовать низкоуровневые вызовы (например, HTTP-вызовы) при создании другого сценария ios. По этой причине у меня есть следующая структура (функция 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 в качестве параметра, echo () - это когда начинаются проблемы. Предположим, у меня есть следующая реализация 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]]
и использовать обычный блок exe c (т.е. не тот, который был введен в сеанс). В этом случае я не смог получить реальную карту из сеанса!
Кажется, что bodyString доступен только при использовании exe c (), а не exe c {session => ...; сессия} Мои Scala знания очень малы, что добавляет мне путаницы.
Я чувствую, что упускаю что-то очень фундаментальное в этом. Будем благодарны за любую помощь.
ОБНОВЛЕНИЕ # 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
s из сценария? Например, если у меня есть другая функция, которая принимает Int в качестве параметра и создает HTTP-запрос с номером в запросе, который должен быть отправлен, как бы я go сделал это?