This project is a basic but runnable API automation framework built with Java, Maven, TestNG, and Rest Assured. It includes:
- A local embedded API server that creates and stores user data.
- Optional PostgreSQL-backed persistent storage for the user API.
- Token-based authentication with access tokens, refresh tokens, caching, and synchronized refresh handling.
- Simple and complex nested POJO examples for request/response modelling.
- A TestNG-based API automation layer.
- A configurable high-volume test path that can scale to thousands of API calls.
- Environment-specific config files for local, QA, stage, and prod execution.
- Docker assets for the API server and test runner.
- Kubernetes manifests for deploying the API and running tests as a job.
src/
main/java/com/example/framework/server -> local API server
main/java/com/example/framework/model -> shared request/response models
test/java/com/example/framework -> framework code and API tests
test/resources -> framework config and endpoint paths
k8s/ -> Kubernetes manifests
The default mode still uses in-memory storage. Persistent storage is currently implemented for /users when the server is started with PostgreSQL settings.
GET /healthPOST /auth/tokenPOST /auth/refreshPOST /usersGET /usersGET /users/{id}PUT /users/{id}PATCH /users/{id}DELETE /users/{id}POST /seed?count=10POST /profilesPUT /profiles/{id}PATCH /profiles/{id}GET /profiles/{id}DELETE /profiles/{id}POST /ordersPUT /orders/{id}PATCH /orders/{id}GET /orders/{id}DELETE /orders/{id}
PUT expects a full replacement payload. PATCH supports partial updates, deep-merges nested objects, and replaces arrays when they are provided.
Start the test suite with the embedded API server:
mvn testRun with a higher request volume:
mvn test -Dapi.request.count=10000 -Dapi.parallel.threads=50Run against a named environment:
mvn test -Dapi.env=qaEnable full Rest Assured request and response logging:
mvn test -Dapi.logging.enabled=trueChange the logging detail level:
mvn test -Dapi.logging.enabled=true -Dapi.logging.detail=BODYAvailable environment files:
src/test/resources/config.properties
src/test/resources/config-local.properties
src/test/resources/config-qa.properties
src/test/resources/config-stage.properties
src/test/resources/config-prod.properties
src/test/resources/endpoints.properties
Logging-related properties:
api.logging.enabled=false
api.logging.detail=ALL
api.logging.on.validation.failure=true
api.response.time.assert.enabled=true
api.response.time.max.ms=5000
Retry-related properties:
api.retry.enabled=true
api.retry.max.attempts=3
api.retry.delay.ms=250
api.retry.retryable.status.codes=429,500,502,503,504
Example retry override:
mvn test -Dapi.retry.max.attempts=5 -Dapi.retry.delay.ms=500Example response-time override:
mvn test -Dapi.response.time.max.ms=2000Authentication-related properties:
api.auth.enabled=true
api.auth.username=demo-api-user
api.auth.password=demo-api-password
api.auth.access.token.expiry.skew.seconds=3
Package the standalone API server jar:
mvn -DskipTests packageRun the API server directly:
java -Dserver.port=9876 -jar target/rest-api-framework-1.0.0-shaded.jarRun the API server with PostgreSQL-backed user storage:
java -Dserver.port=9876 -Dserver.user.store.type=jdbc -Ddb.url=jdbc:postgresql://localhost:5432/api_framework -Ddb.username=postgres -Ddb.password=postgres -jar target/rest-api-framework-1.0.0-shaded.jarRun tests against an already-running server:
mvn test -Dapi.base.url=http://localhost:9876 -Dapi.start.embedded.server=falseBuild the API image:
docker build -f Dockerfile.server -t java-api-framework/local-api:latest .Build the test image:
docker build -f Dockerfile.tests -t java-api-framework/api-tests:latest .Run both with Compose:
docker compose up --build --abort-on-container-exitdocker compose now starts PostgreSQL, the API server, and the test runner together. The API container uses JDBC-backed persistent storage for /users, while the nested profile and order demo endpoints still remain in memory.
The test layer also performs automatic per-test cleanup for created users, profiles, and orders. Each test registers the ids it creates, and BaseApiTest deletes them after the method finishes in reverse order. This keeps runs isolated, which is especially important when you use persistent storage or run inside Docker and Kubernetes.
Docker test reports are written to:
docker-results/api-tests/
Apply the API deployment and service:
kubectl apply -f k8s/local-api-deployment.yaml
kubectl apply -f k8s/local-api-service.yamlRun the test job:
kubectl apply -f k8s/api-tests-job.yaml- The server uses
ConcurrentHashMapandAtomicLong, so it is safe for concurrent local test traffic. - The test suite uses TestNG parallel execution and a parallel data provider.
- For 10,000 calls, increase JVM heap and tune
api.parallel.threadsbased on your machine or cluster capacity. - In Kubernetes, scale the API deployment replicas separately from the test job parallelism.
- Docker-based test runs write reports into
docker-results/api-testson the host machine.