t3ide/php-lsp-test

PHPUnit-first LSP blackbox testing tools for PHP

Maintainers

Package info

github.com/t3ide/php-lsp-test

pkg:composer/t3ide/php-lsp-test

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-03-22 17:48 UTC

This package is not auto-updated.

Last update: 2026-04-20 17:07:20 UTC


README

php-lsp-test is a lightweight test harness for Language Server Protocol (LSP) servers in PHP projects, built for reliable use with PHPUnit.

It is inspired by pytest-lsp, but intentionally adapted to PHP and synchronous PHPUnit workflows instead of async pytest fixtures.

Goals

  • Start and control real LSP server processes from tests
  • Send and receive JSON-RPC messages over stdio
  • Assert protocol behavior in unit, integration, and end-to-end scenarios
  • Reproduce editor-like flows in a deterministic PHPUnit environment
  • Surface actionable diagnostics when tests fail (stderr/stdout/log messages)

Installation

Add as a dev dependency:

composer require --dev t3ide/php-lsp-test

Quickstart (PHPUnit)

Use LanguageServerTestCase to spin up and initialize a client quickly:

<?php

declare(strict_types=1);

use T3IDE\LanguageServerProtocol\Structure\InitializeParams;
use T3IDE\PhpLspTest\Capability\CapabilityRepository;
use T3IDE\PhpLspTest\PHPUnit\LanguageServerTestCase;

final class MyLspTest extends LanguageServerTestCase
{
    public function testServerInitialize(): void
    {
        $capabilities = CapabilityRepository::withDefaultSnapshots()->get('generic');

        $client = $this->initializeLanguageClient(
            ['php', '/path/to/server.php'],
            new InitializeParams(1, 'file:///workspace', $capabilities),
        );

        // ... send requests / assert responses ...

        $client->shutdownSession();
    }
}

Capabilities

Capability snapshots are managed by CapabilityRepository.

Built-in usage includes:

  • generic
  • version selectors like:
    • name@latest
    • name@v1
    • name@1.2.0

This enables reproducible client simulation while still supporting latest-style test targets.

Diagnostics on Failures

LanguageServerTestCase appends client diagnostics to test failures:

  • process running state, pid, and exit code
  • collected stderr/stdout
  • recent window/logMessage entries

For protocol-level failures, termination details are also surfaced (exit code plus stderr), which helps with server crash and broken-pipe debugging.

Protocol and Process Robustness

php-lsp-test includes coverage for edge cases such as:

  • server exits while waiting for notifications
  • invalid JSON payloads from server
  • server termination mid request sequence
  • explicit result: null JSON-RPC response handling

Extensibility

LanguageClient supports overriding default handlers for server requests and notifications, enabling test-specific behavior without forking core client logic.

Relationship to pytest-lsp

This project borrows core ideas from pytest-lsp:

  • realistic client/server test orchestration
  • capability-driven checks
  • strong diagnostics around process and protocol failures

Implementation choices are intentionally PHP-first:

  • synchronous API design suitable for PHPUnit
  • typed PHP structures and exception model
  • process lifecycle and teardown behavior aligned with common PHP CI setups

License

MIT. See LICENSE.md.