USD ($)
$
United States Dollar
Euro Member Countries
India Rupee
د.إ
United Arab Emirates dirham
ر.س
Saudi Arabia Riyal

Automated Testing in CI

Lesson 13/50 | Study Time: 40 Min

A CI pipeline without testing is just an automated way to ship broken code faster. Testing is what gives CI its value — every time code is pushed, the pipeline verifies it actually works before it moves any further. 

The Three Types of Automated Checks


Unit Tests

Unit tests check individual pieces of code in isolation — a single function, a single method, a single class. They are fast, focused, and tell you exactly which part of the code is broken.

Unit tests run in milliseconds. You should have many of them — they form the foundation of your test suite.


Integration Tests

Integration tests check that different parts of the system work correctly together — your application connecting to a database, an API calling another service, a Lambda function writing to S3.

Where unit tests test a single piece in isolation, integration tests test how pieces interact in a real or simulated environment.

Integration tests are slower than unit tests because they involve real connections and real data flows.

Linting

Linting is automated code quality checking. A linter reads your code and flags problems — syntax errors, formatting issues, unused variables, overly complex functions, security anti-patterns — before the code even runs.

Linting is not about style preference. It is about catching real problems early and keeping the codebase consistent across the whole team.

Running Tests Inside CodeBuild

All three checks — unit tests, integration tests, and linting — run inside the pre_build and build phases of your buildspec.yml.


yaml

version: 0.2


phases:

  install:

    runtime-versions:

      python: 3.11

    commands:

      - pip install -r requirements.txt

      - pip install pytest flake8


  pre_build:

    commands:

      - echo Running linter

      - flake8 src/ --max-line-length=100

      - echo Running unit tests

      - pytest tests/unit/ --verbose


  build:

    commands:

      - echo Running integration tests

      - pytest tests/integration/ --verbose

      - echo All tests passed. Building artifact.

      - zip -r app.zip src/


artifacts:

  files:

    - app.zip

If any command fails — linting finds an error, a test fails — CodeBuild stops immediately and marks the build as failed. CodePipeline then blocks the code from moving to the deploy stage.

Test Reports in CodeBuild

CodeBuild can generate visual test reports in the AWS Console, making it easy to see which tests passed and which failed without reading through logs.

yaml

reports:

  pytest-results:

    files:

      - test-results.xml

    file-format: JUNITXML


phases:

  pre_build:

    commands:

      - pytest tests/unit/ --junitxml=test-results.xml

```

Once configured, go to CodeBuild → your project → **Reports** to see a visual breakdown of every test run.


## 4. The Testing Pyramid

Not all tests are equal. The testing pyramid helps you understand how many of each type to write:

```

        /\

       /  \

      / E2E\        ← Few — slow and expensive

     /──────\

    /Integrat\      ← Some — moderate speed

   /──────────\

  / Unit Tests \    ← Many — fast and cheap

 /______________\


1. Write many unit tests — they are fast, cheap, and precise.

2. Write some integration tests — they catch real interaction bugs.

3. Write few end-to-end tests — they are slow and fragile but validate the full user journey.


Most of your CI pipeline speed comes from having a strong base of unit tests that run in seconds

Drew Collins

Drew Collins

Product Designer
Profile

Class Sessions

1- What is DevOps? Principles, Culture, and Practices 2- The DevOps Lifecycle 3- Introduction to Cloud Computing 4- AWS Global Infrastructure 5- Core AWS Services Overview 6- Git Fundamentals 7- Branching Strategies 8- Pull Requests and Code Review Best Practices 9- Integrating Git with AWS CodeCommit and GitHub 10- Managing Secrets and Sensitive Files in Repositories 11- What is CI/CD? 12- Building Pipelines with AWS CodePipeline and CodeBuild 13- Automated Testing in CI 14- Deployment Strategies 15- Using GitHub Actions and Jenkins on AWS 16- Why Infrastructure as Code (IaC)? 17- AWS CloudFormation 18- Terraform on AWS 19- AWS Cloud Development Kit (CDK) 20- IaC Best Practices 21- Docker Fundamentals 22- Amazon ECR 23- Deploying Containers with Amazon ECS 24- Kubernetes Basics and Amazon EKS 25- Integrating Containers into CI/CD Pipelines 26- Serverless Computing Concepts and Use Cases 27- Building and Deploying AWS Lambda Functions 28- Event-Driven Automation with Amazon EventBridge 29- Orchestrating Workflows with AWS Step Functions 30- API Gateway Integration for Serverless APIs 31- Introduction to MLOps 32- Training and Deploying Models with Amazon SageMaker 33- Automating ML Pipelines with SageMaker Pipelines 34- Using Amazon CodeWhisperer and AI Tools for Code Automation 35- AI-Powered Testing, Anomaly Detection, and Incident Prediction 36- Observability Fundamentals 37- Amazon CloudWatch 38- Distributed Tracing with AWS X-Ray 39- Centralised Logging with Amazon OpenSearch Service 40- Setting Up Automated Alerts and Incident Response Workflows 41- Shift-Left Security 42- IAM Roles, Policies, and Least-Privilege Access 43- Static Code Analysis and Vulnerability Scanning in CI/CD 44- AWS Security Hub, GuardDuty, and Config for Compliance 45- Secrets Management with AWS Secrets Manager and Parameter Store 46- AWS Well-Architected Framework 47- Auto Scaling and Elastic Load Balancing for Resilience 48- Cost Monitoring with AWS Cost Explorer and Budgets 49- Disaster Recovery Strategies 50- Preparing Your Project for Production