Lesson 23 / 25

Running Tests in CI

Organise unit and integration tests in builds and keep the pipeline fast and trustworthy.

Tests that run on every change

Tests protect you only if they run automatically. In CI, run the fast unit tests on every push and pull request, and integration tests (Testcontainers, Spring context) in the same pipeline or a parallel job. With Maven, Surefire runs *Test classes during test, and Failsafe runs *IT classes during integration-test and verify, ensuring cleanup steps still run if integration tests fail. With Gradle, define a separate source set or task for integration tests. Publish JUnit XML reports so the CI system shows failures, durations and trends; publish coverage reports too. Keep the pipeline fast: parallelise test execution and CI jobs, cache dependencies, reuse containers, and move slow end-to-end suites to a separate stage. Treat flaky tests as bugs: track them, quarantine with a ticket if necessary, and fix them quickly. Make a red build stop the line: nobody merges on top of failing tests.

A GitHub Actions workflow for a Maven project

Unit and integration tests, with reports uploaded for every run.

name: build
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '21'
          cache: maven
      - name: Unit and integration tests
        run: ./mvnw -B verify          # surefire (*Test) then failsafe (*IT); Docker is available on this runner
      - name: Upload test reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-reports
          path: |
            target/surefire-reports
            target/failsafe-reports
            target/site/jacoco

Quality checks on an assembly line

CI tests are the inspection stations on an assembly line: quick checks at every step catch defects immediately, and a full inspection before shipping catches what slipped through. Stopping the line when a check fails is cheaper than recalling cars later.

Quick check: In a Maven build, which plugin conventionally runs integration test classes named *IT?

  • Surefire
  • Failsafe
  • JaCoCo
  • Shade
Answer

Failsafe — Failsafe runs integration tests in the integration-test and verify phases.