Skip to content

Commit 9a7ff26

Browse files
committed
AMP-187 Add api test as a separate module in project which can be invoked from commandline and intellij
1 parent b5bbb79 commit 9a7ff26

File tree

15 files changed

+725
-60
lines changed

15 files changed

+725
-60
lines changed

apiTest/apiTest_README.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# API Test Module
2+
3+
This module contains api tests that run against a Docker containerized version of the application.
4+
The tests make HTTP calls to verify the API endpoints are working correctly.
5+
6+
## Overview
7+
8+
The `apiTest` module is a standalone Gradle project that:
9+
- Runs api tests against the application running in Docker containers
10+
- Automatically manages Docker containers (starts before tests, stops after)
11+
- Generates HTML and XML test reports
12+
13+
## Prerequisites
14+
15+
Before running the tests, ensure you have the following installed and configured:
16+
17+
### Required Software
18+
19+
1. **Java 21** (or higher)
20+
- Verify installation: `java -version`
21+
- Should show version 21 or higher
22+
23+
2. **Docker Desktop** (or Docker Engine)
24+
- Verify installation: `docker --version`
25+
- Docker must be running (check with `docker ps`)
26+
- Docker Compose V2 must be available: `docker compose version`
27+
28+
3. **Gradle** (or use the Gradle wrapper)
29+
- The project includes `gradlew` wrapper, so Gradle installation is optional
30+
- Verify wrapper: `./gradlew --version`
31+
32+
### System Requirements
33+
34+
- At least 4GB of free RAM (Docker containers need memory)
35+
- Ports available: `8082` (application), `5432` (PostgreSQL), `9999` (WireMock)
36+
- Sufficient disk space for Docker images
37+
38+
## Running Tests
39+
40+
### From the Root Directory
41+
42+
```bash
43+
# Navigate to the apiTest directory
44+
cd apiTest
45+
46+
# Run all tests
47+
../gradlew test
48+
49+
# Run tests with more verbose output
50+
../gradlew test --info
51+
52+
# Run tests with debug output
53+
../gradlew test --debug
54+
```
55+
56+
### From the apiTest Directory
57+
58+
```bash
59+
# If you're already in the apiTest directory
60+
../gradlew test
61+
```
62+
63+
### What Happens When You Run Tests
64+
65+
1. **Builds the root project's bootJar** - The application JAR is built first
66+
2. **Builds Docker images** - Creates the application Docker image
67+
3. **Starts Docker containers**:
68+
- PostgreSQL database (port 5432)
69+
- Application server (port 8082)
70+
- WireMock server (port 9999)
71+
4. **Runs tests** - Executes all test classes
72+
5. **Stops and removes containers** - Cleanup after tests complete
73+
74+
### Running Specific Tests
75+
76+
```bash
77+
# Run a specific test class
78+
../gradlew test --tests "RootApiTest"
79+
80+
# Run a specific test method
81+
../gradlew test --tests "RootApiTest.root_endpoint_should_be_ok"
82+
```
83+
84+
## Test Reports
85+
86+
After running tests, you can view the results in several formats:
87+
88+
### HTML Test Report (Recommended)
89+
90+
**Location:** `apiTest/build/reports/tests/test/index.html`
91+
92+
The HTML report includes:
93+
- Test summary (total, passed, failed, skipped)
94+
- Individual test results with execution times
95+
- Stack traces for failed tests
96+
- Package and class-level summaries
97+
98+
### JUnit XML Reports
99+
100+
**Location:** `apiTest/build/test-results/test/`
101+
102+
These XML reports are useful for CI/CD integration.
103+
104+
## Troubleshooting
105+
106+
### Issue: "Could not start Gradle Test Executor 1: Failed to load JUnit Platform"
107+
108+
**Solution:** This should be resolved with the current configuration. If you see this error:
109+
1. Clean the build: `../gradlew clean`
110+
2. Rebuild: `../gradlew build`
111+
112+
### Issue: "no main manifest attribute, in /app/apiTest-0.0.999.jar"
113+
114+
**Solution:** This means the Docker build context is wrong. Ensure:
115+
1. The `docker-compose.yml` has `context: ..` (builds from root directory)
116+
2. The root project's `bootJar` is built before Docker build
117+
3. Run: `../gradlew buildRootBootJar` manually if needed
118+
119+
### Issue: Container exits with code 1
120+
121+
**Check application logs:**
122+
```bash
123+
# View app container logs
124+
docker logs apitest-app-1
125+
126+
# Or using docker-compose
127+
docker-compose -f docker-compose.yml logs app
128+
129+
# View all container logs
130+
docker-compose -f docker-compose.yml logs
131+
```
132+
133+
**Common causes:**
134+
- Application configuration errors
135+
- Database connection issues
136+
- Missing environment variables
137+
- Port conflicts
138+
139+
### Issue: Port already in use
140+
141+
**Solution:** Stop any services using the required ports:
142+
```bash
143+
# Check what's using port 8082
144+
lsof -i :8082
145+
146+
# Check what's using port 5432
147+
lsof -i :5432
148+
149+
# Stop conflicting services or change ports in docker-compose.yml
150+
```
151+
152+
### Issue: Cannot connect to database
153+
154+
**Solution:**
155+
- Ensure the database container is healthy: `docker ps` should show "Healthy"
156+
- Check database logs: `docker-compose -f docker-compose.yml logs db`
157+
- Verify connection string in `docker-compose.yml` matches database configuration
158+
159+
### Issue: IntelliJ not recognizing Java code
160+
161+
Change .idea/gradle.xml to add apiTest module
162+
163+
```.idea/gradle.xml
164+
<?xml version="1.0" encoding="UTF-8"?>
165+
<project version="4">
166+
<component name="GradleMigrationSettings" migrationVersion="1" />
167+
<component name="GradleSettings">
168+
<option name="linkedExternalProjectsSettings">
169+
<GradleProjectSettings>
170+
<option name="externalProjectPath" value="$PROJECT_DIR$" />
171+
<option name="gradleJvm" value="#JAVA_HOME" />
172+
<option name="modules">
173+
<set>
174+
<option value="$PROJECT_DIR$" />
175+
</set>
176+
</option>
177+
</GradleProjectSettings>
178+
<GradleProjectSettings>
179+
<option name="externalProjectPath" value="$PROJECT_DIR$/apiTest" />
180+
<option name="gradleJvm" value="#JAVA_HOME" />
181+
<option name="modules">
182+
<set>
183+
<option value="$PROJECT_DIR$/apiTest" />
184+
</set>
185+
</option>
186+
</GradleProjectSettings>
187+
</option>
188+
</component>
189+
</project>
190+
```
191+
192+
**Solution:**
193+
1. **Refresh Gradle Project:**
194+
- Open Gradle tool window (View → Tool Windows → Gradle)
195+
- Click the refresh button (circular arrow icon)
196+
- Or: File → Reload Gradle Project
197+
198+
2. **Mark Directory as Test Source:**
199+
- Right-click on `apiTest/src/test/java`
200+
- Mark Directory as → Test Sources Root
201+
202+
3. **Reimport Project:**
203+
- File → Invalidate Caches... → Invalidate and Restart
204+
205+
4. **Verify Module Recognition:**
206+
- File → Project Structure (⌘; on Mac)
207+
- Check that `apiTest` module appears under Modules
208+
209+
## Manual Container Management
210+
211+
If you need to manually manage containers:
212+
213+
```bash
214+
# Start containers without running tests
215+
docker-compose -f docker-compose.yml up -d
216+
217+
# Stop containers
218+
docker-compose -f docker-compose.yml down
219+
220+
# View container logs
221+
docker-compose -f docker-compose.yml logs -f app
222+
223+
# Check container status
224+
docker-compose -f docker-compose.yml ps
225+
226+
# Rebuild containers
227+
docker-compose -f docker-compose.yml build --no-cache
228+
```
229+
230+
## Test Configuration
231+
232+
### Environment Variables
233+
234+
Tests use the following default configuration:
235+
- Application base URL: `http://localhost:8082` (can be overridden with `app.baseUrl` system property)
236+
- Database: PostgreSQL on port 5432
237+
- WireMock: Port 9999
238+
239+
### Customizing Test Execution
240+
241+
You can override the application URL:
242+
```bash
243+
../gradlew test -Dapp.baseUrl=http://localhost:8080
244+
```
245+

apiTest/build.gradle

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// TODO need to delete duplicate code
2+
plugins {
3+
id 'java'
4+
id 'com.avast.gradle.docker-compose' version '0.17.20'
5+
id 'io.spring.dependency-management' version '1.1.7'
6+
}
7+
8+
group = 'uk.gov.hmcts.cp'
9+
version = System.getProperty('ARTEFACT_VERSION') ?: '0.0.999'
10+
11+
// Disable main source set since this module only has tests
12+
sourceSets {
13+
main {
14+
java.srcDirs = []
15+
resources.srcDirs = []
16+
}
17+
}
18+
19+
// Disable unnecessary tasks for test-only module
20+
tasks.named('jar') {
21+
enabled = false
22+
}
23+
24+
tasks.named('compileJava') {
25+
enabled = false
26+
}
27+
28+
tasks.named('processResources') {
29+
enabled = false
30+
}
31+
32+
dependencyManagement {
33+
imports {
34+
mavenBom "org.springframework.boot:spring-boot-dependencies:4.0.1"
35+
}
36+
}
37+
38+
tasks.named('test') {
39+
description = "Runs api tests against docker-compose stack"
40+
group = "Verification"
41+
useJUnitPlatform()
42+
dependsOn tasks.composeUp
43+
finalizedBy tasks.composeDown
44+
45+
testLogging {
46+
events "passed", "skipped", "failed"
47+
exceptionFormat = 'full'
48+
showStandardStreams = true
49+
}
50+
51+
reports {
52+
junitXml.required.set(true)
53+
html.required.set(true)
54+
}
55+
}
56+
57+
tasks.named('build') {
58+
dependsOn tasks.named('test')
59+
}
60+
61+
dockerCompose {
62+
useComposeFiles = ['docker-compose.yml']
63+
startedServices = ['db', 'app']
64+
65+
buildBeforeUp = true
66+
waitForTcpPorts = true
67+
upAdditionalArgs = ['--wait', '--wait-timeout', '120']
68+
69+
captureContainersOutput = true
70+
removeOrphans = true
71+
stopContainers = true
72+
removeContainers = true
73+
74+
useDockerComposeV2 = true
75+
dockerExecutable = 'docker'
76+
}
77+
78+
// Build the root project's bootJar before building Docker image
79+
tasks.register('buildRootBootJar', Exec) {
80+
description = "Builds the root project's bootJar"
81+
workingDir = projectDir.parent
82+
executable = "${projectDir.parent}/gradlew"
83+
args = ['bootJar']
84+
}
85+
86+
tasks.named('composeBuild') {
87+
dependsOn tasks.named('buildRootBootJar')
88+
}
89+
90+
dependencies {
91+
testImplementation "org.springframework:spring-web"
92+
testImplementation "org.springframework.boot:spring-boot-starter-test"
93+
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
94+
}
95+
96+
repositories {
97+
mavenLocal()
98+
mavenCentral()
99+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010

1111
app:
1212
build:
13+
context: ..
1314
dockerfile: Dockerfile
1415
environment:
1516
SERVER_PORT: 8082

0 commit comments

Comments
 (0)