Unit Testing Explained: A Simple Guide for Developers.

Unit Testing Explained: A Simple Guide for Developers.

Introduction.

  • Unit Testing.
  • Unit testing is the type of software testing.
  • It’s also known as component testing.
  • In unit testing the small piece of software code are tested.
  • Unit testing mostly done by developers but some time QA engineers also do unit testing.
  • The purpose of unit testing is to validate each unit of software code to performs as expected.
  • Unit testing done during coding phases.
  • In SDLC, STLC, V Model, Unit testing is first level of testing done before integration testing.
  • Unit testing is a WhiteBox testing technique.

Top 8 Tools.

  1. Junit.
  2. NUnit.
  3. DBUnit.
  4. HTMLUnit.
  5. PHPUnit.
  6. Simple test
  7. Embunit.
  8. ABAP Unit.

Automated Unit testing.

Testing unit tests inside a CI/CD pipeline means automating their execution, validating results, and enforcing quality gates every time code changes. Below is a practical, step-by-step explanation with real CI/CD examples.

1. Add Unit Tests to the Codebase

  • Place unit tests in standard directories
    (e.g., src/test, tests/, __tests__)
  • Ensure tests can be run with a single command

Examples:

mvn test

pytest

npm test

2. Configure the CI/CD Pipeline

The pipeline should automatically:

  1. Pull code
  2. Install dependencies
  3. Build the app
  4. Run unit tests
  5. Collect results

3. Example CI/CD Pipeline Configurations

Jenkins (Jenkinsfile)

pipeline {   agent any   stages {     stage(‘Checkout’) {       steps {         checkout scm       }     }     stage(‘Build’) {       steps {         sh ‘mvn clean compile’       }     }     stage(‘Unit Tests’) {       steps {         sh ‘mvn test’       }       post {         always {           junit ‘target/surefire-reports/*.xml’         }       }     }   } }

Pipeline fails if any unit test fails

GitHub Actions

name: CI Unit Tests on: [push, pull_request] jobs:   test:     runs-on: ubuntu-latest     steps:     – uses: actions/checkout@v4     – name: Set up Java       uses: actions/setup-java@v4       with:         java-version: ’17’         distribution: ‘temurin’     – name: Run Unit Tests       run: mvn test

GitLab CI

stages:   – test unit_test:   stage: test   script:     – mvn test

4. Validate Test Results

  • CI automatically checks exit codes
    • 0 → Pass
    • ≠ 0 → Fail pipeline
  • Test reports are generated (JUnit XML, HTML)

5. Publish Unit Test Reports

Ensure visibility of results:

ToolReport Type
JenkinsJUnit / HTML
GitHub ActionsTest Summary
GitLabTest Reports
Azure DevOpsTest Runs

Example (Jenkins):

junit ‘target/surefire-reports/*.xml’

6. Enforce Code Coverage

Fail pipeline if coverage is too low

Example (Maven + JaCoCo):

  BUNDLE               INSTRUCTION       COVEREDRATIO       0.80        

7. Add Quality Gates (Optional but Recommended)

  • Integrate SonarQube
  • Fail pipeline if:
    • Coverage < threshold
    • Bugs or vulnerabilities found

8. Test Failure Scenarios

To verify unit testing works in CI/CD:

  1. Intentionally break a test
  2. Push code
  3. Confirm:
    1. Pipeline fails
    1. Error appears in test report
    1. Deployment is blocked

This proves unit tests are enforced correctly

9. Best Practices for Unit Testing in CI/CD

  • Run unit tests before build artifacts
  • Keep execution time short
  • Do not depend on DB, APIs, or network
  • Run tests on every:
    • Push
    • Pull request
  • Fail fast on test failure

10. CI/CD Unit Testing Flow Diagram

Commit → CI Trigger → Build → Unit Tests → Report → Next Stage

                          ❌ Fail = Stop

Manual Unit Testing.

1️ Application Code (Unit Under Test)

Calculator.java

public class Calculator {     public int divide(int a, int b) {         return a / b;     } }

2️ Manual Unit Test Demo (Developer Side)

Step 1: Write Manual Test Case (Documented)

Test Case IDUT-01
ClassCalculator
Methoddivide(int a, int b)
Inputa = 10, b = 2
Expected Output5
Actual Output5
StatusPass

Step 2: Manually Execute Test

public class ManualTest {     public static void main(String[] args) {         Calculator calc = new Calculator();         System.out.println(calc.divide(10, 2));     } }

Console Output

5

Developer manually verifies output
Test marked as PASS

Step 3: Manual Negative Test

Test CaseInputExpected Result
UT-02divide(10, 0)Exception

System.out.println(calc.divide(10, 0));

Developer confirms ArithmeticException
Logic validated manually

3️ Convert Manual Unit Test → Automated Test (Required for CI/CD)

CalculatorTest.java (JUnit)

import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; class CalculatorTest {     @Test     void testDivideSuccess() {         Calculator calc = new Calculator();         assertEquals(5, calc.divide(10, 2));     }     @Test     void testDivideByZero() {         Calculator calc = new Calculator();         assertThrows(ArithmeticException.class,             () -> calc.divide(10, 0));     } }

This is what CI/CD will run

4️ CI/CD Pipeline Demo (Jenkins)

Jenkinsfile

pipeline {   agent any   stages {     stage(‘Checkout’) {       steps {         checkout scm       }     }     stage(‘Build’) {       steps {         sh ‘mvn clean compile’       }     }     stage(‘Unit Tests’) {       steps {         sh ‘mvn test’       }       post {         always {           junit ‘target/surefire-reports/*.xml’         }       }     }   } }

5️ CI/CD Execution Result

 When Tests Pass

[INFO] Tests run: 2, Failures: 0

BUILD SUCCESS

 If Logic Breaks

  • Pipeline fails
  • Deployment stops
  • Developer notified

6️ CI/CD Flow Diagram (Demo View)

Developer

   ↓

Manual Unit Test (Local)

   ↓

Automated Unit Test

   ↓

Git Commit

   ↓

CI/CD Pipeline

   ↓

Unit Tests Pass → Deploy

Conclusion.

Unit testing doesn’t have to be complicated or intimidating. At its core, it’s simply about verifying that small pieces of your code work as expected and continue to work as your application evolves. By catching bugs early, unit tests help you write more reliable code, refactor with confidence, and reduce time spent debugging issues later.

For developers, especially those just getting started, the key is consistency rather than perfection. Start small, test the most critical logic, and gradually build a habit of writing tests alongside your code. Over time, unit tests become more than a safety net they act as living documentation that explains how your code is supposed to behave.

In the long run, investing in unit testing pays off. It leads to cleaner code, fewer production bugs, and a smoother development experience for both individuals and teams. Whether you’re working on a personal project or a large-scale application, unit testing is a skill that will make you a better, more confident developer.

shamitha
shamitha
Leave Comment
Share This Blog
Recent Posts
Get The Latest Updates

Subscribe To Our Newsletter

No spam, notifications only about our New Course updates.

Enroll Now
Enroll Now
Enquire Now