
roblox-testing
Testing Roblox code - testable modules with dependency injection, Jest Lua (runCLI, .spec files), legacy TestEZ, running tests in Studio, via Studio MCP, run-in-roblox, or CI with Open Cloud Luau Execution, Lune for pure Luau, multi-client playtests, QA checklist. Use when adding tests, setting up a test runner or CI, or verifying a gameplay change works.
- Installs
- 477
- Last 24h
- +24
- Trending rank
- #5072
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/el4cteo/roblox-skills --skill roblox-testing- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads roblox-testing automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Testing Roblox games
Make code testable first
- Keep game rules in pure ModuleScripts (inputs → outputs, no services, no yields): damage formulas, inventory operations, shop pricing, state machines, serialization, validation. These are trivially testable.
- Services take their dependencies as parameters (dependency injection) so tests can pass fakes
instead of real DataStores, remotes, or
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 (recommended framework)
Port of Jest (describe/it/expect, mocks, snapshots). TestEZ is legacy; Jest Lua 3 includes a
migration guide.
# wally.toml
[dev-dependencies]
Jest = "jsdotlua/jest@3.10.0"
JestGlobals = "jsdotlua/jest-globals@3.10.0"
-- 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)
- Put a
jest.config.luau(return { testMatch = { "**/*.spec" } }) in each test root. - Runner script (Studio command bar, a test place Script, or cloud task):
require(ReplicatedStorage.DevPackages.Jest).runCLI(root, { ci = true }, { root }):awaitStatus()→ inspectresult.results.numFailedTests. - Jest Lua 3 needs the fast flag
FFlagEnableLoadModule = truein Studio'sClientAppSettings.jsonwhen run locally. - Map
DevPackagesinto the DataModel only for test builds (separate Rojo project, e.g.test.project.json).
Where tests run
| Runner | Use |
|---|---|
| Studio (command bar / test Script) | Local development. |
Studio MCP (execute_luau, start_stop_play, get_console_output) | Agents running tests and playtests against the open place — see roblox-studio-mcp. |
run-in-roblox | CLI that opens Studio, runs a script, pipes output (needs Studio installed; local/Windows/mac CI runners). |
| Open Cloud Luau Execution | Headless CI: runs a script in a real Roblox server for a published place version. |
| Lune | Pure-Luau modules with no Roblox API dependencies (fast, runs anywhere). |
Open Cloud Luau Execution flow (details and a script: references/cloud-test-runner.md):
- Build the test place (
rojo build test.project.json -o test.rbxl) and upload it as a Saved version of a dedicated test place. POST /cloud/v2/universes/{u}/places/{p}/versions/{v}/luau-execution-session-taskswith{ "script": ... }(API key scopeuniverse.place.luau-execution-session:write; rate limit ≈ 5 tasks/min per key owner).- Poll the task
pathuntilstateisCOMPLETE/FAILED; readoutput.resultsand.../logs.
Playtesting in Studio
- Test tab: Play (you + server), Run (server only, no character), Clients and Servers with 2+ players to test replication, trading, and PvP. Most multiplayer bugs only appear with ≥ 2 clients.
- Device Simulator toolbar (Test → Device Simulator, top of the viewport): switch phone/tablet/console mid-playtest, with touch-control hints; its Network Simulator applies 3G/4G/Wi-Fi/wired or custom inbound/outbound latency, jitter, and packet loss to test lag compensation and loading/retry UX. Controller Emulator for gamepad input.
- Streaming: test with
StreamingTargetRadius = 64. - DataStores in Studio: enable API access and use a separate test universe or data store names.
QA checklist before shipping a feature
- Works for a player who joins after the feature started (late joiners), and after respawn.
- Works with 2+ clients; server state is authoritative; UI updates on all clients.
- Player leaving mid-action (trade, purchase, round) leaves no broken state or leaked tables.
- Remotes rejected when spammed or sent malformed arguments.
- Data saves and reloads (rejoin), including teleports between places.
- Mobile, gamepad, and keyboard all work; UI readable on a phone.
- No errors/warnings in Output (server and client).
Related skills
roblox-tooling (CI, Rojo), roblox-studio-mcp (agent-driven playtests), roblox-open-cloud,
roblox-code-review.
FAQ
What does the roblox-testing skill do?
Testing Roblox code - testable modules with dependency injection, Jest Lua (runCLI, .spec files), legacy TestEZ, running tests in Studio, via Studio MCP, run-in-roblox, or CI with Open Cloud Luau Execution, Lune for pure Luau, multi-client playtests, QA checklist. Use when adding tests, setting up a test runner or CI, or verifying a gameplay change works.
How do I install roblox-testing?
Run npx skills add https://github.com/el4cteo/roblox-skills --skill roblox-testing in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/roblox-testing/ (personal) or .claude/skills/roblox-testing/ (project).
Which AI agents can use roblox-testing?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is roblox-testing safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains roblox-testing?
It is published by el4cteo in el4cteo/roblox-skills. It has 477 recorded installs.
More from el4cteo/roblox-skills
roblox-world-building
el4cteo/roblox-skills
Building worlds with code - parts, models and pivots, materials, Lighting (LightingStyle, Atmosphere, post-processing), day/night, Terrain API, in-game CSG and destruction (GeometryService Subtract/Union/Fragment), ProceduralModel, EditableMesh/EditableImage, particles/beams/trails/highlights. Use when creating maps, environments, lighting, destructible objects, procedural levels, or visual effects.
roblox-ui
el4cteo/roblox-skills
Responsive cross-platform UI - ScreenGui and safe areas (ScreenInsets), Scale vs Offset, UIListLayout flex/UIFlexItem, constraints, StyleSheets/tokens/themes, RichText, gamepad/touch navigation, UIDragDetector, CanvasGroup, tweens, BillboardGui/SurfaceGui, React-lua/Fusion/Vide. Use when building HUDs, menus, shops, inventories, or fixing UI that breaks on mobile, console, or other screen sizes.
roblox-luau
el4cteo/roblox-skills
Modern, type-safe Luau for Roblox, covering --!strict and the new type solver, generics, string interpolation, if-expressions, task library, require-by-string, module/OOP patterns, error handling with retries, buffer/vector, and legacy APIs to avoid. Use when writing, refactoring, or explaining any Roblox script, fixing type errors, or modernizing old Lua code.
roblox-performance
el4cteo/roblox-skills
Performance diagnosis and optimization - MicroProfiler, Script Profiler, Developer Console, Scene Analysis, Luau heap and memory categories, memory leaks, network/replication cost, rendering and physics cost, streaming, native codegen, Parallel Luau with Actors. Use when a game lags, stutters, drops FPS, crashes on mobile, has high ping, or before optimizing hot code.
roblox-game-systems
el4cteo/roblox-skills
Recipes for common systems built on server authority - currency service and leaderstats, XP/levels, round loops with intermission and teams, validated melee/ranged combat, inventory and tools, soft-currency shops, obby checkpoints, daily rewards, pets. Use when implementing or reviewing gameplay systems such as rounds, combat, weapons, inventories, shops, currencies, or progression.
roblox-security
el4cteo/roblox-skills
Anti-exploit design - never trust the client, validate every remote argument (NaN, spoofed instances, strings), rate limiting, ProximityPrompt/ClickDetector abuse, network ownership, movement and hit validation, economy/trade duplication, code confidentiality, secure teleports, heuristics, Ban API. Use when writing server handlers for client input, combat/economy/trading, or reviewing for exploits.
Popular testing & qa skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
grilling
mattpocock/skills
Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
migrate-to-shoehorn
mattpocock/skills
Migrate test files from as type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
run-train
lllllllama/rigorpilot-skills
Rigor Train skill for deep learning research repositories. Use when a documented or selected training command should be run conservatively for startup verification, short-run verification, full kickoff, or resume, with command, config, seed, log, checkpoint, status, and metric evidence written to standardized trainoutputs/. Do not use for environment setup, exploratory sweeps, speculative idea implementation, or end-to-end orchestration.
test-driven-development
obra/superpowers
Use when implementing any feature or bugfix, before writing implementation code
finishing-a-development-branch
obra/superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work