diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6cb966b..d821eea 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,3 +62,39 @@ jobs: run: | ./mvnw -B spring-boot:run & ab -p src/test/resources/apachebench/create-customer-request.json -T application/json -c 10 -n 1000 http://localhost:8080/api/customers + + pact-contract-tests: + runs-on: ubuntu-24.04 + timeout-minutes: 10 + name: pact-contract-tests + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: 'adopt' + java-package: 'jdk' + cache: 'maven' + + - name: Start Pact Broker infrastructure + run: docker compose --file spring-boot-example/docker-pact-broker-compose.yml up -d + + - name: Run consumer contract tests + working-directory: spring-boot-example + run: ./mvnw -B test -Dtest=StockApiContractTest + + - name: Publish pacts to broker + working-directory: spring-boot-example + run: ./mvnw -B pact:publish + + - name: Run provider verification tests + working-directory: spring-boot-example + run: ./mvnw -B test -Dtest=StockApiProviderTest -DdisablePactVerification=false + + - name: Clean up Docker containers + if: always() + run: | + docker compose --file spring-boot-example/docker-pact-broker-compose.yml down -v diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..83a5609 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,107 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Repository Overview + +This is the Java Testing Toolbox - a comprehensive educational repository demonstrating 30 testing tools and libraries for Java developers. The codebase contains practical examples for the book "30 Testing Tools & Libraries Every Java Developer Must Know". + +## Architecture + +### Module Structure +- **spring-boot-example**: Main module containing most testing examples. Each testing tool has its own package under `src/test/java/de/rieckpil/blog/` +- **jakarta-ee-example**: Demonstrates testing in Jakarta EE context, primarily MicroShed Testing + +### Test Organization +- Unit tests: `*Test.java` or `*Spec.groovy` +- Integration tests: `*IT.java` +- Web tests: `*WT.java` +- Performance tests: Located in `gatling` package +- All test examples are self-contained within their respective packages + +## Essential Commands + +### Spring Boot Example + +```bash +# Build and run all tests +./mvnw verify + +# Run unit tests only +./mvnw test + +# Run integration tests only +./mvnw failsafe:integration-test + +# Run specific test class +./mvnw test -Dtest=UserRegistrationServiceTest + +# Start the application (requires Docker) +docker-compose up -d +./mvnw spring-boot:run + +# Run Gatling performance tests (requires running application) +./mvnw gatling:test + +# Run mutation testing +./mvnw pitest:mutationCoverage + +# Generate JGiven reports +./mvnw jgiven:report + +# Run Pact consumer tests +./mvnw test -Dtest=StockApiContractTest + +# Publish pacts to broker (requires running Pact Broker) +docker-compose -f docker-pact-broker-compose.yml up -d +./mvnw pact:publish + +# Run Pact provider verification tests (by default skipped with system property) +./mvnw test -Dtest=StockApiProviderTest +``` + +### Jakarta EE Example + +```bash +# Build and run all tests +./mvnw verify + +# Run unit tests only +./mvnw test + +# Run integration tests +./mvnw failsafe:integration-test + +# Start Liberty server +./mvnw liberty:run +``` + +## Key Testing Patterns + +### Test Infrastructure + +- **Testcontainers**: Used extensively for integration tests requiring databases or external services +- **Docker Compose**: Provides PostgreSQL and other services for local development +- **MockWebServer/WireMock**: For mocking external HTTP services +- **LocalStack**: For testing AWS services locally + +### Testing Frameworks Coverage + +The repository demonstrates these testing categories: + +1. Test Runners: JUnit 4/5, TestNG, Spock +2. Assertions: AssertJ, Hamcrest, JsonPath, XMLUnit, JSONAssert +3. Mocking: Mockito, WireMock, MockWebServer +4. Integration: Testcontainers, REST Assured, MicroShed Testing +5. Web Testing: Selenium, Selenide +6. Performance: Gatling, JMH, JfrUnit +7. Contract Testing: Pact +8. Architecture Testing: ArchUnit + +### Important Conventions + +- Java 21 is required for all modules +- Docker must be running for integration tests +- Test output is redirected to files in CI/CD environments +- Each testing tool example is isolated in its own package +- Examples demonstrate real-world usage patterns, not just basic syntax diff --git a/spring-boot-example/pom.xml b/spring-boot-example/pom.xml index 7e856f4..4acf494 100644 --- a/spring-boot-example/pom.xml +++ b/spring-boot-example/pom.xml @@ -381,6 +381,9 @@ + + true + **/*Spec.java **/*Test.java diff --git a/spring-boot-example/src/test/java/de/rieckpil/blog/pact/StockApiProviderTest.java b/spring-boot-example/src/test/java/de/rieckpil/blog/pact/StockApiProviderTest.java index 6acf17b..504c563 100644 --- a/spring-boot-example/src/test/java/de/rieckpil/blog/pact/StockApiProviderTest.java +++ b/spring-boot-example/src/test/java/de/rieckpil/blog/pact/StockApiProviderTest.java @@ -1,4 +1,4 @@ -package au.com.dius.pactworkshop.provider; +package de.rieckpil.blog.pact; import au.com.dius.pact.provider.junit5.HttpTestTarget; import au.com.dius.pact.provider.junit5.PactVerificationContext; @@ -10,16 +10,16 @@ import de.rieckpil.blog.Application; import org.apache.hc.core5.http.HttpRequest; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -@Disabled("Requires running Pact Broker, see Docker Compose") @Provider("stock-api") +@DisabledIfSystemProperty(named = "disablePactVerification", matches = "true", disabledReason = "Requires running Pact Broker, see Docker Compose") @PactBroker(url = "http://localhost:9292/", authentication = @PactBrokerAuth(username = "pact-sample", password = "pact-sample")) @SpringBootTest(webEnvironment = RANDOM_PORT, classes = Application.class) public class StockApiProviderTest {