CI with GitHub Actions for Java: Running Unit Tests with Maven Step by Step

GitHub Actions Java Maven unit tests

🧩 Introduction

Automating tests is one of the key pillars of quality in modern software systems. In Java projects using Spring Boot, ensuring that unit tests run on every change is essential to maintain application reliability.

In this article, we will configure a simple CI (Continuous Integration) pipeline using GitHub Actions, focused on running unit tests with Maven.

We will use as an example a project based on Domain Driven Design (DDD) with Java 21 and MapStruct.

🚀 What is GitHub Actions?

GitHub Actions is a native GitHub tool that allows you to automate workflows directly within your repository.

With it, you can:

  • Automatically run tests
  • Build your application
  • Publish artifacts
  • Integrate with external tools

All triggered by events such as push or pull request.

🏗️ Project structure

Our project is organized as follows:

website-projects/
└─ ddd-java-spring-dto-model-entity/
├─ pom.xml
└─ src/

⚙️ Creating the GitHub Actions workflow

To configure the pipeline, we create the following file:

.github/workflows/java-tests.yml

📄 GitHub Actions YAML

name: Java Unit Tests

on:
  push:
    branches: [ "main" ]
    paths:
      - "ddd-java-spring-dto-model-entity/**"
      - ".github/workflows/java-tests.yml"

  pull_request:
    branches: [ "main" ]
    paths:
      - "ddd-java-spring-dto-model-entity/**"
      - ".github/workflows/java-tests.yml"

jobs:
  test:
    runs-on: ubuntu-latest

    defaults:
      run:
        working-directory: ddd-java-spring-dto-model-entity

    steps:
      - name: Checkout do código
        uses: actions/checkout@v4

      - name: Configurar Java 21
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: '21'
          cache: maven

      - name: Executar testes unitários
        run: mvn -B test

🔍 Workflow breakdown

🔹 name

name: Java Unit Tests

Defines the name displayed in GitHub Actions.

🔹 on (triggers)

on:
  push:
  pull_request:

The workflow runs when:

  • code is pushed to the main branch
  • a pull request is opened or updated

🔹 paths (important optimization)

paths:
  - "ddd-java-spring-dto-model-entity/**"

👉 Ensures the pipeline runs only when changes occur in the project folder, avoiding unnecessary executions.

🔹 jobs

jobs:
  test:
    runs-on: ubuntu-latest

Defines a job that runs on a Linux machine.

🔹 working-directory (key point)

defaults:
  run:
    working-directory: ddd-java-spring-dto-model-entity

👉 This is critical:

Since the project is inside a subdirectory, we define the working directory so Maven can correctly locate the pom.xml.

🔹 checkout

- uses: actions/checkout@v4

Clones the repository into the runner.

🔹 Java setup

- uses: actions/setup-java@v5

Configures:

  • Java 21
  • Maven dependency caching

👉 This significantly improves build performance.

🔹 Running tests

run: mvn -B test

Runs unit tests.

  • -B → batch mode (recommended for CI)

🔄 Pipeline flow

GitHub Actions Java Maven unit tests

GitHub Actions Java Maven unit tests

💡 Best practices

  • ✔️ Use dependency caching (already applied)
  • ✔️ Limit execution using paths
  • ✔️ Fix Java version (e.g., 21)
  • ✔️ Keep the pipeline simple at first

🔥 Possible improvements

You can evolve this pipeline to include:

  • 📊 Code coverage with JaCoCo
  • 🧪 Integration tests
  • 🐳 Docker build
  • 🚀 Automatic deployment

🔗 Example project

👉 https://github.com/isacaguiar/website-projects

🧠 Conclusion

With just a few steps, we created an efficient CI pipeline for Java projects.

This approach:

  • improves code quality
  • reduces production issues
  • makes your repository more professional

And best of all: everything is fully integrated into GitHub.

Share this content:


Newsletter / CTA

Let’s grow together in technology, career, and discipline.

Follow new articles on backend, architecture, performance, and the lessons that also come from sports. A space to share knowledge, consistency, and growth throughout the journey.