mirror of https://github.com/docker/docs.git
126 lines
4.7 KiB
Markdown
126 lines
4.7 KiB
Markdown
---
|
||
title: Run your Java tests
|
||
linkTitle: Run your tests
|
||
weight: 30
|
||
keywords: Java, build, test
|
||
description: How to build and run your Java tests
|
||
aliases:
|
||
- /language/java/run-tests/
|
||
- /guides/language/java/run-tests/
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
Complete all the previous sections of this guide, starting with [Containerize a Java application](containerize.md).
|
||
|
||
## Overview
|
||
|
||
Testing is an essential part of modern software development. Testing can mean a lot of things to different development teams. There are unit tests, integration tests and end-to-end testing. In this guide you'll take a look at running your unit tests in Docker.
|
||
|
||
### Multi-stage Dockerfile for testing
|
||
|
||
In the following example, you'll pull the testing commands into your Dockerfile.
|
||
Replace the contents of your Dockerfile with the following.
|
||
|
||
```dockerfile {hl_lines="3-19"}
|
||
# syntax=docker/dockerfile:1
|
||
|
||
FROM eclipse-temurin:21-jdk-jammy as base
|
||
WORKDIR /build
|
||
COPY --chmod=0755 mvnw mvnw
|
||
COPY .mvn/ .mvn/
|
||
|
||
FROM base as test
|
||
WORKDIR /build
|
||
COPY ./src src/
|
||
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
|
||
--mount=type=cache,target=/root/.m2 \
|
||
./mvnw test
|
||
|
||
FROM base as deps
|
||
WORKDIR /build
|
||
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
|
||
--mount=type=cache,target=/root/.m2 \
|
||
./mvnw dependency:go-offline -DskipTests
|
||
|
||
FROM deps as package
|
||
WORKDIR /build
|
||
COPY ./src src/
|
||
RUN --mount=type=bind,source=pom.xml,target=pom.xml \
|
||
--mount=type=cache,target=/root/.m2 \
|
||
./mvnw package -DskipTests && \
|
||
mv target/$(./mvnw help:evaluate -Dexpression=project.artifactId -q -DforceStdout)-$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout).jar target/app.jar
|
||
|
||
FROM package as extract
|
||
WORKDIR /build
|
||
RUN java -Djarmode=layertools -jar target/app.jar extract --destination target/extracted
|
||
|
||
FROM extract as development
|
||
WORKDIR /build
|
||
RUN cp -r /build/target/extracted/dependencies/. ./
|
||
RUN cp -r /build/target/extracted/spring-boot-loader/. ./
|
||
RUN cp -r /build/target/extracted/snapshot-dependencies/. ./
|
||
RUN cp -r /build/target/extracted/application/. ./
|
||
ENV JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000"
|
||
CMD [ "java", "-Dspring.profiles.active=postgres", "org.springframework.boot.loader.launch.JarLauncher" ]
|
||
|
||
FROM eclipse-temurin:21-jre-jammy AS final
|
||
ARG UID=10001
|
||
RUN adduser \
|
||
--disabled-password \
|
||
--gecos "" \
|
||
--home "/nonexistent" \
|
||
--shell "/sbin/nologin" \
|
||
--no-create-home \
|
||
--uid "${UID}" \
|
||
appuser
|
||
USER appuser
|
||
COPY --from=extract build/target/extracted/dependencies/ ./
|
||
COPY --from=extract build/target/extracted/spring-boot-loader/ ./
|
||
COPY --from=extract build/target/extracted/snapshot-dependencies/ ./
|
||
COPY --from=extract build/target/extracted/application/ ./
|
||
EXPOSE 8080
|
||
ENTRYPOINT [ "java", "-Dspring.profiles.active=postgres", "org.springframework.boot.loader.launch.JarLauncher" ]
|
||
```
|
||
|
||
First, you added a new base stage. In the base stage, you added common instructions that both the test and deps stage will need.
|
||
|
||
Next, you added a new test stage labeled `test` based on the base stage. In this
|
||
stage you copied in the necessary source files and then specified `RUN` to run
|
||
`./mvnw test`. Instead of using `CMD`, you used `RUN` to run the tests. The
|
||
reason is that the `CMD` instruction runs when the container runs, and the `RUN`
|
||
instruction runs when the image is being built. When using `RUN`, the build will
|
||
fail if the tests fail.
|
||
|
||
Finally, you updated the deps stage to be based on the base stage and removed
|
||
the instructions that are now in the base stage.
|
||
|
||
Run the following command to build a new image using the test stage as the target and view the test results. Include `--progress=plain` to view the build output, `--no-cache` to ensure the tests always run, and `--target test` to target the test stage.
|
||
|
||
Now, build your image and run your tests. You'll run the `docker build` command and add the `--target test` flag so that you specifically run the test build stage.
|
||
|
||
```console
|
||
$ docker build -t java-docker-image-test --progress=plain --no-cache --target=test .
|
||
```
|
||
|
||
You should see output containing the following
|
||
|
||
```console
|
||
...
|
||
|
||
#15 101.3 [WARNING] Tests run: 45, Failures: 0, Errors: 0, Skipped: 2
|
||
#15 101.3 [INFO]
|
||
#15 101.3 [INFO] ------------------------------------------------------------------------
|
||
#15 101.3 [INFO] BUILD SUCCESS
|
||
#15 101.3 [INFO] ------------------------------------------------------------------------
|
||
#15 101.3 [INFO] Total time: 01:39 min
|
||
#15 101.3 [INFO] Finished at: 2024-02-01T23:24:48Z
|
||
#15 101.3 [INFO] ------------------------------------------------------------------------
|
||
#15 DONE 101.4s
|
||
```
|
||
|
||
## Next steps
|
||
|
||
In the next section, you’ll take a look at how to set up a CI/CD pipeline using
|
||
GitHub Actions.
|