mcpField
R
roblox-testing

roblox-testing

github.com/el4cteoテスト・品質54511 回インストール2 週間前に更新
リポジトリ

roblox-testing について

Roblox ゲーム開発者向けのテストガイドです。テストしやすいコード構成、Jest Lua によるテスト、Studio・CLI・クラウドでの実行方法を扱い、マルチプレイヤーのテスト方法とリリース前チェックリストも示します。

主な機能

  1. 01ゲームロジックを純粋なモジュールに分離
  2. 02依存性注入とテスト用フェイクの利用
  3. 03Jest Lua によるテストの作成と実行
  4. 04Studio、CLI、クラウドでのテスト実行
  5. 05複数クライアントとデバイスシミュレーターでのプレイテスト
  6. 06リリース前チェックリストで機能を確認

活用シーン

  1. 01インベントリ、ダメージ、ショップのロジック検証
  2. 02インメモリのフェイクでデータサービスをテスト
  3. 03CI でヘッドレステストを実行
  4. 04マルチプレイヤー同期とデバイス対応を確認

MCP 対応

Studio MCP の `execute_luau`、`start_stop_play`、`get_console_output` を使い、エージェントが開いているプレースでテストやプレイテストを実行する方法を紹介します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/el4cteo/roblox-skills --skill roblox-testing

インストール後、Claude Code で/roblox-testingを入力して読み込まれたか確認します。

同梱ファイルreferences/cloud-test-runner.md

詳細

Roblox ゲームのテスト

まずテスト可能なコードにする

  • ゲームルールは純粋な ModuleScript(入力 → 出力、サービスなし、yield なし)にまとめます。ダメージ計算式、インベントリ操作、ショップの価格設定、状態マシン、シリアライズ、検証などが該当します。これらは簡単にテストできます。
  • サービスは依存関係をパラメーターとして受け取るようにします(依存性注入)。そうすれば、テストでは実際の DataStore、リモート、Players の代わりにフェイクを渡せます。
--!strict
-- ReplicatedStorage/Shared/Inventory.luau — pure logic, no Roblox services.
export type Inventory = { [string]: number }

local Inventory = {}

function Inventory.add(inventory: Inventory, itemId: string, amount: number, maxStack: number): (boolean, string?)
	if amount <= 0 or amount ~= math.floor(amount) then
		return false, "invalid amount"
	end
	local current = inventory[itemId] or 0
	if current + amount > maxStack then
		return false, "stack full"
	end
	inventory[itemId] = current + amount
	return true, nil
end

return Inventory
--!strict
-- A service that receives its data store, so tests can inject an in-memory fake.
type Store = {
	GetAsync: (self: Store, key: string) -> any,
	SetAsync: (self: Store, key: string, value: any) -> (),
}

local function newCurrencyService(store: Store)
	local service = {}
	function service.award(userId: number, amount: number): number
		local key = `User_{userId}`
		local balance = (store:GetAsync(key) or 0) + amount
		store:SetAsync(key, balance)
		return balance
	end
	return service
end

-- In tests: a fake store backed by a table.
local fakeData: { [string]: any } = {}
local fakeStore: Store = {
	GetAsync = function(_self, key)
		return fakeData[key]
	end,
	SetAsync = function(_self, key, value)
		fakeData[key] = value
	end,
}
print(newCurrencyService(fakeStore).award(1, 50))

return newCurrencyService

Jest Lua(推奨フレームワーク)

Jest の移植版です(describe/it/expect、モック、スナップショット)。TestEZ はレガシーです。Jest Lua 3 には移行ガイドが含まれています。

# wally.toml
[dev-dependencies]
Jest = "jsdotlua/[email protected]"
JestGlobals = "jsdotlua/[email protected]"
-- src/shared/Inventory.spec.luau
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local JestGlobals = require(ReplicatedStorage.DevPackages.JestGlobals)
local Inventory = require(ReplicatedStorage.Shared.Inventory)

local describe, it, expect = JestGlobals.describe, JestGlobals.it, JestGlobals.expect

describe("Inventory.add", function()
	it("stacks items up to the limit", function()
		local inventory = {}
		expect(Inventory.add(inventory, "Apple", 3, 5)).toBe(true)
		expect(inventory.Apple).toBe(3)
		local ok, reason = Inventory.add(inventory, "Apple", 3, 5)
		expect(ok).toBe(false)
		expect(reason).toBe("stack full")
	end)

	it("rejects fractional amounts", function()
		expect(Inventory.add({}, "Apple", 0.5, 5)).toBe(false)
	end)
end)
  • 各テストルートに jest.config.luau(return { testMatch = { "**/*.spec" } })を配置します。
  • ランナースクリプト(Studio のコマンドバー、テスト用 place の Script、またはクラウドタスク): require(ReplicatedStorage.DevPackages.Jest).runCLI(root, { ci = true }, { root }):awaitStatus() → result.results.numFailedTests を確認します。
  • Jest Lua 3 をローカルで実行するには、Studio の ClientAppSettings.json で高速フラグ FFlagEnableLoadModule = true を設定する必要があります。
  • DevPackages はテストビルド時にのみ DataModel にマッピングします(例:別の Rojo プロジェクト test.project.json を使用)。

テストの実行場所

ランナー用途
Studio(コマンドバー/テスト用 Script)ローカル開発。
Studio MCP(execute_luau、start_stop_play、get_console_output)開いている place でテストやプレイテストを実行するエージェント向け。roblox-studio-mcp を参照してください。
run-in-robloxStudio を開いてスクリプトを実行し、出力をパイプする CLI(Studio のインストールが必要。ローカル/Windows/mac CI ランナーに対応)。
Open Cloud Luau Executionヘッドレス CI:公開済み place バージョンの実際の Roblox サーバーでスクリプトを実行します。
LuneRoblox API に依存しない純粋な Luau モジュール向け(高速で、どこでも実行できます)。

Open Cloud Luau Execution の手順(詳細とスクリプト:references/cloud-test-runner.md):

  1. テスト用 place をビルドし(rojo build test.project.json -o test.rbxl)、専用のテスト用 place の Saved バージョンとしてアップロードします。
  2. { "script": ... } を指定して POST /cloud/v2/universes/{u}/places/{p}/versions/{v}/luau-execution-session-tasks を実行します(API キーのスコープは universe.place.luau-execution-session:write、レート制限はキー所有者あたり約 5 タスク/分)。
  3. タスクの path をポーリングし、state が COMPLETE/FAILED になるまで待ちます。output.results と .../logs を読み取ります。

Studio でのプレイテスト

  • Test タブ:Play(自分+サーバー)、Run(サーバーのみ、キャラクターなし)、Clients and Servers(プレイヤー 2 人以上)でレプリケーション、トレード、PvP をテストします。マルチプレイヤーのバグのほとんどは、クライアントが 2 つ以上でないと発生しません。
  • Device Simulator ツールバー(Test → Device Simulator、ビューポート上部):プレイテスト中にスマートフォン/タブレット/コンソールを切り替え、タッチ操作のヒントを確認できます。Network Simulator では 3G/4G/Wi-Fi/有線、またはカスタムの受信/送信レイテンシ、ジッター、パケット損失を適用して、ラグ補正や読み込み/再試行時の UX をテストできます。ゲームパッド入力には Controller Emulator を使用します。
  • ストリーミング:StreamingTargetRadius = 64 に設定してテストします。
  • Studio での DataStore:API アクセスを有効にし、別のテスト用ユニバースまたはデータストア名を使用します。

機能リリース前の QA チェックリスト

  • 機能の開始後に参加したプレイヤー(途中参加者)や、リスポーン後のプレイヤーでも正常に動作する。
  • クライアントが 2 つ以上でも動作する。サーバーが状態を管理し、すべてのクライアントで UI が更新される。
  • プレイヤーがアクション中(トレード、購入、ラウンド中)に退出しても、状態の破損やテーブルのリークが発生しない。
  • リモートに対するスパム送信や、不正な引数を含む送信が拒否される。
  • テレポートによる place 間の移動も含め、データが保存され、再読み込みされる。
  • モバイル、ゲームパッド、キーボードのすべてで動作し、スマートフォンでも UI が読みやすい。
  • Output にエラーや警告がない(サーバーとクライアントの両方)。

関連スキル

roblox-tooling(CI、Rojo)、roblox-studio-mcp(エージェント主導のプレイテスト)、roblox-open-cloud、roblox-code-review。

コメント