How to Integrate Test Driven Development With CI/CD

Boemo Wame Mmopelwa
Share this :
Share this :

Sometimes developers don’t implement the Test Driven Development (TDD) methodology just because the project they are building is small and does not need testing frameworks. But, this is a fatal mistake. Big projects start as small projects. Once the value of the small project is acknowledged, the small project gets scaled into a medium or big project.

TDD is an imperative development method that ensures that your project meets every requirement and security standard at every phase of the project. If you don’t implement TDD because it requires more discipline, this is the right article for you. This article will teach you how to automate TDD tests using a CI/CD tool. A CI/CD tool like Travis CI can improve the simplicity and time taken to implement TDD.

What is Test-Driven Development

Test Driven Development is a software development concept that emphasizes writing tests before writing application code to ensure that the codebase is consistently tested and validated. TDD has the following steps that we will cover in detail in the next section of the article:

  1. Write a test
  2. Run the test
  3. Write code
  4. Run the test again until the code passes the tests.
  5. Refactor
  6. Repeat

TDD is iterative as it follows a cycle that keeps on testing the code and refactoring the code until the code meets the requirements and the client’s expectations. TDD is customer feedback driven and the client is the first priority.

The problem with writing code before a test is that it’s easy to get lost in the development process and forget the client’s expectations. It gets worse when you are a perfectionist. You keep on adding and eliminating chunks of code just because you think the code is not enough for the function. By the time you start testing the code the tests are big and output endless complicated errors.

Let’s say you are developing an e-commerce website. You start by defining the components and setting the website logic. After you are done developing the website you start writing tests. When writing tests, you realize you forgot to add validation checks for user input, and the worst happens: the code doesn’t give the expected output when invalid data is submitted, causing incorrect order processing and potential data corruption.

This situation gets better if you follow TDD as it does not only give you a clearly defined workflow it guides you through every step to prevent you from missing critical goals and application expectations.

TDD is efficient at eliminating technical debt because bugs are caught when they are still small and less complex. Code is optimized at every step to avoid intricate code that needs expensive maintenance later on. This also saves you time because eliminating flaws when they are big and widespread across the application architecture is time-consuming.

TDD was a methodology that came from agile development and Extreme Programming (XP). TDD fits in well with agile development workflows because:

  1. TDD follows an iterative cycle of testing functionalities continuously. This continuous can be broken and fit into agile sprints.
  2. TDD enables quick code change.
  3. TDD enables rapid prototyping and experimentation based on customer feedback.

How to Set Up a CI/CD Pipeline for Test-Driven Development

Before we start automating the TDD process, let’s set up Travis CI with GitHub. Travis CI has a 30 day free trial you can use to explore how CI/CD can boost your testing workflow. Go to Travis CI and log in using your GitHub account. GitHub will ask you to authorize and give Travis CI permission to your repositories, make sure you authorize Travis CI.

After logging into Travis CI using GitHub you are all set. Next, navigate to the Travis dashboard to familiarize yourself with the Travis CI.

Next, you have to write the .travis.yml or Travis file to set up continuous integration configuration. This file is stored in the repository root path. The Travis file defines how Travis CI will build the application environment. Without this file, your Travis CI pipeline does not exist. This file contains the following important pipeline configuration components:

  1. The language used to build your application.
  2. The script entails the commands to run and tests.
  3. The Travis file enables you to install dependencies for your project. The project that we will be using as an example will be a Node.js project. So, the language is set to Node.js and npm commands will be run.

Using the .travis.yml file Travis CI will clone your repository and create a virtual environment that suits your project dependencies. Travis CI uses the tests in your repository to test your code. Ensure that your tests are stored in the right folders for example Javascript tests are located in the tests/ folder or end with the .tests.js extension. This will change depending on the testing framework or library you are using.

How to Integrate Test-Driven Development with Travis CI

In this section, you will learn how to integrate TDD with Travis CI/CD. Integrating TDD with Continuous Integration (CI) and Continuous Deployment (CD) practices ensures that the benefits of TDD are fully realized in a modern development workflow.

To make this tutorial more pragmatic we’ll be testing a simple ecommerce shopping cart component. You do not have to build an application to be able to execute the instructions laid out in the following sections. As long as you have code that has tests you are good to go. If you don’t have code, please go ahead and copy the code and tests from this tutorial to create your own files.

Your GitHub repository structure needs to have the following files:

  1. App.js(your app code can be in any file)
  2. app.tests.js
  3. Travis file
  4. Package.json file

In addition, make sure you have set up a testing framework and downloaded its necessary dependencies. Below is the package.json file for the shopping cart component, the project uses the Jest testing framework to execute and compile tests.

The TDD cycle is also called the Red Green Refactor. The red stands for testing phase and the green stands for the implementing code phase. Below are the 3 core phases of the Test Driven Development methodology.

1. Writing Tests (The Red Phase)

This is the most challenging phase of the cycle. You are tasked with creating unit tests for code that does not exist. The tests will fail because the code isn’t written yet. This phase is called the Red phase because the unit test framework will display red error texts when you try to compile the tests. It’s all red until you implement the code. The essence of this phase is not to get compiling tests, the goal is to set up guardrails for the code’s functionality and behavior.

The shopping cart that we will be testing simply displays products and gives the user buttons to add or remove a product from the cart using React. Once you add the below code to your repository that you connected with Travis CI and make a commit on Github Travis CI will trigger a test pipeline on the cloud.

Here is the app.tests.js that tests the shopping cart component.

The above test functions cause errors because there are many components that have to be defined in the application code file for the tests to be successful. Below is an image showing the job log in Travis CI dashboard that shows how the shopping cart tests failed. Whenever Travis CI is done building your project it will send you an email that notifies whether the tests have failed or passed.

2. Writing Code (The Green Phase)

In this phase, you aim to write sufficient code that passes the tests set in the previous phase. Nothing less, nothing more. The phase keeps everything simple as the refactoring phase is the one that cleans and optimizes the code. Developers have to compile the code and then launch the unit test framework to test the code. The code has to pass the tests to proceed to the next phase. Below is the shopping cart component code in app.js file,

After writing and adding the code the tests pass even though there are still issues…

The issue is that the shopping cart component code is using a deprecated React library as shown in the image below. Once we replace the ReactDOMTestUtilis.act with the act function from react alll issues caused by deprecated libraries will be resolved.

3. Refactoring and Optimizing the Code

Since the previous stage doesn’t follow any code optimization and security standards the refactoring phase focuses on polishing the code: deleting code duplicates, improving code readability, maintenance, and overall code security. In the end, the code has to be of good standard and secure from flaws.

During this phase, you will get alerts from Travis CI when you break the functionality as the pipeline runs automatically to verify your new code additions. So, you don’t have to worry about ruining the code that meets requirements when deleting duplicates and insecure code.

For refactoring you can use multiple libraries and tools for improving the code. A linting tool like JSHint is good at identifying syntax errors and duplicates.

Conclusion

Pairing Travis CI with Test Driven Development is a game changer. Code is tested on every commit you make and the test results are displayed on the dashboard. We did not have to write any intimidating commands in this tutorial to achieve TDD automation. This is good for beginners and self taught DevOps engineers.

This is the true glory of automation. It empowers developers to catch errors early and identify their mistakes before they cause data breaches that cost the company millions of dollars.

Written By
Boemo Wame Mmopelwa
Boemo is a software developer who embraces innovative approaches when building applications. He likes diving deep into complex concepts in order to learn and write articles that can help the reader understand complex methodologies in a simple and fun way.
Reviewed By
Stan Jaromin
Stan Jaromin is a Product Manager with Travis CI. Stan drives the product roadmap and manages the entire development process. Stan thrives on collaboration, working closely with engineers, designers, and customers to ensure the creation of user-centric products. Stan's experience translates to a deep understanding of the entire product lifecycle.
© Copyright 2024, All Rights Reserved