Reference API Roblox

Engine API

Website

Related

Reference API Roblox

StudioTestService

Service allowing plugins to automate and customize Test and Run mode testing.

This class is not replicated. Its interface does not cross the network boundary.
This class is not creatable. Instances of this class cannot be created with Instance.new.
This class is a service. It is a singleton that may be acquired with GetService.
Tags: [NotCreatable, Service, NotReplicated]

Member index 5

HistoryMember
712EditModeActive: bool
700EndTest(value: Variant): null
700ExecutePlayModeAsync(args: Variant): Variant
700ExecuteRunModeAsync(args: Variant): Variant
700GetTestArgs(): Variant
inherited from Instance
553Archivable: bool
670Capabilities: SecurityCapabilities
553Name: string
553Parent: Instance
702PredictionMode: PredictionMode
670Sandboxed: bool
680UniqueId: UniqueId
576AddTag(tag: string): null
573ClearAllChildren(): null
462Clone(): Instance
573Destroy(): null
486FindFirstAncestor(name: string): Instance
486FindFirstAncestorOfClass(className: string): Instance
486FindFirstAncestorWhichIsA(className: string): Instance
486FindFirstChild(name: string, recursive: bool = false): Instance
486FindFirstChildOfClass(className: string): Instance
486FindFirstChildWhichIsA(className: string, recursive: bool = false): Instance
486FindFirstDescendant(name: string): Instance
563GetActor(): Actor
486GetAttribute(attribute: string): Variant
462GetAttributeChangedSignal(attribute: string): RBXScriptSignal
631GetAttributes(): Dictionary
648GetChildren(): Instances
462GetDebugId(scopeLength: int = 4): string
707GetDescendants(): Instances
486GetFullName(): string
706GetStyled(name: string, selector: string?): Variant
657GetStyledPropertyChangedSignal(property: string): RBXScriptSignal
576GetTags(): Array
576HasTag(tag: string): bool
486IsAncestorOf(descendant: Instance): bool
486IsDescendantOf(ancestor: Instance): bool
664IsPropertyModified(property: string): bool
698QueryDescendants(selector: string): Instances
573Remove(): null
576RemoveTag(tag: string): null
664ResetPropertyToDefault(property: string): null
573SetAttribute(attribute: string, value: Variant): null
462WaitForChild(childName: string, timeOut: double): Instance
648children(): Instances
553clone(): Instance
573destroy(): null
553findFirstChild(name: string, recursive: bool = false): Instance
648getChildren(): Instances
553isDescendantOf(ancestor: Instance): bool
573remove(): null
462AncestryChanged(child: Instance, parent: Instance)
462AttributeChanged(attribute: string)
462ChildAdded(child: Instance)
462ChildRemoved(child: Instance)
462DescendantAdded(descendant: Instance)
462DescendantRemoving(descendant: Instance)
500Destroying()
657StyledPropertiesChanged()
553childAdded(child: Instance)
inherited from Object
647ClassName: string
647className: string
647GetPropertyChangedSignal(property: string): RBXScriptSignal
647IsA(className: string): bool
650isA(className: string): bool
647Changed(property: string)

Description

StudioTestService allows plugins to automate and customize Test and Run mode testing. With StudioTestService, your plugins can launch tests that jump straight to a specific part of your game, or run complex code tests automatically.

You can use StudioTestService to start a server with multiple simulated clients, add players mid-session, pass arguments into running tests, end tests from the server, and trigger client disconnections, all without manually clicking through the Test tab in Studio.

These methods complement the existing playtest automation available through Studio's built-in MCP server. Where the MCP server's start_stop_play tool starts a single Play Client session, the StudioTestService methods are designed for scripted multi-client scenarios such as lobby, matchmaking, and join/leave flow testing.

A typical multiplayer test splits across three script contexts: the plugin that launches it, the server that drives it, and the clients that participate:

Plugin script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
local StudioTestService = game:GetService("StudioTestService")

local toolbar = plugin:CreateToolbar("STS Tests")
local button = toolbar:CreateButton("MyTest", "", "")

button.Click:Connect(function()
    button.Enabled = false
    local result = StudioTestService:ExecuteMultiplayerTestAsync(1, "MyArguments")
    assert(result == "Success!")
    print("Test finished successfully!")
    button.Enabled = true
end)

Server script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
local Players = game:GetService("Players")
local StudioTestService = game:GetService("StudioTestService")

assert(StudioTestService:GetTestArgs() == "MyArguments")

Players.PlayerRemoving:Connect(function(player)
    print(player.Name .. " left the experience")
    task.wait(3)
    StudioTestService:EndTest("Success!")
end)

Client script:

1
2
3
4
5
6
7
if not game:IsLoaded() then
    game.Loaded:Wait()
end

local StudioTestService = game:GetService("StudioTestService")
task.wait(3)
StudioTestService:LeaveTest()

Limitations

  • ExecuteMultiplayerTestAsync can only be called from plugin scripts. It yields until the test ends, so wrap it in a coroutine if the calling plugin needs to remain responsive.
  • ExecuteMultiplayerTestAsync cannot be called from inside a running test.
  • ExecuteMultiplayerTestAsync supports up to 8 simulated clients per test session.
  • Only one multiplayer test session can run at a time per Studio instance.
  • AddPlayers and EndTest must be called from the server DataModel of a running test.
  • CanLeaveTest and LeaveTest must be called from a client DataModel.
  • GetTestArgs currently has a known issue when called from a client LocalScript.

History 6

Members 5

EditModeActive

TypeDefault
booltrue

History 1

EndTest

Parameters (1)
valueVariant
Returns (1)
null

Ends the current Studio test session if called from the server DataModel, even if the test was not started by this service.

If the test was started by StudioTestService:ExecutePlayModeAsync() or StudioTestService:ExecuteRunModeAsync(), the value passed here is returned by that method.

This method returns immediately and ends the test session asynchronously. It errors if called from any DataModel other than that of the server during a running Studio test session.

History 1

ExecutePlayModeAsync

Parameters (1)
argsVariant
Returns (1)
Variant

Starts a solo Test session and yields until that session ends.

The args parameter can be retrieved using StudioTestService:GetTestArgs(). Returns the value passed to StudioTestService:EndTest(), or nil if the test ended by other means.

This method errors if a test session is already running.

This function yields. It will block the calling thread until completion.

History 1

Tags: [Yields]

ExecuteRunModeAsync

Parameters (1)
argsVariant
Returns (1)
Variant

Starts a Run test session and yields until that session ends.

The args parameter can be retrieved using StudioTestService:GetTestArgs(). Returns the value passed to StudioTestService:EndTest(), or nil if the test ended by other means.

This method errors if a test session is already running.

This function yields. It will block the calling thread until completion.

History 1

Tags: [Yields]

GetTestArgs

Parameters (0)
No parameters.
Returns (1)
Variant

Returns the argument passed to StudioTestService:ExecutePlayModeAsync() or StudioTestService:ExecuteRunModeAsync() for the current test session, or nil if the session was not started by those methods.

GetTestArgs returns the value as-is, preserving its type. For example, if the plugin passed a Color3, GetTestArgs returns a Color3.

Note that if you call GetTestArgs a client LocalScript, it may fail. Server-side calls work as expected.

History 1

Settings