Your First CI Pipeline
Creating and Running Our First CI Pipeline
In this guide, we will create our first CI pipeline using GitLab. We will start with a simple pipeline that builds the code and runs unit tests. We will then extend the pipeline based on our project requirements.
The pipeline will be defined in a file named .gitlab-ci.yml in the root of our project. This file is written in YAML (YAML Ain't Markup Language), a human-readable data serialization language.
ℹ️ YAML is often used in DevOps tools because of its simplicity and readability. Except Terraform and a few other tools, most DevOps and Cloud Native tools use YAML for configuration: GitLab, GitHub Actions, Kubernetes, Ansible, SaltStack, Docker Compose, Helm, Istio, Prometheus, Grafana, Fluentd, Loki... the list goes on and on.
We are going to create a simple unit test for our project.
ℹ️ A unit test is a test that verifies the behavior of a small piece of code, usually a function or a method. It is a test that is isolated from the rest of the code and doesn't depend on external services or databases. Unit tests are fast to run and easy to write. They are the foundation of a good test suite.
Unit testing is so important that some companies require developers to write unit tests before writing the actual code. This is called Test-Driven Development (TDD). The idea is to write a failing test first, then write the code to make the test pass. This way, you are sure that the code you write is actually needed and that it works as expected.
To proceed, we are going to use a Python unit testing tool called unittest. The following code will test the /tasks endpoint of our Flask application:
cat <<EOF >$HOME/todo/app/test_app.py
# Import the required libraries from the unittest module.
import unittest
# Import the required libraries from the Flask application.
from app import app
# Define a class that inherits from the TestCase class.
# This class will contain the unit tests for the Flask application.
class TestToDoApp(unittest.TestCase):
# Define a method that will be executed before each test.
def setUp(self):
# Create a test client for the Flask application.
self.app = app.test_client()
# Propagate the exceptions to the test client.
self.app.testing = True
# Define a method to test the GET /tasks endpoint.
def test_get_tasks(self):
# Send a GET request to the '/tasks' endpoint.
response = self.app.get('/tasks')
# Check if the response status code is 200 (OK).
self.assertEqual(response.status_code, 200)
# Define a method to test the POST /tasks endpoint.
def test_add_task(self):
# Create a dictionary containing the task details.
task = {
'title': 'Task 1',
'description': 'Description 1'
}
# Send a POST request to the '/tasks' endpoint with the task details.
response = self.app.post('/tasks', json=task)
# Check if the response status code is 201 (Created).
self.assertEqual(response.status_code, 201)
# Define the main entry point of the test script.
if __name__ == '__main__':
# Run the unit tests.
unittest.main()Cloud Native CI/CD with GitLab
From Commit to Production ReadyEnroll now to unlock all content and receive all future updates for free.
