Minecraft Plugin Quality Platform

Real server integration tests for Paper and Spigot.

LightKeeper provisions, caches, and launches full server runtimes, then gives your JUnit tests fluent handles for worlds, bots, menus, commands, and assertions.

Why LightKeeper

Not mocks. Not simulators.

Execute tests against an actual Minecraft server process, with your plugin and dependencies loaded exactly as they would be in production.

Fast repeated runs

Server binaries and base server directories are cached, so retry and CI loops avoid unnecessary re-downloads and rebuilds.

Bot-level API

Create synthetic players, execute commands, place blocks, interact with inventories, and verify world/menu/player state with fluent assertions.

First-class provisioning

Bring your own world folders or archives, plugin jars or Maven artifacts, and overlay config trees into the prepared server.

How it works

  1. lightkeeper:prepare-server resolves/builds and caches the server runtime.
  2. LightKeeper writes a runtime manifest with socket/auth/config metadata.
  3. JUnit tests connect through LightkeeperExtension and framework handles.
  4. Tests drive synthetic players and validate world/menu/chat behavior.
  5. lightkeeper:cleanup-server optionally removes target server directories on success.

Core test example

@ExtendWith(LightkeeperExtension.class)
class MyPluginIT {
    @Test
    void botCanOpenMenuAndPlaceBlock(ILightkeeperFramework framework) {
        final WorldHandle world = framework.mainWorld();
        final PlayerHandle player = framework.buildPlayer()
            .withName("lk_tester")
            .atSpawn(world)
            .build();

        player.executeCommand("myplugin open")
            .andWaitForMenuOpen(10)
            .verifyMenuName("Main Menu")
            .clickAtIndex(0)
            .andWaitTicks(1);

        player.placeBlock("minecraft:stone", 1, 100, 0).andWaitTicks(1);
        assertThat(world).hasBlockAt(1, 100, 0).ofType("minecraft:stone");
    }
}