SDLC Automation · Topic 3 of 6

Automated Testing in Pipelines

Add unit, integration, load and security tests to CI/CD pipelines, gate promotion on results and roll back automatically when alarms fire after deployment.

  • 5 min
In a nutshell
  • A non zero exit code from a command fails the CodeBuild action and stops the pipeline.
  • CodeBuild reports store JUnit and similar results for trend history.
  • Use the CodePipeline Test category for CodeBuild test runs and Device Farm for device and browser tests.

What it is

Automated testing in a pipeline means every change is checked by code, not by a person, before it can reach production. Tests run at several points: before the build finishes, after a deploy to a test environment, and after the release to production.

The aim is fast feedback and a safe gate. A failed test stops the pipeline, so a bad change never reaches the next stage.

Commitcodefast testsBuildunit tests and scandeployStagingintegration and load testsgateProductioncanary and alarms

How it works

The test layers

Put cheap, fast tests first and expensive ones later. This is the idea behind the test pyramid.

LayerWhere it runsTypical tool
Static analysis and lintingBuild stageCodeBuild commands, cfn-lint
Unit testsBuild stageTest framework in CodeBuild
Dependency and secrets scanningBuild stageThird party scanners, Amazon Inspector for images
Integration testsAfter deploy to testCodeBuild test action, Lambda invoke action
Load and performance testsStagingLoad tool run from CodeBuild
UI and device testsStagingAWS Device Farm
Smoke and synthetic testsAfter production deployCloudWatch Synthetics canaries

CodeBuild as the test runner

In CodePipeline a CodeBuild action can sit in the Build category or the Test category. If a command returns a non zero exit code the build fails, and the stage and the pipeline stop. Test result files are published as reports, so you can see trends even when the build passes.

version: 0.2
phases:
  build:
    commands:
      - pytest --junitxml=report.xml
reports:
  pytest-results:
    files:
      - report.xml
    file-format: JUNITXML

Running tests on pull requests and merges

Validate a change before it merges, not only after. Three common triggers exist.

TriggerHow
CodeBuild webhookFor GitHub, GitHub Enterprise and Bitbucket sources. Filter groups match the event type (PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED, PULL_REQUEST_MERGED, PUSH) and can match the target branch
CodePipeline V2 triggerA V2 pipeline can start on pull request events, with branch filters, for a connection based source
EventBridge ruleMatches a CodeCommit "Pull Request State Change" event (created or source branch updated) and starts a CodeBuild project
aws codebuild create-webhook --project-name app-tests \
  --filter-groups '[[{"type":"EVENT","pattern":"PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED"},{"type":"BASE_REF","pattern":"^refs/heads/main$"}]]'

Report the result back to the pull request so reviewers see it. With a webhook, CodeBuild posts the build status to the source provider. With CodeCommit, a Lambda function or the build itself can add a comment to the pull request or update its approval state.

Exam tip

Use a merge trigger (for example PUSH on the main branch) for the full pipeline, and a lighter pull request trigger for fast unit tests only.

Testing after a deploy

An integration test needs a running environment. The usual pattern is to deploy to a test stack, run a CodeBuild action against its endpoint, and then tear the stack down or keep it for the next run.

DeployCloudFormation test stackoutputsTestCodeBuild calls endpointpassNextapproval or prod

A Lambda function in an Invoke action suits small custom checks, such as calling a health URL and reporting success or failure back to the pipeline.

Testing inside the deployment

CodeDeploy can run tests as part of the deploy itself.

  • On EC2, the ValidateService hook runs a script after the application starts and can fail the deployment.
  • For Lambda and ECS, the traffic hooks (BeforeAllowTraffic and AfterAllowTraffic, plus AfterAllowTestTraffic for ECS) call a Lambda function that tests the new version.
  • CodeDeploy can watch CloudWatch alarms during a deployment and stop and roll back when one enters the ALARM state.

This turns production monitoring into the last test: a canary release sends a small share of traffic to the new version while alarms judge its health.

Security testing

Shift security checks left, which means running them early in the pipeline.

  • Scan source and dependencies in the build for known vulnerable packages and committed secrets.
  • Scan container images in Amazon ECR, using either the basic scan or Amazon Inspector enhanced scanning.
  • Validate infrastructure templates before deploy with tools such as cfn-lint and CloudFormation Guard.
  • Use AWS CloudFormation Hooks to block noncompliant resources at deploy time.

Gates and approvals

A gate can be automatic (tests must pass, alarms must be clear) or manual (an approval action). Use automatic gates for repeatable rules and manual approval where a business decision is needed. Many teams use a manual approval only for the production step.

Test data and isolation

Tests should not depend on shared long lived state. Give each pipeline run its own test stack or its own data prefix, and use short lived credentials from the pipeline role.

What to remember for the exam

  • A non zero exit code from a command fails the CodeBuild action and stops the pipeline.
  • CodeBuild reports store JUnit and similar results for trend history.
  • Use the CodePipeline Test category for CodeBuild test runs and Device Farm for device and browser tests.
  • CodeDeploy hooks and CloudWatch alarms provide validation and automatic rollback.
  • Amazon Inspector scans ECR images and also Lambda functions and EC2 instances.
  • CloudWatch Synthetics canaries test an endpoint continuously after release.
  • Put fast tests early and slow tests later to fail fast.
  • A Lambda invoke action runs custom test logic and reports back to the pipeline.
Exam tip

When a question asks for the least operational effort to stop a bad deployment automatically, choose CodeDeploy alarm based rollback over a custom monitoring script.

Common mistakes

Testing only in production. Waiting for users to find defects defeats the pipeline.

Running every test in one stage. Slow integration tests then delay feedback from quick unit tests.

Treating a manual approval as testing. A human click does not prove the change works.

Sharing one test environment. Parallel pipeline runs overwrite each other's data and give flaky results.

Watch out

Tests that call production data stores or use production credentials can cause the very incident the pipeline is meant to prevent.

Check yourself

  • Where do you put a fast unit test and where a slow load test?

    Unit tests go in the build stage for quick feedback, and load tests run later against a staging deployment.

  • How can a deployment roll back without human action?

    CodeDeploy watches CloudWatch alarms and rolls back automatically if one goes into ALARM.

  • Which service tests a web application on real browsers and devices?

    AWS Device Farm, used as a Test action in CodePipeline.

Topic 3 of 6 in SDLC Automation

Test yourself on SDLC Automation

The full AWS DOP-C02 question bank has 844 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by AWS. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.