シナリオを構成する要素
Scenamatica のシナリオを構成する要素について説明しています。
このページでは, シナリオの具体的な要素について説明しています。
シナリオファイルの構文や実践的な書き方については以下のページを参照してください。
概要
シナリオは以下の要素で構成されています。
- メタデータ
Scenamatica がシナリオ(ファイル)を識別する情報について記述します。 - トリガ
シナリオテストが発火する条件について記述します。 - 実行順
シナリオテストを実行する順番について記述します。
プラグインのスタートアップ時に実行されるシナリオなど, 同時に他のシナリオが複数発火する場合などに, その中での実行順を制御します。 - コンテキスト
シナリオテストを実行するために, 必要な前提環境(e.g. ワールド, プレイヤ, モブ・エンティティ)について記述します。 - メインシナリオ
プラグイン機能を発火させたり, 発火した機能を検証するためのフローを記述します。 - 実行条件
シナリオの実行に必要な条件(e.g. マイルストーン)について記述します。 - 定数の定義
使いまわしする値や構造体について記述します。
シナリオ
プラグイン開発者は, プラグインの機能の発火条件と, 想定される動作の一連のフローをシナリオとして記述します。
Scenamatica はこれらを一つ一つ実行・検証し, プラグインの振る舞いをテストします。
実行・検証に失敗した場合は, Scenamatica はプラグインが正しく動作していないと判断し, シナリオ実行の失敗を報告します。
各シナリオは、アクションとシナリオタイプの対で構成されます。
アクション
アクションとは, 「プレイヤが死亡する」や「プレイヤがメッセージを送信する」などの, サーバにおける具体的な動作のことです。
これらは Scenamatica によってあらかじめ定義されたもので, プラグインの機能を最小単位に分解したものです。
アクションを組み合わせてシナリオを記述します。
アクションは膨大な数の種類があるので, 各カテゴリ別に分けられています。
すべてのアクションについてはScenamatica References | アクションの一覧を参照してください。
アクションはそれぞれ異なった入力を受け取り, またそれぞれ異なった出力を返します。
入力は with
キーを使用して指定します。
例:
scenario:
# Actor1 に /hoge を実行させる。
- type: execute
action: command_dispatch
with:
command: "/hoge"
sender: Actor1
シナリオタイプ
全てのシナリオは, 以下の3つのタイプのいずれかに分類されます。
シナリオタイプ | 役割 |
---|---|
アクション実行(execute ) | アクションを実行し, プラグインの機能を発火させる。 |
アクション実行期待(expect ) | アクションが実行されるまで待機し, プラグインの機能が正常に動作するかどうかを検証する。 |
条件要求(require ) | アクションが既に実行され, 状態が満たされているかどうかを検証する。 |
シナリオタイプは, そのシナリオの役割(機能の発火・機能のテストなど)を指定するとともに、そのシナリオに使用されるアクションの振る舞いを制御します。
例:
scenario:
# 1. Actor 1 をキルする。
- type: execute
action: player_death
with:
target: Actor1
# 2. Actor 1 がキルされることを期待する。
- type: expect
action: player_death
with:
target: Actor1
# 3. Actor 1 が死亡していることを要求する。
- type: require
action: player_death
with:
target: Actor1
上記のシナリオの例ではすべて「Actor1 がキルされる」という同じアクションを使用しています。 しかし, 対応するシナリオタイプが異なるために, 以下のようにそれぞれ異なって振る舞います。
シナリオタイプ | ふるまい | |
---|---|---|
1 | アクション実行(execute ) | プレイヤをキルする |
2 | アクション実行期待(expect ) | プレイヤがキルされるまで待機する |
3 | 条件要求(require ) | プレイヤが(もう既に)死亡していることを要求する |
すべてのアクションが3のシナリオタイプすべてを持つわけではありません。
例えばアクション:ワールドの初期化は, 実行期待シナリオタイプにのみ対応しています。
アクション実行(execute
) タイプ
アクション実行(execute
) タイプは, 引数に指定されたアクションを実行し, 実行が完了するまで, またはタイムアウトするまで待機します。
これはテスト対象のプラグイン機能の実行を発火させるために使用します。
- シナリオが成功する条件
- アクションの実行が例外またはエラーなしで完了する。
- シナリオが失敗する条件
- アクションの実行がタイムアウトする。
- アクションの実行時に例外またはエラーが発生する。
例:
scenario:
# Actor1 に /hoge を実行させる。
- type: execute
action: command_dispatch
with:
command: "/hoge"
sender: Actor1
timeout: 1000 # タイムアウトを 1000 チックに設定
アクション実行期待(expect
) タイプ
アクション実行期待(expect
) タイプは, アクションがプラグインによって実行されるかどうかを監視します。
指定されたアクションが実行されるまで, もしくはタイムアウトするまで次のシナリオの実行を待機します。
- シナリオが成功する条件
- 対象のプラグインによってアクションが実行される。
- シナリオが失敗する条件
- 検証がタイムアウトする。
- 後述された実行期待シナリオ(
expect
)のアクシ ョンが先に実行される(詳細後述)。
scenario:
# fuga というメッセージが(Actor1 に)表示されることを期待する。
- type: expect
action: message
with:
content: "fuga"
recipient: Actor1
# Actor1 がキルされることを期待する。
- type: expect
action: player_death
with:
target: Actor1
例えば, 以下のようなシナリオについて考えます:
- アクション A を実行する
- アクション B の実行を(プラグインによって行われるか)期待する
- アクション C を実行を(〃)期待する
このとき, プラグインが機能(アクション)を C -> B の順番で実行した場合は, このシナリオは C の実行とともに失敗します。
ただし, 実行が失敗するのは, アクションの実行順序が不正な場合のみです。
例えば「指定されたメッセージ "Hoge" が送信されること
」を後に期待している場合に メッセージ "Fuga" が送信されたとしても, このシナリオは即座に失敗しません。
そのあとに正しいメッセージが時間内に送信された場合は, このシナリオは成功します。
上記の例で云うところの, メッセージ fuga
が送信される前に, プレイヤが死亡してしまった場合は, このシナリオは失敗します。
条件要求(require
) タイプ
条件要求(require
) タイプは, 引数に指定された条件が既に満たされているかどうかを検証します。
Scenamatica はシナリオを上から順に実行しますから, このタイプを使っているシナリオに到達する前までに条件が満たされていない場合は, そのシナリオは失敗します。
シナリオ内以外の使用法としては, これは条件付き実行の条件の指定に使用します。
- シナリオが成功する条件
- 条件がこのシナリオの到達時に満たされている。
- シナリオが失敗する条件
- 条件がこのシナリオの到達時に満たされていない。
- 条件がこのシナリオの到達後に満たされる。
例えば, 以下のようなシナリオについて考えます:
- アクション A を実行する
- プレイヤ P がアイテム X を持っていること(条件)を要求する
- アクション B を実行する
このシナリオでは, シナリオ 2 の到達時に Scenamatica はプレイヤ P がアイテム X を持っているかどうかを確認します。
シナリオ 1 の実行完了と同じタイミング(同チック)時点で, 指定された条件が満たされていない場合は, このシナリオは失敗します。
このタイプはそのシナリオに到達する前に条件を満たしていることを確認するためのものです。
そのために, 満たされるまで待機したり, タイムアウトまで待機する機能はありません。
このような機能を使用したい場合は, 代わりにアクション実行期待(expect
) タイプを使用してください。
scenario:
# Actor1 が死亡していることを要求する。
- type: require
action: player_death
with:
target: Actor1
実 行順
この機能を使用すれば, 同じシナリオセッション内でのシナリオの実行順序を制御できます。
シナリオの実行順序は, シナリオファイルの order
プロパティによって制御されます。
これを設定しない場合や, 順次指定が重複した場合は, 自動的にシナリオの名前順でソートされます。
例えば, 以下のシナリオが同じシナリオセッションに追加されている時,
order
プロパティによって実行順序が制御され, test-fuga-success.yml
が最初に実行されます。
name: "test-hoge-success"
description: "hoge 機能の正常系テスト"
order: 2
# ...
name: "test-fuga-success"
description: "fuga 機能の正常系テスト"
order: 1
# ...
例えば, 以下のようなシナリオと, それらが所属するセッションを考えます。
- シナリオA -
order: 1
- シナリオB -
order: 2
- シナリオC -
order: 3
- シナリオD - (未設定)
- セッション[0]
- シナリオD
- シナリオA
- シナリオC
- セッション[1]
- シナリオD
- シナリオB
セッションはキューに追加された順に実行されますから, 最終的なシナリオの実行順は {D -> A -> C}
-> {D -> B}
となります。