A Testcontainer implementation for the A2A (Agent2Agent) Java Server, providing an easy way to integration test A2A protocol implementations.
This project provides a Docker-based testcontainer that wraps the A2A Java helloworld server, making it simple to start and test against an A2A server instance in your integration tests.
- Easy Integration: Simple Java API for starting/stopping A2A server containers
- Health Checks: Built-in health monitoring and readiness detection
- Flexible Configuration: Support for custom Docker images and environment variables
- Rich API: Methods for interacting with agent cards, sending messages, and health checks
- Multi-container Support: Run multiple A2A server instances simultaneously
- Test-friendly: Designed specifically for integration testing scenarios
- Java 11 or higher
- Docker
- Maven
Add the dependency to your pom.xml:
<dependency>
<groupId>io.a2a.testcontainers</groupId>
<artifactId>a2a-java-testcontainer</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>First, build the A2A server Docker image:
docker build -t a2a-java-server:latest .import io.a2a.testcontainers.A2AServerContainer;
import com.fasterxml.jackson.databind.JsonNode;
@Test
void testA2AServer() throws IOException {
try (A2AServerContainer container = new A2AServerContainer()) {
container.start();
// Get server URL for your client
String serverUrl = container.getServerUrl();
// Get agent information
JsonNode agentCard = container.getPublicAgentCard();
assertEquals("Hello World Agent", agentCard.get("name").asText());
// Send message to agent
String response = container.sendMessage("Hello!");
assertTrue(response.contains("Hello World"));
// Use serverUrl with your A2A client for testing
// YourA2AClient client = new YourA2AClient(serverUrl);
// client.connect();
// String result = client.query("test message");
}
}A2AServerContainer()- Create container with default imageA2AServerContainer(String dockerImageName)- Create container with custom image
start()- Start the container and wait for readinessstop()- Stop the containergetServerUrl()- Get the base URL of the A2A servergetPublicAgentCard()- Get the agent's public card as JsonNodesendMessage(String message)- Send a message and get responseisHealthy()- Check if server is healthywaitForReady(Duration timeout)- Wait for server with custom timeout
withEnv(String key, String value)- Add environment variablewithLogConsumer(Consumer<OutputFrame> logConsumer)- Capture logs
A2AServerContainer container = new A2AServerContainer()
.withEnv("QUARKUS_LOG_LEVEL", "DEBUG")
.withEnv("CUSTOM_SETTING", "value")
.withLogConsumer(frame -> System.out.print("[A2A] " + frame.getUtf8String()));@Test
void testMultipleServers() {
A2AServerContainer server1 = new A2AServerContainer();
A2AServerContainer server2 = new A2AServerContainer();
try {
server1.start();
server2.start();
// Different ports automatically assigned
assertNotEquals(server1.getMappedPort(9999), server2.getMappedPort(9999));
// Test both servers
assertTrue(server1.isHealthy());
assertTrue(server2.isHealthy());
} finally {
server1.stop();
server2.stop();
}
}Set environment variable to skip tests requiring Docker:
export SKIP_INTEGRATION_TESTS=true
mvn test# Clone the repository
git clone <repository-url>
cd a2a-java-testcontainer
# Build the Docker image
docker build -t a2a-java-server:latest .
# Run tests (requires Docker)
mvn test
# Skip integration tests
export SKIP_INTEGRATION_TESTS=true
mvn test
# Build the project
mvn clean packageThe testcontainer consists of:
- Dockerfile: Multi-stage build that clones a2a-java repo and builds the helloworld server
- A2AServerContainer: Java wrapper that extends Testcontainers GenericContainer
- Test Classes: Comprehensive tests and examples showing usage patterns
- Base Image: Eclipse Temurin 17 JRE
- Build Process: Maven build of a2a-java helloworld server
- Port: 9999 (configurable)
- Health Check: Quarkus health endpoint (
/q/health) - User: Non-root user for security
The containerized server provides:
- Agent Name: "Hello World Agent"
- Capabilities: Streaming, push notifications, state transition history
- Skills: Single "hello_world" skill that returns "Hello World" responses
- Protocol Version: A2A 0.3.0
- Endpoints:
/a2a/agent-card/public- Get public agent card/a2a/invoke- Send JSON-RPC messages/q/health- Health check
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the same terms as the A2A Java project.
- A2A Java SDK - The original A2A Java implementation
- Testcontainers - Integration testing with Docker containers