0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Gatling DSL の EL 式と Scala の変数展開が同居するとややこしい件

Last updated at Posted at 2020-06-08

(2022-03-03追記) 本記事で取り上げた内容は #4157 で解決され、Gatling 3.7 で取り込まれました。Gatling 3.7 以降の EL 式では、${} の代わりに #{} を利用することが推奨されています。1


Gatling は Scala でテストコードを記述する負荷試験ツールですが、その多くを占めるシナリオ部分は Gatling DSL と呼ばれるドメイン特化言語で記述します。

Gatling DSL の EL 式(Expression Language)

Gatling DSL の EL 式は Gatling のセッション属性(Session attributes)への参照を埋め込む際に利用します。

// セッション属性 foo に値を設定する
session.set("foo", "FOO")

// Session API でセッション属性 foo の値を取り出す
session("foo").as[String] // FOO

// EL 式でセッション属性 foo の値を取り出し、文字列に埋め込む
"${foo} BAR" // FOO BAR

基本的には ${属性名} という記法で参照を得ますが、EL 式に組み込まれた機能を利用してもっと複雑なこともできます:

// コレクション foo のサイズを得る
"${foo.size()}"

// インデックス付コレクション foo からランダムな要素を一つ取り出す
"${foo.random()}"

// インデックス付コレクション foo から 5 番目の要素を一つ取り出す
"${foo(5)}"

// インデックス付コレクションもしくはタプルである foo から n 番目の要素を取り出す
"${foo(n)}"

// タプル foo から 2 番目の要素を取り出す
"${foo._2}"

// マップ foo からキーが bar である要素を取り出す
"${foo.bar}"

// foo があれば true を、なければ false を得る
"${foo.exists()}"

// foo がなければ true を、あれば false を得る
"${foo.isUndefined()}"

// foo を JSON 形式でフォーマットした値を得る
"${foo.jsonStringify()}"

Gatling DSL の EL 式は Gatling DSL の関数に渡される String に対してのみ動作します。

Scala の変数展開

一方、Scala には変数展開(あるいは「文字列の補完」、string interpolation)という機能があります。文字列の前に補間子(interpolator)をつけることで、変数へ参照を埋め込むことができます。

val foo = "FOO"
println(s"$foo BAR")  // FOO BAR

基本的には $変数名 という記法で値を取り出しますが、${式} という記法で任意の式を埋め込むこともできます:

println(s"${1 + 1}")  // 2

Scala に組み込まれた補完子は三種類あります。

// s 補完子。シンプルな変数展開を実現します。
val foo = "FOO"
println(s"$foo")  // FOO

// raw 補完子。s 補完子の機能に加え、エスケープを実行しません。
println(raw"{"foo":"$foo"")  // {"foo":"FOO"}
// """~""" でも raw 補完子と同じ効果を実現します。
println("""{"foo":"$foo"}""") // {"foo":"FOO"}

// f 補完子。C の printf のようなフォーマット付文字列を実現します。
val decimal = 10
println(f"$foo%s $decimal%d") // FOO 10

混在するとなにがややこしいのか

さて、Scala の変数展開では、下のような記述も許されます:

s"${foo} BAR" // FOO BAR

"""${foo} BAR""" // FOO BAR

Gatling DSL の EL 式にそっくりですね。実際の所、Gatling DSL でも Scala の変数展開を利用することはできますが、それぞれの機能は排他的です:

session.set("foo", "FOO")
val bar = "BAR"

"${foo} BAR" // FOO BAR         -- 1
s"FOO ${bar}" // FOO BAR        -- 2

"${foo} ${bar}" // FOO ${bar}   -- 3
s"${foo} ${bar}" // error!      -- 4

3 や 4 のように変数とセッション属性の取得を同時に行いたい場合は、変数をセッション属性にセットするか、式展開で Session API を呼ぶことで実現できます。

参考リンク

  1. https://gatling.io/docs/gatling/reference/current/upgrading/3.6-to-3.7/

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?