Continuous Integration (CI) is an essential practice in modern software development. It ensures that code changes are automatically tested, leading to faster and more reliable software releases. In this article, we'll walk through the process of setting up a Spring Boot project with Gradle, writing unit tests, and configuring GitLab CI to automate the testing.
Pre-requirements:
- Linux (Ubuntu based) Operational System
- GitLab Account
- Tool to unzip a file
Step 1: Install SDKMAN and Java 21
First, we need to install SDKMAN, a tool for managing parallel versions of multiple Software Development Kits (SDKs), including Java.
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
You can close and open again your terminal to assure your installation is successful.
Second, use sdkman to install Java 21, the most stable version.
The command below shows the available versions:
sdk list java
You can choose one of your preferences. Use the Identifier column as reference to install the chosen version:
sdk install java 21.0.2-open
Third, confirm you've installed successfully
java --version
Step 2: Install Git
Next, install Git, a version control system that we'll use to manage code changes of our project.
sudo apt-get update
sudo apt-get install git
Step 3 Install IntelliJ IDEA
IntelliJ IDEA is a popular IDE(Integrated Development Environment) for Java development. Here is the command to install it:
sudo snap install intellij-idea-community --classic
Step 4: Create a Spring Boot Project
We'll use Spring Initializr to create a new project for the most recent version.
Access https://start.spring.io/ and configure the project as follows:
- Project: Gradle - Kotlin
- Language: Java
- Spring Boot: 3.3.1
- Packaging: jar
- Java: 21
- Dependencies: No dependency is necessary
Click on the button GENERATE to download the project as zip.
Step 5: Import the Project into IntelliJ
Unzip the downloaded file into a folder of your preference.
Open IntelliJ IDEA and import the unzipped project. IntelliJ will automatically detect the Gradle configuration and set up the project accordingly.
Step 6: Make a TDD
First, let's create a Test. Create a simple class and a corresponding unit test.
Create a new class named Calculator in the folder src/main/java/com/example/demo:
java
public class Calculator {
public int add(int a, int b) {
return 0;
}
}
Use jUnit lib (it already comes with the Spring Boot) to create its unit test in the folder src/test/java/com/example/demo:
java
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class CalculatorTest {
@Test
void testAdd() {
var calculator = new Calculator();
var result = calculator.add(2, 3);
assertThat(result).isEqualTo(5);
}
}
Second, let the test fail.
Press one of the Green Buttons to run the test.
Check that the test fails.
Third, fix the test by writing the correct business rule:
java
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
And, at last, run the test again and see that now it is passing.
Step 6: Create a Gitlab CI Configuration File
Create a .gitlab-ci.yml file in the root of your project. This file will define the pipeline.
yml
stages:
- build
Build:
stage: build
image: gradle:8.8.0-alpine
script:
- gradle --build-cache clean build
artifacts:
when: always
expire_in: 1 days
paths:
- build/libs/*.jar
- build/test-results/test/*.xml
reports:
junit:
- build/test-results/test/*.xml
only:
- main
stages: define a sequence of steps that the pipeline will execute. The pipeline runs stages in the order they are defined, and all jobs within the same stage run in parallel. Only after all jobs in a stage complete successfully does the pipeline proceed to the next stage.
Build: name of the job to be executed for the stage.
Image: Docker Image that will be used to execute the job.
script: gradle command to generate the jar, run the tests and generate a report about the tests.
artifacts: Files that will survive when the job is done.
only: name of the git branch
Step 8: Create a Project on GitLab
Gitlab is a web-based DevOps lifecycle tool that provides a Git repository manager offering source code management, continuous integration, and continuous deployment capabilities.
Go to GitLab and create a new blank project and make it public or private based on your preference.
https://gitlab.com/projects/new#blank_project
Step 9: Configure Git in Project
Open the terminal, go to the directory where you unzipped your code and configure git on it.
git init --initial-branch=main
git remote add origin https://gitlab.com/your-username/spring-boot-unit-test-ci.git
git add .
git commit -m "Initial commit"
git push --set-upstream origin main
Step 10: Check the pipeline running
Go to https://gitlab.com/your-username/spring-boot-unit-test-ci/-/pipelines and click on the first (and only existent) pipeline running.
Here you can see the pipeline running:
After some time, the pipeline passes:
Here you can see the test report:
Conclusion
By following these steps, you've successfully set up a Spring Boot project with Gradle, written an unit test, and configured GitLab CI to automate the testing. You can now make a test fail intentionally and observe the pipeline breaking, then fix the test and see the pipeline pass again. This iterative process helps ensure that your code is always in a deployable state.
Here is the link to the project:
https://gitlab.com/thiagoematos/spring-boot-unit-test-ci
Top comments (4)
Hello sir✋
I have one query regarding to automated testing:
"What are the most experience challenges faced by teams while using automated testing in ci/cd pipeline?"
Hello Patel!
One major challenge is test maintenance; as the codebase evolves, tests need to be updated to reflect changes in functionality, which can be time-consuming and require significant effort. Another issue is the challenge of having a unique environment to execute the automation; ensuring that tests run in a consistent and isolated environment can be difficult. Additionally, skill gaps within the team can hinder the effective implementation of automated testing and CI/CD pipelines, necessitating adequate training and a culture of continuous learning.
thank you sir for your response now i have an encounter question about it, so what are the strategies adopted by team or organization to handle these challenges?
For test maintenance, adhere to the same principles used in production code, such as clean code, design patterns, and SOLID principles. Another thing that helps is use the Gherkin Language to write test code. To ensure environment consistency, use containerization tools like TestContainers to create consistent and isolated environments for running tests. To bridge skill gaps, implement Coding Dojos and Pair Programming sessions where less experienced team members can learn from more experienced coworkers, fostering a culture of continuous learning.
Here is an example of gherkin language. Also, note the variables and method are well described:
I hope this helps you.
Feel free to ask any further questions.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.