Testing in a CI/CD Pipeline Part 2: Integration testing
Why, how, when, where to perform testing in a CI/CD pipeline.

Search for a command to run...
Why, how, when, where to perform testing in a CI/CD pipeline.

No comments yet. Be the first to comment.
Tools are an essential part of developing good and consistent software. This is my attempt to help you out & shed some light on the tools that helped me because it's just an idea that all you need 💡.
Why, how, when, where to perform testing in a CI/CD pipeline.
Bringing in a fresh perspective on how you can turn your traditional streaming pipeline to perform like batch processing with endless possibilities

Uncover why SQL may not be the best choice for ETL pipelines in data applications and learn about common hurdles.

Turning Data Pipeline Failures into Success Stories: A Memory Optimization Case Study with Polars Library & Data Engineering best practices.

Practical techniques backed by benchmarks for working with Databases effectively in Python

Guide to Efficiently Streamlining Your Databricks Environment Setup

This is part 2 of the Testing in a CI/CD Pipeline series. It is advised to first go through it 🤓.
Integration testing is different from system or unit testing. Let's see in brief (as the original intent of this guide is how to integrate it CI/CD pipeline)
Why
How
When
Where
Let's go first through the testing script and then through the CI pipeline
with open('./tests/sample_data.json', 'r') as f:
payload = json.load(f)
header = {"Content-Type": "application/json"}
response = requests.request('POST', url, headers=header, json=payload)
response_data = response.json()
assert response_data['ida_output_path'].split('/')[-1] =='IDA.ndjson', 'Not Received expected output, test is failed.' # You may use some other method to compare 😁
try:
response = requests.request('POST', url, headers=header, json=payload)
response_data = response.json()
except:
logging.error('An error has occurred. Refer logs to locate error.')
os.system("docker logs test_api > output.log")
time.sleep(3)
with open('./output.log', 'r') as log:
print(log.read())
try:
assert response_data['ida_output_path'].split('/')[-1] =='IDA.ndjson', 'Not Received expected output, test is failed.'
except (AssertionError,KeyError) as e:
os.system("docker logs test_api > output.log")
time.sleep(3)
with open('./output.log', 'r') as log:
print(log.read())
try-catch block so that any error will not stop the code. subprocess.call(['docker', 'run', '-d', '-p' ,'80:80','--name', 'test_api', args.image_name])
ip = subprocess.getoutput("docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' test_api")
url = f'http://{ip}/api/IDA'
logger.info(f"Testing api @ {url}")
- task: PythonScript@0
displayName: Integration testing
inputs:
scriptSource: 'filePath'
scriptPath: '$(System.DefaultWorkingDirectory)/tests/integration_testing.py'
arguments: '--image_name your.repo.io/ida:$(Build.BuildNumber)'
os.sys.exit()
Img: Case- Passing of Integration test
Img: Case- Failing of Integration test.
import os
import json
import time
import logging
import argparse
import requests
import subprocess
logging.basicConfig(level=logging.INFO, format='[%(levelname)s]: %(message)s')
logger = logging.getLogger(__name__)
parser = argparse.ArgumentParser()
parser.add_argument('--image_name', type=str)
args = parser.parse_args()
# Run docker container at port 80
subprocess.call(['docker', 'run', '-d', '-p' ,'80:80','--name', 'test_api', args.image_name])
ip = subprocess.getoutput("docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' test_api")
url = f'http://{ip}/api/IDA'
logger.info(f"Testing api @ {url}")
with open('./tests/sample_data.json', 'r') as f:
payload = json.load(f)
header = {"Content-Type": "application/json"}
logger.info('Waiting for 30 sec to let docker container start')
time.sleep(30)
logger.info("Send API request for integration testing")
try:
response = requests.request('POST', url, headers=header, json=payload)
response_data = response.json()
except:
logging.error('An error has occurred. Refer logs to locate error.')
os.system("docker logs test_api > output.log")
time.sleep(3)
with open('./output.log', 'r') as log:
print(log.read())
os.sys.exit('Task terminated')
try:
assert response_data['ida_output_path'].split('/')[-1] =='IDA.ndjson', 'Not Received expected output, test is failed.'
except (AssertionError,KeyError) as e:
os.system("docker logs test_api > output.log")
time.sleep(3)
with open('./output.log', 'r') as log:
print(log.read())
logging.error(f'Problem with {e} Refer logs to locate error')
logging.error(f"Response from API: {response_data}")
os.sys.exit('Task terminated')
logger.info("Integration test passed successfully moving to next task")
trigger:
branches:
include:
- develop
paths:
exclude:
- Dockerfile_base
- requirements.txt
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
clean: true
fetchDepth: 1
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
addToPath: true
architecture: 'x64'
- task: CmdLine@2
displayName: Install python package
inputs:
script: 'python3 -m pip install requests azure-devops'
- task: PythonScript@0
displayName: Check build pipeline status
inputs:
scriptSource: 'filePath'
scriptPath: '$(System.DefaultWorkingDirectory)/tests/base_pipeline_status.py'
arguments: '--personal_access_token $(PERSONALACCESSTOKEN) --repo_id b978e55f-bf80-466c-86c8-fc0dfe909b2c --pipeline_def_id 179'
- task: Docker@0
displayName: 'Docker Build Image'
inputs:
azureSubscription: 'Your Subscripton'
azureContainerRegistry: 'Your container registery'
dockerFile: Dockerfile
buildArguments: |
ARG_STORAGEACCOUNTNAME=$(STORAGEACCOUNTNAME)
ARG_CONTAINERNAME=$(CONTAINERNAME)
ARG_STORAGEACCOUNTKEY=$(STORAGEACCOUNTKEY)
ARG_MAXWORKERS=$(MAXWORKERS)
imageName: 'ida:$(Build.BuildNumber)'
- task: PythonScript@0
displayName: Integration testing
inputs:
scriptSource: 'filePath'
scriptPath: '$(System.DefaultWorkingDirectory)/tests/integration_testing.py'
arguments: '--image_name your.repo.io/ida:$(Build.BuildNumber)'
- task: Docker@0
displayName: 'Push image to ACR'
inputs:
azureSubscription: 'Your Subscripton'
azureContainerRegistry: 'Your container registery'
action: 'Push an image'
imageName: 'ida:$(Build.BuildNumber)'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.SourcesDirectory)/kube'
ArtifactName: 'drop'
publishLocation: 'Container'