DEV Community

Cover image for Running Tests in GitLab CI: From Zero to Pipeline
Thiago Matos
Thiago Matos

Posted on • Edited on

Running Tests in GitLab CI: From Zero to Pipeline

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"


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

List of available Java versions
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


Enter fullscreen mode Exit fullscreen mode

Third, confirm you've installed successfully



java --version


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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:

  1. Project: Gradle - Kotlin
  2. Language: Java
  3. Spring Boot: 3.3.1
  4. Packaging: jar
  5. Java: 21
  6. Dependencies: No dependency is necessary

Click on the button GENERATE to download the project as zip.

Spring Initializr Configured

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;
    }
}


Enter fullscreen mode Exit fullscreen mode

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);
    }
}


Enter fullscreen mode Exit fullscreen mode

Second, let the test fail.
Press one of the Green Buttons to run the test.
Press Green Button to run the test

Check that the test fails.

Test failing

Third, fix the test by writing the correct business rule:


 java
public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}


Enter fullscreen mode Exit fullscreen mode

And, at last, run the test again and see that now it is passing.

Test 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


Enter fullscreen mode Exit fullscreen mode

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

New empty gitlab 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

Enter fullscreen mode Exit fullscreen mode




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.

the first and only existent pipeline

Here you can see the pipeline running:
The pipeline running

After some time, the pipeline passes:
The pipeline passed

Here you can see the test report:
Image description

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)

Collapse
 
akshit_patel_22 profile image
AKSHIT PATEL

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?"

Collapse
 
thiagoematos profile image
Thiago Matos

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.

Collapse
 
akshit_patel_22 profile image
AKSHIT PATEL

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?

Thread Thread
 
thiagoematos profile image
Thiago Matos

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:

class CalculatorTest {
    @Test
    void itShouldReturnTheResultWhenPlusTwoOperand() {
        // given
        var firstOperand = 2;
        var secondOperand = 3;
        var theCalculator = new Calculator();
        // when
        var result = theCalculator.add(firstOperand, secondOperand);
        // then
        assertThat(result).isEqualTo(5);
    }
}
Enter fullscreen mode Exit fullscreen mode

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.