Skip to content

Instantly share code, notes, and snippets.

@yyahav
Last active May 7, 2023 16:03
Show Gist options
  • Save yyahav/c5f7791bd3bb9ec9148ebbdf9aeb5914 to your computer and use it in GitHub Desktop.
Save yyahav/c5f7791bd3bb9ec9148ebbdf9aeb5914 to your computer and use it in GitHub Desktop.
Script to prepare JUnit XML files for Zephyr Scale, package them into a ZIP file, and upload to Zephyr API
# Zephyr Scale upload script
# Author: yyahav // Date: May 4th 2023
# ------------------------------------
# When uploading a zip file containing JUnit xml reports, trying to auto create testcases will create the test cases based on their FQCN including the package (e.g. com.automate.tests.really.long.annoying.TestClass.testMethod).
# Usually this is not convenient or easy on the eyes. So this script is meant to be run after a 'test' build task, editing the xml files to remove the package and keep only the method (test) names for the created test case.
# After editing the xml files, they are archived into a zip file, which is then uploaded to Zephyr Scale API using the supplied Bearer token.
# To create a token if you don't have one - https://support.smartbear.com/zephyr-scale-cloud/docs/rest-api/generating-api-access-tokens.html
import argparse
import os
import re
import shutil
import json
import importlib
import ensurepip
import tempfile
# Check if the 'requests' package is installed
try:
requests = importlib.import_module('requests')
except ImportError:
# If not, run ensurepip to verify pip exists and install the 'requests' package using pip
ensurepip.bootstrap(upgrade=True)
import subprocess
subprocess.check_call(["pip3", "install", "requests"])
requests = importlib.import_module('requests')
parser = argparse.ArgumentParser(description='Script to prepare JUnit XML files for Zephyr Scale, package them into a ZIP file, and upload to Zephyr API')
parser.add_argument('-f', '--filename', required=True, help='Name of the zip file to be created and uploaded to Zephyr Scale')
parser.add_argument('-p', '--project', required=True, help='The project key in Jira (e.g. DEV)')
parser.add_argument('-c', '--testcycle', required=True, help='Name of the test cycle to appear in Zephyr Test Cycles')
parser.add_argument('-t', '--token', required=True, help='The Zephyr API Token used for authorization. If you don\'t have one see: https://support.smartbear.com/zephyr-scale-cloud/docs/rest-api/generating-api-access-tokens.html')
parser.add_argument('-a', '--auto', default='FALSE', help='Auto create test cases if they do not exist (default FALSE)')
args = parser.parse_args()
# Define input and output directories
xmlDir = 'build/test-results/test'
zipDir = 'build/test-results/test/zephyr'
# Clean the Zephyr directory if exists and create a new one
print('Preparing directory')
if os.path.exists(zipDir):
shutil.rmtree(zipDir)
os.makedirs(zipDir, exist_ok=True)
# Loop through the JUnit XML files in the test-results directory
print('Editing xml files')
for filename in os.listdir(xmlDir):
if filename.endswith('.xml'):
# Read contents of the file
with open(os.path.join(xmlDir, filename), 'r') as file:
contents = file.read()
# Replace pattern with replacement string
replaced_contents = re.sub(r'classname=\".*\" ', 'classname="" ', contents)
#replaced_contents = replaced_contents.replace('()', '')
# Write new contents to output file
with open(os.path.join(zipDir, filename), 'w') as file:
file.write(replaced_contents)
# Create a zip file for Zephyr API and move it to the results directory
print('Creating zip')
tempZip = os.path.join(tempfile.gettempdir(), args.filename)
shutil.make_archive(os.path.splitext(tempZip)[0], 'zip', zipDir)
shutil.move(tempZip, zipDir)
zipFile = os.path.join(zipDir, args.filename)
# Set up Zephyr API endpoint and data
apiUrl = f'https://api.zephyrscale.smartbear.com/v2/automations/executions/junit?projectKey={args.project}&autoCreateTestCases={args.auto}'
headers = {'Authorization': f'Bearer {args.token}'}
requestBody = {
"testCycle": (None, json.dumps({'name': f'{args.testcycle}'}), "application/json"),
"file": (args.filename, open(zipFile, "rb"))
}
# POST the data to Zephyr API
print('Uploading to Zephyr')
response = requests.post(apiUrl, headers=headers, files=requestBody)
# Check the response status code
if response.status_code == requests.codes.ok:
print('Upload successful')
print(response.text)
else:
print(f'Upload failed with status code {response.status_code}')
print(response.text)
exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment