API tests example for JSONPlaceholder built with Java, RestAssured, JUnit 6, and Gradle.
# Linux/macOS
./gradlew functionalTest
# Windows (PowerShell)
.\gradlew.bat functionalTestOpen report after run:
test-results/junit/functionalTest/html/index.html
This runs all tests annotated with the Functional.
To run all tests (including annotated with Contract and E2E tags), use the test task:
# Linux/macOS
./gradlew test
# Windows (PowerShell)
.\gradlew.bat testJava 25, Gradle 9.3.1 (Wrapper), JUnit 6, RestAssured, AssertJ, Allure
src/
main/java/dev/maksymzapisov/jsonplaceholder/
clients/ # API clients (users, posts)
config/ # Environment/config provider
data/ # Test data provider
model/ # DTO models
specs/ # Request/response specs
utils/ # Reusable response extractors
test/java/dev/maksymzapisov/jsonplaceholder/
users/ # Users endpoint tests
posts/ # Posts/Comments endpoint tests
e2e/ # End-to-end tests
BaseApiTest # Common test setup
Tests are grouped by JUnit tags:
Functional- functional endpoint behavior and search/get scenariosContract- JSON schema validation checksE2E- full e2e workflow
- Java 25 installed (use any provider or version manager your preference: Eclipse Temurin (Adoptium), SDKMAN, Oracle JDK)
- Use Gradle Wrapper (
./gradlew), no local Gradle installation required
Default configuration is in src/test/resources/api.properties:
api.base.uri = https://jsonplaceholder.typicode.com/
api.base.path =
api.port = 443
log.all = falseNotes:
- Configuration is loaded via OWNER with merge policy (
system properties+classpathfile) log.all = trueenables full request/response logging for all tests; whenfalse, logging is triggered only on validation failure- You can override values from command line, for example:
./gradlew test -Dapi.base.uri=https://jsonplaceholder.typicode.com/Linux/macOS:
./gradlew test # runs all tests (functional, contract, e2e)
./gradlew contractTest # runs only contract tests
./gradlew functionalTest # runs only functional tests
./gradlew e2eTest # runs only e2e testsWindows (PowerShell):
.\gradlew.bat test # runs all tests (functional, contract, e2e)
.\gradlew.bat contractTest # runs only contract tests
.\gradlew.bat functionalTest # runs only functional tests
.\gradlew.bat e2eTest # runs only e2e testsJUnit reports are generated under test-results/junit per task:
- XML:
test-results/junit/<task-name>/xml - HTML:
test-results/junit/<task-name>/html
Allure results directory:
test-results/allure-results
To generate and view the Allure report, refer to the Allure JUnit documentation
The project includes a CircleCI pipeline (.circleci/config.yml) that runs on every push.
What the pipeline does:
- Checks out the code
- Restores cached Gradle dependencies (keyed on
build.gradle.ktschecksum) - Runs all tests via
./gradlew test - Stores JUnit XML/HTML reports and Allure results as artifacts
Environment:
- Docker image:
cimg/openjdk:25.0.1
- Users: get all, get by valid/invalid id, search by valid/invalid query combinations
- Posts: get all, get by valid/invalid id, search by valid/invalid query combinations
- Comments: get comments for post, search comments with valid/invalid query combinations
- E2E: search user by username -> search user's posts by userId -> fetch all comments for each post -> for each comment, validate email format
Negative scenarios are primarily covered in atomic endpoint tests (non-E2E).
- Request/response specs are centralized for consistency
- API calls are encapsulated in client classes
- DTO models are strongly typed and reused across tests
- Response extraction is centralized to reduce boilerplate in tests
- Tests are tagged for flexible execution