docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Tests architecture

    How the package's tests exercise commands. There are two complementary styles — ViaClient (over real HTTP, end-to-end) and CommandDirect (calling the static command method straight) — backed by a small set of shared test helpers.

    Two test styles

    ViaClient — exercise the full HTTP path

    Spin up an isolated PipelineTestServer and call server.Execute(command, params). This goes over HTTP through the same routing, parameter coercion, and threading the real server uses — it tests the command as a client sees it.

    [Test]
    public void SetTransform_ViaClient_ArrayParams_Apply()
    {
        var go = Track(new GameObject("Xform219_Arrays"));
    
        using (var server = new PipelineTestServer())
        {
            var response = server.Execute("set_transform", new
            {
                target   = new { instanceId = PipelineUtils.GetObjectId(go) },
                position = new[] { 1f, 2f, 3f },
                rotation = new[] { 0f, 90f, 0f },
                scale    = new[] { 2f, 2f, 2f }
            });
    
            Assert.IsTrue(response.IsSuccess, $"set_transform should succeed: {response.Error}");
            Assert.AreEqual(new Vector3(1, 2, 3), go.transform.localPosition);
        }
    }
    

    The test server is isolated: it uses the test editor port range 7850–7899 and writes no descriptor, so it never disturbs the live editor server (which uses 7800–7849). Execute pumps the server's own dispatcher while the HTTP call is in flight, so MainThreadRequired commands complete even from a plain [Test] that blocks the main thread — no deadlock.

    CommandDirect — call the static method directly

    Call the command's static method with typed arguments. This is synchronous, with no server, HTTP, or dispatcher involved — fast and ideal for unit-testing command logic and parameter handling.

    [Test]
    public void SetTransform_Direct_TypedArrays_Apply()
    {
        var go = Track(new GameObject("Xform219_Direct"));
    
        GameObjectCommands.SetTransform(RefTo(go),
            position: new[] { 1f, 2f, 3f },
            rotation: new[] { 0f, 90f, 0f },
            scale:    new[] { 2f, 2f, 2f });
    
        Assert.AreEqual(new Vector3(1, 2, 3), go.transform.localPosition);
        Assert.AreEqual(new Vector3(2, 2, 2), go.transform.localScale);
    }
    

    Use CommandDirect to verify a command's behavior with strongly-typed inputs; use ViaClient to additionally verify wire-level concerns (JSON coercion, required-parameter validation, threading).

    Shared helpers

    Helper Role
    PipelineTestServer Disposable wrapper that starts an isolated TestEditorPipelineServer, wires up a PipelineClient, and exposes Execute(command, parameters, timeoutMs = 30000). Pumps the server dispatcher during each call to avoid main-thread deadlock.
    TestEditorPipelineServer EditorPipelineServer subclass for tests. Overrides WritesDescriptor => false, GetPortRange() => (7850, 7899), and GetToken() (from SecurityTokenManager) so it is fully isolated from the live server.
    PipelineClient Test-side HTTP client. Constructed from a URL+token or a server/manager instance. Key methods: ExecuteCommandAsync (/api/exec), GetStatusAsync (/api/status), PostJsonAsync. Returns a PipelineResponse (IsSuccess, StatusCode, Error, JsonResponse, IsCommandSuccess).
    EditorTestUtilities Async helpers for editor state, e.g. WaitFor(Func<bool> condition, timeoutMs) to poll a condition without busy-waiting.
    LiveServerGuard Assembly-level ITestAction that asserts the live editor server survives the test run.

    PipelineTestServer setup

    public PipelineTestServer()
    {
        m_Server = new TestEditorPipelineServer();
        m_Server.Start(); // auto-assigns a port in 7850-7899; writes no descriptor
        m_Client = new PipelineClient($"http://localhost:{m_Server.Port}", SecurityTokenManager.GetOrCreateToken());
    }
    

    Wrap it in a using (it is disposable) so the isolated server is stopped at the end of the test.

    LiveServerGuard

    Applied once at assembly scope ([assembly: LiveServerGuard]), it runs before and after every test in the editor suite. If a live editor server was advertising its descriptor before a test, the guard asserts afterwards that the test did not disturb it — the descriptor still exists, the port is unchanged, and the server is still listening:

    Assert.IsNotNull(after, $"'{test.Name}' deleted the live pipeline server descriptor");
    Assert.AreEqual(m_Before.Port, after.Port, $"'{test.Name}' changed the port");
    Assert.IsTrue(IsListening(after.Port, after.EvalToken), $"'{test.Name}' left the server not responding");
    

    This is what makes it safe to "dogfood" — run the test suite against the very editor you are driving — without a test clobbering the live server. Tests that intentionally start/stop the live server are marked [Explicit] and must hand it back intact.

    See also

    • Creating commands — the command API these tests exercise.
    • Connectivity — ports, descriptor, and auth (the test server deliberately skips the descriptor).
    In This Article
    Back to top
    Copyright © 2026 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)