setup coverate report generation
This commit is contained in:
@ -20,7 +20,8 @@
|
||||
"Bash(docker-compose ps:*)",
|
||||
"Bash(tree:*)",
|
||||
"Bash(docker-compose:*)",
|
||||
"Bash(chmod:*)"
|
||||
"Bash(chmod:*)",
|
||||
"Bash(ls:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
400
DOCKER_COMPOSE_GUIDE.md
Normal file
400
DOCKER_COMPOSE_GUIDE.md
Normal file
@ -0,0 +1,400 @@
|
||||
# Docker Compose Patterns - Quick Guide
|
||||
|
||||
This guide provides a focused reference for all Docker Compose patterns used in this project.
|
||||
|
||||
## Overview
|
||||
|
||||
This project uses **three Docker Compose files** for different purposes:
|
||||
|
||||
```
|
||||
docker-compose.yml ← Start application server
|
||||
docker-compose.test.yml ← Run unit tests
|
||||
docker-compose.coverage.yml ← Generate coverage reports
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pattern 1: Application Server
|
||||
|
||||
**File**: `docker-compose.yml`
|
||||
**Purpose**: Deploy JAX-WS application to Tomcat
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
# Start server
|
||||
docker-compose up -d
|
||||
|
||||
# Start with build
|
||||
docker-compose up -d --build
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Stop server
|
||||
docker-compose down
|
||||
|
||||
# Restart
|
||||
docker-compose restart
|
||||
```
|
||||
|
||||
### What Happens
|
||||
|
||||
1. Builds Docker image (3 stages):
|
||||
- Stage 1: Run unit tests
|
||||
- Stage 2: Build WAR file
|
||||
- Stage 3: Deploy to Tomcat
|
||||
2. Starts Tomcat on port 8080
|
||||
3. Creates/persists SQLite database
|
||||
|
||||
### Access
|
||||
|
||||
- Hello World: http://localhost:8080/jaxws-hello-world/hello?wsdl
|
||||
- Loan Service: http://localhost:8080/jaxws-hello-world/loan?wsdl
|
||||
- Tomcat Manager: http://localhost:8080/manager (admin/admin123)
|
||||
|
||||
---
|
||||
|
||||
## Pattern 2: Run Unit Tests
|
||||
|
||||
**File**: `docker-compose.test.yml`
|
||||
**Purpose**: Execute JUnit tests
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
|
||||
# View test output
|
||||
docker-compose -f docker-compose.test.yml logs
|
||||
|
||||
# Clean up
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
|
||||
# One-liner (run and clean)
|
||||
docker-compose -f docker-compose.test.yml up --build && docker-compose -f docker-compose.test.yml down
|
||||
```
|
||||
|
||||
### Convenience Scripts
|
||||
|
||||
**Windows:**
|
||||
```cmd
|
||||
run-tests.bat
|
||||
```
|
||||
|
||||
**Linux/Mac:**
|
||||
```bash
|
||||
./run-tests.sh
|
||||
```
|
||||
|
||||
### What Happens
|
||||
|
||||
1. Builds test environment
|
||||
2. Runs `mvn test`
|
||||
3. Executes all *Test.java files
|
||||
4. Exports results to `./target/surefire-reports/`
|
||||
5. Generates JaCoCo coverage data
|
||||
|
||||
### Output
|
||||
|
||||
**Console:**
|
||||
```
|
||||
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0
|
||||
BUILD SUCCESS
|
||||
```
|
||||
|
||||
**Files:**
|
||||
- `./target/surefire-reports/` - Test reports (text & XML)
|
||||
- `./target/jacoco.exec` - Coverage data
|
||||
|
||||
---
|
||||
|
||||
## Pattern 3: Generate Code Coverage
|
||||
|
||||
**File**: `docker-compose.coverage.yml`
|
||||
**Purpose**: Generate JaCoCo coverage reports
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
# Generate coverage
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
|
||||
# View logs
|
||||
docker-compose -f docker-compose.coverage.yml logs
|
||||
|
||||
# Clean up
|
||||
docker-compose -f docker-compose.coverage.yml down
|
||||
|
||||
# One-liner (generate and clean)
|
||||
docker-compose -f docker-compose.coverage.yml up --build && docker-compose -f docker-compose.coverage.yml down
|
||||
```
|
||||
|
||||
### Convenience Scripts
|
||||
|
||||
**Windows:**
|
||||
```cmd
|
||||
run-coverage.bat
|
||||
```
|
||||
|
||||
**Linux/Mac:**
|
||||
```bash
|
||||
./run-coverage.sh
|
||||
```
|
||||
|
||||
### What Happens
|
||||
|
||||
1. Builds test environment
|
||||
2. Runs `mvn test` with JaCoCo agent
|
||||
3. Generates coverage reports (HTML, XML, CSV)
|
||||
4. Exports to `./target/site/jacoco/`
|
||||
|
||||
### Output
|
||||
|
||||
**Console:**
|
||||
```
|
||||
=================================================================================
|
||||
Coverage report generated successfully!
|
||||
=================================================================================
|
||||
HTML Report: ./target/site/jacoco/index.html
|
||||
XML Report: ./target/site/jacoco/jacoco.xml
|
||||
CSV Report: ./target/site/jacoco/jacoco.csv
|
||||
=================================================================================
|
||||
```
|
||||
|
||||
**Files:**
|
||||
- `./target/site/jacoco/index.html` ← **Open this in browser**
|
||||
- `./target/site/jacoco/jacoco.xml` (for CI/CD)
|
||||
- `./target/site/jacoco/jacoco.csv` (for spreadsheets)
|
||||
|
||||
---
|
||||
|
||||
## Complete Workflow
|
||||
|
||||
### Typical Development Cycle
|
||||
|
||||
```bash
|
||||
# 1. Write code
|
||||
vim src/main/java/com/example/service/MyService.java
|
||||
|
||||
# 2. Run tests
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
|
||||
# 3. Check coverage
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
docker-compose -f docker-compose.coverage.yml down
|
||||
|
||||
# 4. View coverage report
|
||||
# Open target/site/jacoco/index.html in browser
|
||||
|
||||
# 5. Deploy if tests pass
|
||||
docker-compose up -d --build
|
||||
|
||||
# 6. Verify
|
||||
curl http://localhost:8080/jaxws-hello-world/hello?wsdl
|
||||
|
||||
# 7. View logs
|
||||
docker-compose logs -f
|
||||
|
||||
# 8. Stop when done
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### Using Convenience Scripts (Faster)
|
||||
|
||||
**Windows:**
|
||||
```cmd
|
||||
REM 1. Write code
|
||||
notepad src\main\java\com\example\service\MyService.java
|
||||
|
||||
REM 2. Run tests
|
||||
run-tests.bat
|
||||
|
||||
REM 3. Generate coverage
|
||||
run-coverage.bat
|
||||
|
||||
REM 4. View coverage
|
||||
start target\site\jacoco\index.html
|
||||
|
||||
REM 5. Deploy
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
**Linux/Mac:**
|
||||
```bash
|
||||
# 1. Write code
|
||||
vim src/main/java/com/example/service/MyService.java
|
||||
|
||||
# 2. Run tests
|
||||
./run-tests.sh
|
||||
|
||||
# 3. Generate coverage
|
||||
./run-coverage.sh
|
||||
|
||||
# 4. View coverage (Linux)
|
||||
xdg-open target/site/jacoco/index.html
|
||||
|
||||
# 5. Deploy
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Task | Docker Compose Command | Script Alternative |
|
||||
|------|----------------------|-------------------|
|
||||
| **Run Tests** | `docker-compose -f docker-compose.test.yml up --build` | `run-tests.bat` / `./run-tests.sh` |
|
||||
| **Generate Coverage** | `docker-compose -f docker-compose.coverage.yml up --build` | `run-coverage.bat` / `./run-coverage.sh` |
|
||||
| **Start Server** | `docker-compose up -d` | N/A |
|
||||
| **Stop Server** | `docker-compose down` | N/A |
|
||||
| **View Logs** | `docker-compose logs -f` | N/A |
|
||||
| **Rebuild Server** | `docker-compose up -d --build` | N/A |
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Pattern: Test-Driven Development (TDD)
|
||||
|
||||
```bash
|
||||
# Watch-test loop (manual)
|
||||
while true; do
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
read -p "Press Enter to run again, Ctrl+C to exit..."
|
||||
done
|
||||
```
|
||||
|
||||
### Pattern: CI/CD Pipeline
|
||||
|
||||
```yaml
|
||||
# GitHub Actions example
|
||||
- name: Run Tests
|
||||
run: docker-compose -f docker-compose.test.yml up --build
|
||||
|
||||
- name: Generate Coverage
|
||||
run: docker-compose -f docker-compose.coverage.yml up --build
|
||||
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
files: ./target/site/jacoco/jacoco.xml
|
||||
|
||||
- name: Deploy (if tests pass)
|
||||
run: docker-compose up -d --build
|
||||
```
|
||||
|
||||
### Pattern: Pre-commit Hook
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# .git/hooks/pre-commit
|
||||
|
||||
echo "Running tests before commit..."
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Tests failed! Commit aborted."
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
echo "Tests passed! Proceeding with commit."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Tests Failing
|
||||
|
||||
```bash
|
||||
# View detailed test output
|
||||
docker-compose -f docker-compose.test.yml up
|
||||
|
||||
# Check test container logs
|
||||
docker-compose -f docker-compose.test.yml logs
|
||||
|
||||
# Access test container
|
||||
docker-compose -f docker-compose.test.yml run --rm test bash
|
||||
```
|
||||
|
||||
### Coverage Report Empty
|
||||
|
||||
```bash
|
||||
# Ensure tests are running
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
|
||||
# Check if target directory is mounted
|
||||
docker-compose -f docker-compose.coverage.yml config | grep target
|
||||
|
||||
# Manually verify mount
|
||||
ls -la target/site/jacoco/
|
||||
```
|
||||
|
||||
### Server Won't Start
|
||||
|
||||
```bash
|
||||
# Check if port 8080 is in use
|
||||
netstat -ano | findstr :8080 # Windows
|
||||
lsof -i :8080 # Linux/Mac
|
||||
|
||||
# View server logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Rebuild from scratch
|
||||
docker-compose down
|
||||
docker-compose build --no-cache
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Run Specific Test
|
||||
|
||||
```bash
|
||||
# Override command to run specific test
|
||||
docker-compose -f docker-compose.test.yml run --rm test \
|
||||
mvn test -Dtest=HelloWorldServiceImplTest
|
||||
```
|
||||
|
||||
### Custom Memory Settings
|
||||
|
||||
```bash
|
||||
# Override environment variable
|
||||
docker-compose -f docker-compose.test.yml run --rm \
|
||||
-e MAVEN_OPTS="-Xmx1024m" test mvn test
|
||||
```
|
||||
|
||||
### Debug Mode
|
||||
|
||||
```bash
|
||||
# Run tests with Maven debug output
|
||||
docker-compose -f docker-compose.test.yml run --rm test \
|
||||
mvn test -X
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
- **3 Docker Compose files** = 3 different purposes
|
||||
- **Test first** before deploying
|
||||
- **Check coverage** to ensure quality
|
||||
- **Use scripts** for convenience
|
||||
- **All outputs** go to `./target/`
|
||||
|
||||
**Quick commands to remember:**
|
||||
```bash
|
||||
run-tests.bat # or ./run-tests.sh
|
||||
run-coverage.bat # or ./run-coverage.sh
|
||||
docker-compose up -d # start server
|
||||
```
|
||||
|
||||
That's it! You now have everything you need to use Docker Compose patterns in this project.
|
||||
30
Dockerfile.coverage
Normal file
30
Dockerfile.coverage
Normal file
@ -0,0 +1,30 @@
|
||||
# Multi-stage build for code coverage
|
||||
FROM maven:3.8.6-openjdk-8 AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy pom.xml and src
|
||||
COPY pom.xml .
|
||||
COPY src ./src
|
||||
|
||||
# Build with tests
|
||||
RUN mvn clean package -DskipTests=false
|
||||
|
||||
# Create a separate stage for running tests with coverage
|
||||
FROM maven:3.8.6-openjdk-8
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the built project
|
||||
COPY --from=builder /app/target/*.war /app/app.war
|
||||
|
||||
# Install dependencies for coverage reporting
|
||||
RUN apt-get update && apt-get install -y wget unzip
|
||||
|
||||
# Create a script to run tests with coverage
|
||||
COPY scripts/ .
|
||||
|
||||
# Run tests with coverage
|
||||
CMD ["mvn", "test"]
|
||||
16
Dockerfile.coverage.simple
Normal file
16
Dockerfile.coverage.simple
Normal file
@ -0,0 +1,16 @@
|
||||
FROM maven:3.8.6-openjdk-8
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy pom.xml and source files
|
||||
COPY pom.xml .
|
||||
COPY src ./src
|
||||
|
||||
# Run tests with coverage
|
||||
RUN mvn clean test
|
||||
|
||||
# Generate coverage report
|
||||
RUN mvn jacoco:report
|
||||
|
||||
# Show the coverage report location
|
||||
RUN echo "Coverage report is available in target/site/jacoco/"
|
||||
581
README.md
581
README.md
@ -2,6 +2,25 @@
|
||||
|
||||
A complete JAX-WS SOAP web services application for loan processing, featuring customer registration, credit score evaluation, and loan approval workflows with SQLite database persistence.
|
||||
|
||||
## Quick Reference Card
|
||||
|
||||
### 🚀 Three Ways to Use This Project
|
||||
|
||||
| Task | Command | Result |
|
||||
|------|---------|--------|
|
||||
| **Run Tests** | `docker-compose -f docker-compose.test.yml up --build` | Tests run, results in `./target/surefire-reports/` |
|
||||
| **Generate Coverage** | `docker-compose -f docker-compose.coverage.yml up --build` | Coverage report in `./target/site/jacoco/index.html` |
|
||||
| **Start Server** | `docker-compose up -d` | Server running at http://localhost:8080 |
|
||||
|
||||
### 📝 Convenience Scripts
|
||||
|
||||
| Platform | Run Tests | Generate Coverage |
|
||||
|----------|-----------|-------------------|
|
||||
| **Windows** | `run-tests.bat` | `run-coverage.bat` |
|
||||
| **Linux/Mac** | `./run-tests.sh` | `./run-coverage.sh` |
|
||||
|
||||
---
|
||||
|
||||
## Project Details
|
||||
|
||||
### Overview
|
||||
@ -23,7 +42,8 @@ This project demonstrates a production-ready JAX-WS web service implementation u
|
||||
- **Application Server**: Apache Tomcat 9+
|
||||
- **Database**: SQLite 3.43.0
|
||||
- **Containerization**: Docker & Docker Compose
|
||||
- **Testing**: Python 3 with zeep library
|
||||
- **Unit Testing**: JUnit 5 (Jupiter), Mockito, JaCoCo
|
||||
- **Integration Testing**: Python 3 with requests library
|
||||
|
||||
### Key Features
|
||||
|
||||
@ -32,7 +52,8 @@ This project demonstrates a production-ready JAX-WS web service implementation u
|
||||
- **Credit Risk Assessment**: Tiered approval logic based on credit scores
|
||||
- **Blacklist Management**: Customer screening and rejection system
|
||||
- **Docker Support**: Fully containerized with one-command deployment
|
||||
- **Comprehensive Testing**: Python test clients for all services
|
||||
- **Unit Testing**: JUnit 5 tests with JaCoCo code coverage
|
||||
- **Integration Testing**: Python test clients for all services
|
||||
- **Production-Ready**: Singleton patterns, prepared statements, error handling
|
||||
|
||||
---
|
||||
@ -46,6 +67,75 @@ This project demonstrates a production-ready JAX-WS web service implementation u
|
||||
|
||||
### Quick Start
|
||||
|
||||
#### Three Docker Compose Configurations
|
||||
|
||||
This project provides three Docker Compose files for different purposes:
|
||||
|
||||
| Purpose | File | Command | Output Location |
|
||||
|---------|------|---------|----------------|
|
||||
| **🚀 Start Server** | `docker-compose.yml` | `docker-compose up -d` | http://localhost:8080 |
|
||||
| **✅ Run Tests** | `docker-compose.test.yml` | `docker-compose -f docker-compose.test.yml up --build` | `./target/surefire-reports/` |
|
||||
| **📊 Coverage Report** | `docker-compose.coverage.yml` | `docker-compose -f docker-compose.coverage.yml up --build` | `./target/site/jacoco/index.html` |
|
||||
|
||||
**Visual Workflow:**
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Development Workflow │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
1. Write Code
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Run Unit Tests │ ──► docker-compose -f docker-compose.test.yml up --build
|
||||
│ (docker-compose.test) │
|
||||
└──────────┬──────────────┘
|
||||
│ Tests Pass ✓
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Generate Coverage │ ──► docker-compose -f docker-compose.coverage.yml up --build
|
||||
│ (docker-compose.coverage│
|
||||
└──────────┬──────────────┘ Open: ./target/site/jacoco/index.html
|
||||
│ Coverage OK ✓
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Deploy Application │ ──► docker-compose up -d
|
||||
│ (docker-compose.yml) │
|
||||
└──────────┬──────────────┘ Access: http://localhost:8080
|
||||
│
|
||||
▼
|
||||
Production Ready!
|
||||
```
|
||||
|
||||
**Quick Commands:**
|
||||
```bash
|
||||
# Run all tests
|
||||
docker-compose -f docker-compose.test.yml up --build && docker-compose -f docker-compose.test.yml down
|
||||
|
||||
# Generate coverage report
|
||||
docker-compose -f docker-compose.coverage.yml up --build && docker-compose -f docker-compose.coverage.yml down
|
||||
|
||||
# Start application server
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
**Or use convenience scripts:**
|
||||
```cmd
|
||||
REM Windows
|
||||
run-tests.bat
|
||||
run-coverage.bat
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
```bash
|
||||
# Linux/Mac
|
||||
./run-tests.sh
|
||||
./run-coverage.sh
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 1. Start the Application
|
||||
|
||||
```bash
|
||||
@ -88,6 +178,188 @@ docker-compose logs jaxws-service
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Docker Compose Patterns
|
||||
|
||||
This project includes three Docker Compose configurations for different purposes:
|
||||
|
||||
#### Pattern 1: Start Application Server
|
||||
|
||||
**File**: `docker-compose.yml`
|
||||
**Purpose**: Deploy and run the JAX-WS application on Tomcat
|
||||
|
||||
```bash
|
||||
# Start the server in detached mode
|
||||
docker-compose up -d
|
||||
|
||||
# Start with build (after code changes)
|
||||
docker-compose up -d --build
|
||||
|
||||
# View logs in real-time
|
||||
docker-compose logs -f
|
||||
|
||||
# Stop the server
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
1. Runs unit tests (Stage 1: tester)
|
||||
2. Builds WAR file (Stage 2: builder)
|
||||
3. Deploys to Tomcat (Stage 3)
|
||||
4. Exposes port 8080
|
||||
5. Creates/persists SQLite database
|
||||
|
||||
**Access points:**
|
||||
- Hello World Service: http://localhost:8080/jaxws-hello-world/hello?wsdl
|
||||
- Loan Service: http://localhost:8080/jaxws-hello-world/loan?wsdl
|
||||
- Tomcat Manager: http://localhost:8080/manager (admin/admin123)
|
||||
|
||||
---
|
||||
|
||||
#### Pattern 2: Run Unit Tests
|
||||
|
||||
**File**: `docker-compose.test.yml`
|
||||
**Purpose**: Execute JUnit tests and export results to `./target`
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
|
||||
# Run tests in background
|
||||
docker-compose -f docker-compose.test.yml up -d
|
||||
|
||||
# View test output
|
||||
docker-compose -f docker-compose.test.yml logs
|
||||
|
||||
# Clean up
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
1. Builds test environment (tester stage)
|
||||
2. Runs `mvn test`
|
||||
3. Executes all *Test.java files
|
||||
4. Exports test reports to `./target/surefire-reports/`
|
||||
5. Exports coverage data to `./target/jacoco.exec`
|
||||
|
||||
**Test results location:**
|
||||
- Console output: Test summary with pass/fail counts
|
||||
- Reports: `./target/surefire-reports/` (text and XML)
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0
|
||||
BUILD SUCCESS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Pattern 3: Generate Code Coverage Report
|
||||
|
||||
**File**: `docker-compose.coverage.yml`
|
||||
**Purpose**: Run tests and generate JaCoCo coverage reports in `./target/site/jacoco/`
|
||||
|
||||
```bash
|
||||
# Generate coverage reports
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
|
||||
# Generate coverage in background
|
||||
docker-compose -f docker-compose.coverage.yml up -d
|
||||
|
||||
# View coverage generation logs
|
||||
docker-compose -f docker-compose.coverage.yml logs
|
||||
|
||||
# Clean up
|
||||
docker-compose -f docker-compose.coverage.yml down
|
||||
```
|
||||
|
||||
**What happens:**
|
||||
1. Builds test environment
|
||||
2. Runs `mvn test` with JaCoCo agent
|
||||
3. Generates coverage reports in multiple formats
|
||||
4. Exports to `./target/site/jacoco/`
|
||||
|
||||
**Coverage reports location:**
|
||||
- **HTML Report**: `./target/site/jacoco/index.html` ← **Open this in browser**
|
||||
- **XML Report**: `./target/site/jacoco/jacoco.xml` (for CI/CD)
|
||||
- **CSV Report**: `./target/site/jacoco/jacoco.csv` (for spreadsheets)
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
=================================================================================
|
||||
Coverage report generated successfully!
|
||||
=================================================================================
|
||||
HTML Report: ./target/site/jacoco/index.html
|
||||
XML Report: ./target/site/jacoco/jacoco.xml
|
||||
CSV Report: ./target/site/jacoco/jacoco.csv
|
||||
=================================================================================
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Complete Workflow Example
|
||||
|
||||
Here's a typical development workflow using all three patterns:
|
||||
|
||||
```bash
|
||||
# 1. Run tests to ensure code works
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
|
||||
# 2. Generate coverage report to check test quality
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
docker-compose -f docker-compose.coverage.yml down
|
||||
|
||||
# 3. View coverage report
|
||||
# Open target/site/jacoco/index.html in browser
|
||||
|
||||
# 4. Deploy application if tests pass
|
||||
docker-compose up -d --build
|
||||
|
||||
# 5. Verify deployment
|
||||
curl http://localhost:8080/jaxws-hello-world/hello?wsdl
|
||||
|
||||
# 6. View application logs
|
||||
docker-compose logs -f
|
||||
|
||||
# 7. Stop when done
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Quick Reference Scripts
|
||||
|
||||
For convenience, use the provided scripts instead of typing full commands:
|
||||
|
||||
| Task | Windows | Linux/Mac | Docker Compose Equivalent |
|
||||
|------|---------|-----------|--------------------------|
|
||||
| Run Tests | `run-tests.bat` | `./run-tests.sh` | `docker-compose -f docker-compose.test.yml up --build` |
|
||||
| Generate Coverage | `run-coverage.bat` | `./run-coverage.sh` | `docker-compose -f docker-compose.coverage.yml up --build` |
|
||||
| Start Server | N/A | N/A | `docker-compose up -d` |
|
||||
|
||||
**Example:**
|
||||
```cmd
|
||||
REM Windows
|
||||
run-tests.bat
|
||||
run-coverage.bat
|
||||
|
||||
REM Then start server
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
```bash
|
||||
# Linux/Mac
|
||||
./run-tests.sh
|
||||
./run-coverage.sh
|
||||
|
||||
# Then start server
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Rebuild After Code Changes
|
||||
|
||||
When you modify the source code, rebuild and restart:
|
||||
@ -103,15 +375,33 @@ docker-compose up -d
|
||||
|
||||
### Docker Commands Reference
|
||||
|
||||
#### Application Server Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `docker-compose up -d` | Start services in detached mode |
|
||||
| `docker-compose up -d --build` | Rebuild and start services |
|
||||
| `docker-compose down` | Stop and remove containers |
|
||||
| `docker-compose logs -f` | Follow logs output |
|
||||
| `docker-compose up -d` | Start application server in detached mode |
|
||||
| `docker-compose up -d --build` | Rebuild and start application server |
|
||||
| `docker-compose down` | Stop and remove application containers |
|
||||
| `docker-compose logs -f` | Follow application logs in real-time |
|
||||
| `docker-compose ps` | List running containers |
|
||||
| `docker-compose restart` | Restart services |
|
||||
| `docker-compose exec jaxws-service bash` | Access container shell |
|
||||
| `docker-compose restart` | Restart application services |
|
||||
| `docker-compose exec jaxws-service bash` | Access application container shell |
|
||||
|
||||
#### Test Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `docker-compose -f docker-compose.test.yml up --build` | Run unit tests |
|
||||
| `docker-compose -f docker-compose.test.yml logs` | View test output |
|
||||
| `docker-compose -f docker-compose.test.yml down` | Clean up test containers |
|
||||
|
||||
#### Coverage Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `docker-compose -f docker-compose.coverage.yml up --build` | Generate coverage reports |
|
||||
| `docker-compose -f docker-compose.coverage.yml logs` | View coverage generation logs |
|
||||
| `docker-compose -f docker-compose.coverage.yml down` | Clean up coverage containers |
|
||||
|
||||
### Accessing the Database
|
||||
|
||||
@ -145,38 +435,45 @@ The `docker-compose.yml` includes these configurations:
|
||||
jaxws-hello-world/
|
||||
│
|
||||
├── src/
|
||||
│ └── main/
|
||||
│ ├── java/
|
||||
│ │ └── com/
|
||||
│ │ └── example/
|
||||
│ │ ├── listener/
|
||||
│ │ │ └── DatabaseInitializationListener.java # Application startup initialization
|
||||
│ │ │
|
||||
│ │ ├── model/ # Data models (POJOs)
|
||||
│ │ │ ├── CustomerRegistrationRequest.java # Customer registration request
|
||||
│ │ │ ├── LoanRequest.java # Loan application request
|
||||
│ │ │ └── LoanResponse.java # Loan application response
|
||||
│ │ │
|
||||
│ │ ├── repository/ # Data access layer
|
||||
│ │ │ ├── CustomerRepository.java # Customer DAO interface
|
||||
│ │ │ ├── LoanHistoryRepository.java # Loan history DAO interface
|
||||
│ │ │ └── impl/
|
||||
│ │ │ ├── CustomerRepositoryImpl.java # Customer DAO implementation
|
||||
│ │ │ └── LoanHistoryRepositoryImpl.java # Loan history DAO implementation
|
||||
│ │ │
|
||||
│ │ ├── service/ # Web service layer
|
||||
│ │ │ ├── HelloWorldService.java # Hello World interface
|
||||
│ │ │ ├── HelloWorldServiceImpl.java # Hello World implementation
|
||||
│ │ │ ├── LoanApprovalService.java # Loan service (interface + impl)
|
||||
│ │ │ └── CreditScoreService.java # Credit score evaluation
|
||||
│ │ │
|
||||
│ │ └── util/
|
||||
│ │ └── DatabaseManager.java # Singleton DB connection manager
|
||||
│ │
|
||||
│ └── webapp/
|
||||
│ └── WEB-INF/
|
||||
│ ├── web.xml # Web application descriptor
|
||||
│ └── sun-jaxws.xml # JAX-WS endpoint configuration
|
||||
│ ├── main/
|
||||
│ │ ├── java/
|
||||
│ │ │ └── com/
|
||||
│ │ │ └── example/
|
||||
│ │ │ ├── listener/
|
||||
│ │ │ │ └── DatabaseInitializationListener.java # Application startup initialization
|
||||
│ │ │ │
|
||||
│ │ │ ├── model/ # Data models (POJOs)
|
||||
│ │ │ │ ├── CustomerRegistrationRequest.java # Customer registration request
|
||||
│ │ │ │ ├── LoanRequest.java # Loan application request
|
||||
│ │ │ │ └── LoanResponse.java # Loan application response
|
||||
│ │ │ │
|
||||
│ │ │ ├── repository/ # Data access layer
|
||||
│ │ │ │ ├── CustomerRepository.java # Customer DAO interface
|
||||
│ │ │ │ ├── LoanHistoryRepository.java # Loan history DAO interface
|
||||
│ │ │ │ └── impl/
|
||||
│ │ │ │ ├── CustomerRepositoryImpl.java # Customer DAO implementation
|
||||
│ │ │ │ └── LoanHistoryRepositoryImpl.java # Loan history DAO implementation
|
||||
│ │ │ │
|
||||
│ │ │ ├── service/ # Web service layer
|
||||
│ │ │ │ ├── HelloWorldService.java # Hello World interface
|
||||
│ │ │ │ ├── HelloWorldServiceImpl.java # Hello World implementation
|
||||
│ │ │ │ ├── LoanApprovalService.java # Loan service (interface + impl)
|
||||
│ │ │ │ └── CreditScoreService.java # Credit score evaluation
|
||||
│ │ │ │
|
||||
│ │ │ └── util/
|
||||
│ │ │ └── DatabaseManager.java # Singleton DB connection manager
|
||||
│ │ │
|
||||
│ │ └── webapp/
|
||||
│ │ └── WEB-INF/
|
||||
│ │ ├── web.xml # Web application descriptor
|
||||
│ │ └── sun-jaxws.xml # JAX-WS endpoint configuration
|
||||
│ │
|
||||
│ └── test/
|
||||
│ └── java/
|
||||
│ └── com/
|
||||
│ └── example/
|
||||
│ └── service/
|
||||
│ └── HelloWorldServiceImplTest.java # Unit tests for Hello World service
|
||||
│
|
||||
├── scripts/ # Python test clients
|
||||
│ ├── test_all_services.py # Comprehensive test suite
|
||||
@ -186,12 +483,25 @@ jaxws-hello-world/
|
||||
│ └── README.md # Test scripts documentation
|
||||
│
|
||||
├── logs/ # Tomcat logs (Docker volume)
|
||||
├── target/ # Build output (generated)
|
||||
│ ├── site/jacoco/ # Code coverage reports
|
||||
│ │ ├── index.html # HTML coverage report
|
||||
│ │ ├── jacoco.xml # XML coverage report
|
||||
│ │ └── jacoco.csv # CSV coverage report
|
||||
│ └── surefire-reports/ # Test execution reports
|
||||
│
|
||||
├── pom.xml # Maven project configuration
|
||||
├── docker-compose.yml # Docker Compose orchestration
|
||||
├── docker-compose.test.yml # Docker Compose for unit tests
|
||||
├── docker-compose.coverage.yml # Docker Compose for coverage
|
||||
├── Dockerfile # Multi-stage Docker build
|
||||
├── Dockerfile.coverage.simple # Dockerfile for coverage
|
||||
├── tomcat-users.xml # Tomcat manager users
|
||||
├── loan_app.db # SQLite database (created on first run)
|
||||
├── run-tests.bat # Windows test runner script
|
||||
├── run-tests.sh # Linux/Mac test runner script
|
||||
├── run-coverage.bat # Windows coverage script
|
||||
├── run-coverage.sh # Linux/Mac coverage script
|
||||
├── README.md # This file
|
||||
├── apidoc.md # Complete API documentation
|
||||
├── requirements.md # Project requirements specification
|
||||
@ -777,6 +1087,197 @@ See [scripts/README.md](scripts/README.md)
|
||||
|
||||
---
|
||||
|
||||
## Unit Tests and Code Coverage
|
||||
|
||||
### Overview
|
||||
|
||||
This project includes comprehensive unit testing with JUnit 5 and code coverage analysis with JaCoCo. All test results and coverage reports are automatically exported to the `./target` directory for easy access.
|
||||
|
||||
### Quick Start
|
||||
|
||||
#### Run Unit Tests
|
||||
|
||||
**Windows:**
|
||||
```cmd
|
||||
run-tests.bat
|
||||
```
|
||||
|
||||
**Linux/Mac:**
|
||||
```bash
|
||||
./run-tests.sh
|
||||
```
|
||||
|
||||
**Docker Compose:**
|
||||
```bash
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
```
|
||||
|
||||
#### Generate Code Coverage Reports
|
||||
|
||||
**Windows:**
|
||||
```cmd
|
||||
run-coverage.bat
|
||||
```
|
||||
|
||||
**Linux/Mac:**
|
||||
```bash
|
||||
./run-coverage.sh
|
||||
```
|
||||
|
||||
**Docker Compose:**
|
||||
```bash
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
docker-compose -f docker-compose.coverage.yml down
|
||||
```
|
||||
|
||||
### Coverage Reports
|
||||
|
||||
All coverage reports are generated in `./target/site/jacoco/`:
|
||||
|
||||
- **HTML Report**: `target/site/jacoco/index.html` (open in browser)
|
||||
- **XML Report**: `target/site/jacoco/jacoco.xml` (for CI/CD tools)
|
||||
- **CSV Report**: `target/site/jacoco/jacoco.csv` (for spreadsheets)
|
||||
|
||||
### Test Framework
|
||||
|
||||
The project uses:
|
||||
|
||||
- **JUnit 5 (Jupiter)** - Modern testing framework with annotations
|
||||
- **Mockito** - Mocking framework for complex test scenarios
|
||||
- **JaCoCo** - Code coverage analysis and reporting
|
||||
- **Maven Surefire** - Test execution plugin
|
||||
|
||||
### Current Test Coverage
|
||||
|
||||
| Service | Test Class | Test Cases | Status |
|
||||
|---------|-----------|------------|--------|
|
||||
| Hello World Service | HelloWorldServiceImplTest | 10 | ✅ Passing |
|
||||
|
||||
### Understanding Coverage Reports
|
||||
|
||||
**Coverage Metrics:**
|
||||
- **Line Coverage**: Percentage of executable lines tested
|
||||
- **Branch Coverage**: Percentage of decision points (if/else) tested
|
||||
- **Method Coverage**: Percentage of methods invoked during tests
|
||||
- **Class Coverage**: Percentage of classes with at least one test
|
||||
|
||||
**Coverage Goals:**
|
||||
- Line Coverage: > 80%
|
||||
- Branch Coverage: > 70%
|
||||
- Method Coverage: > 85%
|
||||
|
||||
### Running Tests with Maven (Local)
|
||||
|
||||
If you have Maven installed locally:
|
||||
|
||||
```bash
|
||||
# Run tests only
|
||||
mvn test
|
||||
|
||||
# Run tests with coverage
|
||||
mvn clean test
|
||||
|
||||
# View coverage report
|
||||
# Open target/site/jacoco/index.html in your browser
|
||||
```
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
#### GitHub Actions Example
|
||||
|
||||
```yaml
|
||||
- name: Run tests with coverage
|
||||
run: mvn clean test
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
files: ./target/site/jacoco/jacoco.xml
|
||||
```
|
||||
|
||||
#### Jenkins Example
|
||||
|
||||
```groovy
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh 'mvn clean test'
|
||||
jacoco(
|
||||
execPattern: 'target/jacoco.exec',
|
||||
classPattern: 'target/classes',
|
||||
sourcePattern: 'src/main/java'
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Writing New Tests
|
||||
|
||||
Create test classes in `src/test/java/` following this pattern:
|
||||
|
||||
```java
|
||||
package com.example.service;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@DisplayName("Your Service Tests")
|
||||
class YourServiceTest {
|
||||
|
||||
private YourService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
service = new YourServiceImpl();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should do something")
|
||||
void testSomething() {
|
||||
// Arrange
|
||||
String input = "test";
|
||||
String expected = "result";
|
||||
|
||||
// Act
|
||||
String result = service.doSomething(input);
|
||||
|
||||
// Assert
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Tests Not Running
|
||||
|
||||
```bash
|
||||
# Ensure test files end with Test.java
|
||||
# Verify directory: src/test/java/
|
||||
# Check pom.xml includes maven-surefire-plugin
|
||||
```
|
||||
|
||||
#### Coverage Reports Not Generated
|
||||
|
||||
```bash
|
||||
# Ensure JaCoCo plugin is in pom.xml
|
||||
mvn clean test
|
||||
|
||||
# Or use Docker
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
```
|
||||
|
||||
#### Permission Issues (Linux/Mac)
|
||||
|
||||
```bash
|
||||
chmod +x run-tests.sh
|
||||
chmod +x run-coverage.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Service Endpoints
|
||||
|
||||
Once running, the following endpoints are available:
|
||||
|
||||
346
TEST_GUIDE.md
346
TEST_GUIDE.md
@ -1,346 +0,0 @@
|
||||
# Unit Testing Guide
|
||||
|
||||
This guide explains how to run and write unit tests for the JAX-WS Hello World Service project.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Run Tests with Docker (Recommended)
|
||||
|
||||
#### Windows
|
||||
```cmd
|
||||
run-tests.bat
|
||||
```
|
||||
|
||||
#### Linux/Mac
|
||||
```bash
|
||||
./run-tests.sh
|
||||
```
|
||||
|
||||
### Run Tests with Maven (Local)
|
||||
|
||||
If you have Maven installed locally:
|
||||
|
||||
```bash
|
||||
mvn test
|
||||
```
|
||||
|
||||
## Test Results Summary
|
||||
|
||||
### Current Test Coverage
|
||||
|
||||
| Service | Test Class | Test Cases | Status |
|
||||
|---------|-----------|------------|--------|
|
||||
| Hello World Service | HelloWorldServiceImplTest | 10 | ✅ Passing |
|
||||
|
||||
### Test Case Details
|
||||
|
||||
The `HelloWorldServiceImplTest` includes the following test cases:
|
||||
|
||||
1. **testGetHelloWorld_WithValidName** - Verifies greeting with valid name
|
||||
2. **testGetHelloWorld_WithEmptyString** - Handles empty string input
|
||||
3. **testGetHelloWorld_WithNull** - Handles null input gracefully
|
||||
4. **testGetHelloWorld_WithSpecialCharacters** - Handles special characters
|
||||
5. **testGetHelloWorld_WithSpaces** - Handles names with spaces
|
||||
6. **testGetHelloWorld_WithLongName** - Handles long names
|
||||
7. **testGetHelloWorld_ReturnsNonNull** - Ensures non-null response
|
||||
8. **testGetHelloWorld_StartsWithHelloWorld** - Verifies message format
|
||||
9. **testGetHelloWorld_EndsWithExclamation** - Verifies message ending
|
||||
10. **testGetHelloWorld_ContainsName** - Verifies name inclusion
|
||||
|
||||
## Docker Test Configuration
|
||||
|
||||
### Test Architecture
|
||||
|
||||
The project uses a multi-stage Dockerfile:
|
||||
|
||||
- **Stage 1 (tester)**: Runs unit tests
|
||||
- **Stage 2 (builder)**: Builds the WAR file
|
||||
- **Stage 3**: Deploys to Tomcat
|
||||
|
||||
### Test Docker Compose
|
||||
|
||||
The `docker-compose.test.yml` file is configured to:
|
||||
- Target the `tester` stage of the Dockerfile
|
||||
- Mount source code for live testing
|
||||
- Cache Maven dependencies for faster subsequent runs
|
||||
- Set appropriate memory limits
|
||||
|
||||
### Run Tests Manually
|
||||
|
||||
```bash
|
||||
# Build and run tests
|
||||
docker-compose -f docker-compose.test.yml up --build
|
||||
|
||||
# Clean up after tests
|
||||
docker-compose -f docker-compose.test.yml down
|
||||
```
|
||||
|
||||
## Testing Framework
|
||||
|
||||
### Dependencies
|
||||
|
||||
The project uses:
|
||||
|
||||
- **JUnit 5 (Jupiter)** - Testing framework
|
||||
- `junit-jupiter-api:5.9.3` - Test annotations and assertions
|
||||
- `junit-jupiter-engine:5.9.3` - Test execution engine
|
||||
|
||||
- **Mockito** - Mocking framework (for future complex tests)
|
||||
- `mockito-core:5.3.1` - Core mocking functionality
|
||||
- `mockito-junit-jupiter:5.3.1` - JUnit 5 integration
|
||||
|
||||
- **Maven Surefire** - Test runner plugin
|
||||
- Configured to run all `*Test.java` files
|
||||
|
||||
## Writing New Tests
|
||||
|
||||
### Test Structure
|
||||
|
||||
Tests follow the standard JUnit 5 structure:
|
||||
|
||||
```java
|
||||
package com.example.service;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@DisplayName("Service Tests")
|
||||
class YourServiceTest {
|
||||
|
||||
private YourService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
service = new YourServiceImpl();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should do something")
|
||||
void testSomething() {
|
||||
// Arrange
|
||||
String input = "test";
|
||||
String expected = "expected result";
|
||||
|
||||
// Act
|
||||
String result = service.doSomething(input);
|
||||
|
||||
// Assert
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test Best Practices
|
||||
|
||||
1. **Use Descriptive Names**: Use `@DisplayName` for readable test descriptions
|
||||
2. **Follow AAA Pattern**: Arrange, Act, Assert
|
||||
3. **Test Edge Cases**: Include null, empty, and boundary conditions
|
||||
4. **Keep Tests Isolated**: Each test should be independent
|
||||
5. **Test One Thing**: Each test should verify one specific behavior
|
||||
|
||||
### Adding Tests for New Services
|
||||
|
||||
To add tests for other services (e.g., LoanApprovalService):
|
||||
|
||||
1. Create test class in `src/test/java/com/example/service/`
|
||||
2. Follow the naming convention: `{ServiceName}Test.java`
|
||||
3. Run tests to verify
|
||||
|
||||
Example structure for LoanApprovalService tests:
|
||||
|
||||
```java
|
||||
package com.example.service;
|
||||
|
||||
import com.example.model.*;
|
||||
import com.example.repository.*;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.mockito.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@DisplayName("LoanApprovalService Tests")
|
||||
class LoanApprovalServiceTest {
|
||||
|
||||
@Mock
|
||||
private CustomerRepository customerRepository;
|
||||
|
||||
@Mock
|
||||
private CreditScoreService creditScoreService;
|
||||
|
||||
private LoanApprovalService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
service = new LoanApprovalService();
|
||||
// Inject mocks if needed
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should approve loan for high credit score")
|
||||
void testLoanApproval_HighCreditScore() {
|
||||
// Test implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Test Directory Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── main/
|
||||
│ └── java/
|
||||
│ └── com/
|
||||
│ └── example/
|
||||
│ └── service/
|
||||
│ ├── HelloWorldService.java
|
||||
│ └── HelloWorldServiceImpl.java
|
||||
└── test/
|
||||
└── java/
|
||||
└── com/
|
||||
└── example/
|
||||
└── service/
|
||||
└── HelloWorldServiceImplTest.java
|
||||
```
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
### Running Tests in CI/CD
|
||||
|
||||
The Dockerfile includes testing as the first stage, which means:
|
||||
|
||||
- Tests run automatically during Docker build
|
||||
- Build fails if tests fail
|
||||
- Ensures code quality before deployment
|
||||
|
||||
To run tests in CI/CD pipelines:
|
||||
|
||||
```bash
|
||||
# Option 1: Run full build (includes tests)
|
||||
docker build -t jaxws-app .
|
||||
|
||||
# Option 2: Run tests only
|
||||
docker build --target tester -t jaxws-test .
|
||||
|
||||
# Option 3: Use docker-compose
|
||||
docker-compose -f docker-compose.test.yml up --abort-on-container-exit
|
||||
```
|
||||
|
||||
## Viewing Test Reports
|
||||
|
||||
### Console Output
|
||||
|
||||
Test results are displayed in the console with summary:
|
||||
|
||||
```
|
||||
-------------------------------------------------------
|
||||
T E S T S
|
||||
-------------------------------------------------------
|
||||
Running com.example.service.HelloWorldServiceImplTest
|
||||
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 s
|
||||
|
||||
Results:
|
||||
|
||||
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0
|
||||
|
||||
BUILD SUCCESS
|
||||
```
|
||||
|
||||
### Surefire Reports
|
||||
|
||||
Maven Surefire generates detailed reports in:
|
||||
- `target/surefire-reports/` (text and XML formats)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Tests Not Running
|
||||
|
||||
**Problem**: Maven doesn't find tests
|
||||
|
||||
**Solution**:
|
||||
- Ensure test files end with `Test.java`
|
||||
- Verify test directory structure: `src/test/java/`
|
||||
- Check pom.xml includes maven-surefire-plugin
|
||||
|
||||
### Docker Build Fails on Tests
|
||||
|
||||
**Problem**: Docker build fails at test stage
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# View detailed test output
|
||||
docker build --target tester -t jaxws-test .
|
||||
|
||||
# Check test container logs
|
||||
docker logs <container-id>
|
||||
```
|
||||
|
||||
### Dependency Issues
|
||||
|
||||
**Problem**: Cannot resolve JUnit dependencies
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Clear Maven cache and rebuild
|
||||
docker-compose -f docker-compose.test.yml build --no-cache
|
||||
```
|
||||
|
||||
### Permission Denied on run-tests.sh
|
||||
|
||||
**Problem**: Cannot execute run-tests.sh on Linux/Mac
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
chmod +x run-tests.sh
|
||||
./run-tests.sh
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Consider adding tests for:
|
||||
|
||||
1. **LoanApprovalService**
|
||||
- Customer registration workflows
|
||||
- Loan approval logic
|
||||
- Credit score evaluation
|
||||
- Blacklist handling
|
||||
|
||||
2. **Repository Layer**
|
||||
- Database operations
|
||||
- CRUD functionality
|
||||
- Error handling
|
||||
|
||||
3. **Integration Tests**
|
||||
- End-to-end SOAP request/response
|
||||
- Database integration
|
||||
- Multi-service workflows
|
||||
|
||||
4. **Performance Tests**
|
||||
- Load testing
|
||||
- Stress testing
|
||||
- Response time validation
|
||||
|
||||
## Resources
|
||||
|
||||
- [JUnit 5 User Guide](https://junit.org/junit5/docs/current/user-guide/)
|
||||
- [Mockito Documentation](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html)
|
||||
- [Maven Surefire Plugin](https://maven.apache.org/surefire/maven-surefire-plugin/)
|
||||
- [Test-Driven Development Best Practices](https://martinfowler.com/bliki/TestDrivenDevelopment.html)
|
||||
|
||||
## Summary
|
||||
|
||||
This project now has a complete unit testing setup with:
|
||||
|
||||
- ✅ JUnit 5 testing framework
|
||||
- ✅ 10 passing test cases for HelloWorldService
|
||||
- ✅ Docker-based test execution
|
||||
- ✅ Convenient test runner scripts
|
||||
- ✅ Multi-stage Dockerfile with test stage
|
||||
- ✅ Maven Surefire configuration
|
||||
- ✅ Mockito for future mocking needs
|
||||
|
||||
To add more tests, simply create new test classes following the established patterns and run them using the provided scripts.
|
||||
32
docker-compose.coverage.yml
Normal file
32
docker-compose.coverage.yml
Normal file
@ -0,0 +1,32 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
coverage:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.coverage.simple
|
||||
image: jaxws-coverage:latest
|
||||
container_name: jaxws-coverage-report
|
||||
volumes:
|
||||
# Mount source code
|
||||
- ./src:/app/src:ro
|
||||
- ./pom.xml:/app/pom.xml:ro
|
||||
# Mount target directory to export coverage reports to host
|
||||
- ./target:/app/target
|
||||
# Mount Maven cache to speed up builds
|
||||
- maven-cache:/root/.m2
|
||||
environment:
|
||||
- MAVEN_OPTS=-Xmx512m
|
||||
command: >
|
||||
sh -c "mvn test &&
|
||||
echo '=================================================================================' &&
|
||||
echo 'Coverage report generated successfully!' &&
|
||||
echo '=================================================================================' &&
|
||||
echo 'HTML Report: ./target/site/jacoco/index.html' &&
|
||||
echo 'XML Report: ./target/site/jacoco/jacoco.xml' &&
|
||||
echo 'CSV Report: ./target/site/jacoco/jacoco.csv' &&
|
||||
echo '================================================================================'"
|
||||
|
||||
volumes:
|
||||
maven-cache:
|
||||
driver: local
|
||||
@ -12,6 +12,8 @@ services:
|
||||
# Mount source for live testing during development
|
||||
- ./src:/app/src:ro
|
||||
- ./pom.xml:/app/pom.xml:ro
|
||||
# Mount target directory to access test reports and coverage on host
|
||||
- ./target:/app/target
|
||||
# Mount Maven cache to speed up subsequent test runs
|
||||
- maven-cache:/root/.m2
|
||||
command: mvn test
|
||||
|
||||
21
pom.xml
21
pom.xml
@ -108,6 +108,27 @@
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- JaCoCo Plugin for code coverage -->
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.11</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-test</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>post-test</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
44
run-coverage.bat
Normal file
44
run-coverage.bat
Normal file
@ -0,0 +1,44 @@
|
||||
@echo off
|
||||
REM Script to generate code coverage reports using Docker
|
||||
|
||||
echo ================================================================================
|
||||
echo Generating Code Coverage Reports
|
||||
echo ================================================================================
|
||||
echo.
|
||||
|
||||
REM Clean previous reports
|
||||
if exist target\site\jacoco (
|
||||
echo Cleaning previous coverage reports...
|
||||
rmdir /s /q target\site\jacoco
|
||||
echo.
|
||||
)
|
||||
|
||||
REM Run tests with coverage
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
|
||||
echo.
|
||||
echo ================================================================================
|
||||
echo Coverage Report Generated
|
||||
echo ================================================================================
|
||||
echo.
|
||||
echo HTML Report: target\site\jacoco\index.html
|
||||
echo XML Report: target\site\jacoco\jacoco.xml
|
||||
echo CSV Report: target\site\jacoco\jacoco.csv
|
||||
echo.
|
||||
echo Open the HTML report in your browser to view coverage details.
|
||||
echo.
|
||||
|
||||
REM Clean up the coverage container
|
||||
docker-compose -f docker-compose.coverage.yml down
|
||||
|
||||
REM Ask user if they want to open the report
|
||||
set /p OPEN_REPORT="Would you like to open the coverage report now? (y/n): "
|
||||
if /i "%OPEN_REPORT%"=="y" (
|
||||
if exist target\site\jacoco\index.html (
|
||||
start target\site\jacoco\index.html
|
||||
) else (
|
||||
echo Error: Coverage report not found!
|
||||
)
|
||||
)
|
||||
|
||||
pause
|
||||
50
run-coverage.sh
Normal file
50
run-coverage.sh
Normal file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to generate code coverage reports using Docker
|
||||
|
||||
echo "================================================================================"
|
||||
echo "Generating Code Coverage Reports"
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
|
||||
# Clean previous reports
|
||||
if [ -d "target/site/jacoco" ]; then
|
||||
echo "Cleaning previous coverage reports..."
|
||||
rm -rf target/site/jacoco
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Run tests with coverage
|
||||
docker-compose -f docker-compose.coverage.yml up --build
|
||||
|
||||
echo ""
|
||||
echo "================================================================================"
|
||||
echo "Coverage Report Generated"
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
echo "HTML Report: target/site/jacoco/index.html"
|
||||
echo "XML Report: target/site/jacoco/jacoco.xml"
|
||||
echo "CSV Report: target/site/jacoco/jacoco.csv"
|
||||
echo ""
|
||||
echo "Open the HTML report in your browser to view coverage details."
|
||||
echo ""
|
||||
|
||||
# Clean up the coverage container
|
||||
docker-compose -f docker-compose.coverage.yml down
|
||||
|
||||
# Ask user if they want to open the report (for systems with xdg-open)
|
||||
read -p "Would you like to open the coverage report now? (y/n): " OPEN_REPORT
|
||||
if [ "$OPEN_REPORT" = "y" ] || [ "$OPEN_REPORT" = "Y" ]; then
|
||||
if [ -f "target/site/jacoco/index.html" ]; then
|
||||
# Try to open with default browser
|
||||
if command -v xdg-open > /dev/null; then
|
||||
xdg-open target/site/jacoco/index.html
|
||||
elif command -v open > /dev/null; then
|
||||
open target/site/jacoco/index.html
|
||||
else
|
||||
echo "Please open target/site/jacoco/index.html manually in your browser."
|
||||
fi
|
||||
else
|
||||
echo "Error: Coverage report not found!"
|
||||
fi
|
||||
fi
|
||||
4
scripts/run_coverage.sh
Normal file
4
scripts/run_coverage.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
echo "Running tests with code coverage..."
|
||||
mvn clean test
|
||||
echo "Coverage report generated in target/site/jacoco/"
|
||||
Reference in New Issue
Block a user