Java测试执行服务器

基于Eclipse JDT Core编译器和JUnit 5的快速Java测试执行与代码覆盖率服务,支持增量编译和热重用的测试服务器。

  • by Thejuampi
  • Java
  • 本地部署
  • 更新于
在 GitHub 查看 Thejuampi/eclipse-jdt-test-mcp

使用说明

Eclipse JDT Test MCP Server

A Model Context Protocol (MCP) server that provides fast Java test execution and code coverage using Eclipse JDT Core compiler and JUnit 5.

Features

  • Fast Compilation: Uses Eclipse ECJ (Eclipse Compiler for Java) for incremental compilation
  • Hot-Reuse: Keeps compiler instance in memory for rapid subsequent compilations
  • JUnit 5 Integration: Run individual test methods or entire test classes
  • Code Coverage: Integrated JaCoCo for coverage reporting
  • Stdio Protocol: Exposes MCP tools via standard input/output
  • Framework Agnostic: Generic tool names work with JUnit, TestNG, or any test framework

Requirements

  • Java 21+
  • Gradle 8.0+

Building

# Clone the repository
git clone https://github.com/Thejuampi/eclipse-jdt-test-mcp.git
cd eclipse-jdt-test-mcp

# Build the fat JAR
./gradlew :plugins:org.jdttest.mcp.core:fatJar

Windows users: Use gradlew.bat instead of ./gradlew

The fat JAR will be created at:

plugins/org.jdttest.mcp.core/build/libs/org.jdttest.mcp.core-all.jar

Running

java -jar plugins/org.jdttest.mcp.core/build/libs/org.jdttest.mcp.core-all.jar

Or test directly via stdin/stdout:

echo '{"jsonrpc":"2.0","id":1,"method":"ping"}' | java -jar plugins/org.jdttest.mcp.core/build/libs/org.jdttest.mcp.core-all.jar

MCP Tools

The server exposes 12 tools for project management, test execution, and compilation:

Project Management

1. load_project

Load a Java project for testing. Must be called before other project operations.

Parameters:

  • path (string, required): Path to the project root

Example:

{
  "name": "load_project",
  "arguments": {
    "path": "/path/to/your/project"
  }
}

2. unload_project

Unload the current project and release resources.

Parameters: None

Example:

{
  "name": "unload_project",
  "arguments": {}
}

Core Test Execution

3. run_test

Run a specific test method.

Parameters:

  • className (string, required): Fully qualified class name of the test
  • methodName (string, required): Name of the test method to run
  • coverage (boolean, optional): Whether to collect code coverage (default: false)

Example:

{
  "name": "run_test",
  "arguments": {
    "className": "com.example.CalculatorTest",
    "methodName": "testAddition",
    "coverage": false
  }
}

4. run_tests

Run tests - either a specific class or all tests in the loaded project.

Parameters:

  • className (string, optional): Fully qualified class name of the test class
  • coverage (boolean, optional): Whether to collect code coverage (default: false)

Example:

// Run a specific test class
{
  "name": "run_tests",
  "arguments": {
    "className": "com.example.CalculatorTest"
  }
}

// Run all tests in the loaded project
{
  "name": "run_tests",
  "arguments": {}
}

5. run_all_tests

Run ALL tests in the loaded project.

Parameters:

  • coverage (boolean, optional): Whether to collect code coverage (default: false)

Example:

{
  "name": "run_all_tests",
  "arguments": {}
}

6. run_test_pattern

Run tests matching a name/regex pattern in the loaded project.

Parameters:

  • pattern (string, required): Name pattern (supports wildcards: * and ?)
  • coverage (boolean, optional): Whether to collect code coverage (default: false)

Example:

{
  "name": "run_test_pattern",
  "arguments": {
    "pattern": "*Integration*",
    "coverage": false
  }
}

Test Discovery

7. list_tests

List all discovered test classes and methods in the loaded project.

Parameters: None

Example:

{
  "name": "list_tests",
  "arguments": {}
}

8. get_test_class_info

Get metadata about a test class.

Parameters:

  • className (string, required): Fully qualified class name

Example:

{
  "name": "get_test_class_info",
  "arguments": {
    "className": "com.example.CalculatorTest"
  }
}

Compilation

9. compile_project

Compile the loaded Java project.

Parameters:

  • classpath (array, optional): Additional classpath entries

Example:

{
  "name": "compile_project",
  "arguments": {
    "classpath": ["lib/dependency.jar"]
  }
}

10. compile_source

Compile Java source files using Eclipse JDT.

Parameters:

  • sourcePath (string, required): Path to the Java source file or directory
  • classpath (array, optional): Classpath entries for compilation

Example:

{
  "name": "compile_source",
  "arguments": {
    "sourcePath": "src/main/java/com/example",
    "classpath": ["lib/dependency.jar"]
  }
}

Results & Coverage

11. get_test_results

Get results of the last test run.

Parameters: None

Example:

{
  "name": "get_test_results",
  "arguments": {}
}

12. get_coverage

Get code coverage for a class using JaCoCo.

Parameters:

  • className (string, required): Fully qualified class name to get coverage for

Example:

{
  "name": "get_coverage",
  "arguments": {
    "className": "com.example.Calculator"
  }
}

Typical Usage Workflow

// 1. Load your project
{"name": "load_project", "arguments": {"path": "/path/to/project"}}

// 2. List available tests
{"name": "list_tests", "arguments": {}}

// 3. Run a specific test
{"name": "run_test", "arguments": {"className": "com.example.MyTest", "methodName": "testSomething"}}

// 4. Run all tests
{"name": "run_all_tests", "arguments": {}}

// 5. Get results
{"name": "get_test_results", "arguments": {}}

// 6. Unload when done
{"name": "unload_project", "arguments": {}}

Project Structure

eclipse-jdt-test-mcp/
├── build.gradle.kts                    # Root Gradle build configuration
├── settings.gradle.kts                 # Gradle settings
├── plugins/
│   └── org.jdttest.mcp.core/           # Main OSGi bundle
│       ├── META-INF/
│       │   └── MANIFEST.MF             # OSGi bundle manifest
│       ├── build.gradle.kts            # Bundle build configuration
│       └── src/
│           ├── main/java/com/jdttest/mcp/
│           │   ├── JdtTestMcpPlugin.java      # OSGi bundle activator
│           │   ├── server/
│           │   │   ├── MCPServer.java         # Main MCP server entry point
│           │   │   └── MCPProtocolHandler.java # JSON-RPC protocol handler
│           │   ├── jdt/
│           │   │   ├── JdtCompiler.java       # Eclipse JDT compiler wrapper
│           │   │   └── CompilationUnitCache.java # AST cache for hot-reuse
│           │   ├── runner/
│           │   │   ├── TestRunner.java        # JUnit test runner
│           │   │   └── TestResultStore.java   # Result persistence
│           │   ├── coverage/
│           │   │   └── CoverageAgent.java     # JaCoCo integration
│           │   └── model/
│           │       ├── TestResult.java        # Test result model
│           │       ├── CoverageData.java      # Coverage data model
│           │       └── CompilationResult.java # Compilation result model
│           └── test/java/com/jdttest/mcp/
│               └── server/
│                   └── MCPServerIntegrationTest.java # Integration tests
└── README.md

Architecture

JdtCompiler

  • Wraps Eclipse ECJ for fast Java compilation
  • Maintains in-memory CompilationUnit cache for hot-reuse
  • Returns structured compilation results with errors and warnings
  • Supports Java 21 with all modern language features

TestRunner

  • Uses JUnit Platform Launcher for programmatic test execution
  • Integrates JaCoCo runtime for optional coverage collection
  • Tracks test execution times and results
  • Provides detailed failure information with stack traces

MCPServer

  • Implements MCP protocol via stdio (JSON-RPC 2.0)
  • Exposes 10 tools for test operations
  • Handles initialize, tools/list, and tools/call requests
  • Returns structured JSON responses for all operations

Integration with MCP Clients

To use this server with Claude Code or another MCP client, create a configuration file:

For Claude Code (.claude/eclipse-jdt-test.json)

{
  "_comment": "Eclipse JDT Test MCP Server - Fast JUnit test execution with Eclipse JDT",
  "eclipse-jdt-test": {
    "command": "java",
    "args": [
      "-jar",
      "/absolute/path/to/eclipse-jdt-test-mcp/plugins/org.jdttest.mcp.core/build/libs/org.jdttest.mcp.core-all.jar"
    ],
    "env": {
      "JAVA_HOME": "/path/to/java21"
    }
  }
}

Replace the paths above with your actual paths:

  • /absolute/path/to/eclipse-jdt-test-mcp/ - Where you cloned this repository
  • /path/to/java21 - Your Java 21+ installation directory

Add to .claude/settings.local.json permissions:

{
  "permissions": {
    "allow": [
      "mcp__eclipse-jdt-test__run_test",
      "mcp__eclipse-jdt-test__run_tests",
      "mcp__eclipse-jdt-test__run_all_tests",
      "mcp__eclipse-jdt-test__run_test_pattern",
      "mcp__eclipse-jdt-test__list_tests",
      "mcp__eclipse-jdt-test__get_test_class_info",
      "mcp__eclipse-jdt-test__compile_project",
      "mcp__eclipse-jdt-test__get_test_results",
      "mcp__eclipse-jdt-test__get_coverage",
      "mcp__eclipse-jdt-test__compile_source"
    ]
  },
  "enabledMcpjsonServers": [
    "eclipse-jdt-test"
  ]
}

Testing

Run Tests

# Linux/macOS
./gradlew test

# Windows
gradlew.bat test

Integration Tests

The project includes comprehensive integration tests in MCPServerIntegrationTest.java that verify:

  • All 10 tools are properly registered
  • Tool parameter validation
  • End-to-end message handling
  • Generic naming (framework-agnostic)

Known Limitations

  1. Multi-module Projects: list_tests scans standard paths (src/test/java) and may not find tests in submodules without additional configuration

  2. Test Discovery: run_all_tests and run_test_pattern use package selectors that may not discover all tests without proper classpath configuration

  3. Classpath Dependencies: Projects must provide dependencies via classpath parameter or have classes pre-compiled and available on the classpath

  4. Coverage Collection: JaCoCo integration is basic - full coverage reports require compiled classes on classpath

Usage Tips

For Best Results

  1. Pre-compile your project using Maven/Gradle before running tests
  2. Provide classpath with all dependencies for compilation tools
  3. Use absolute paths for project paths to avoid resolution issues
  4. Framework compatibility: Tools work with JUnit 4, JUnit 5, TestNG, and other frameworks

Typical Workflow

# 1. Build your project first (with Maven or Gradle)
mvn clean compile test-compile

# 2. Use the MCP server to run tests
# The compiled classes will be on the classpath and tests will run

Development

TDD Approach

This project follows Test-Driven Development:

  1. Write failing test first
  2. Implement minimal code to pass
  3. Refactor and improve
  4. Repeat

Adding New Tools

  1. Add tool definition in MCPServer.getToolsDefinition()
  2. Add case in MCPServer.executeTool() switch statement
  3. Implement method in appropriate service class (TestRunner, JdtCompiler, etc.)
  4. Add integration tests in MCPServerIntegrationTest.java

License

MIT