Skip to content Skip to sidebar Skip to footer

Hp Alm Results Attachment And Status Update Using Python

Challenge : Attach screenshots to Tests in TestLab , update status as PASS/FAIL steps wise (currently updating pass status is enough) I am expected to write a script in python , to

Solution 1:

Assuming that you have working experience in Python. Here I am writing all the different functions needed to complete your task.

Reference:https://admhelp.microfocus.com/alm/api_refs/REST_TECH_PREVIEW/ALM_REST_API_TP.html

Global Variable

import re
import json
import datetime
import time
import sys
import os, fnmatch
from os import listdir
from os.path import isfile, join
from xml.etree.ElementTree import Element, SubElement, tostring, parse
import glob
from requests.auth import HTTPBasicAuth
import requests

ALM_USER_NAME = ""
ALM_PASSWORD = ""
ALM_DOMAIN = ""
ALM_URL = ""
AUTH_END_POINT = ALM_URL + "authentication-point/authenticate"
QC_SESSION_END_POINT = ALM_URL + "rest/site-session"
QC_LOGOUT_END_POINT = ALM_URL + "authentication-point/logout"
ALM_MIDPOINT = "rest/domains/" + ALM_DOMAIN + "/projects/"
PATH_SEP = os.path.sep

Login Function

defalm_login(self):
        """
            Function    :   alm_login
            Description :   Authenticate user
            Parameters  :   global parameter
                            alm_username     -   ALM User
                            alm_password     -   ALM Password
        """
        response = self.alm_session.post(AUTH_END_POINT,
                                         auth=HTTPBasicAuth(ALM_USER_NAME, ALM_PASSWORD))
        if response.status_code == 200:
            response = self.alm_session.post(QC_SESSION_END_POINT)
            if response.status_code == 200 | response.status_code == 201:
                print"ALM Authentication successful"else:
                print"Error: ", response.staus_code
        else:
            print"Error: ", response.staus_code
        self.alm_session.headers.update({'Accept':'application/json',
                                         'Content-Type': 'application/xml'})
        return

Logout Function

After the logout method is successful the cookie should expire

defalm_logout(self):
        '''
            Function    :   alm_logout
            Description :   terminate user session
            Parameters  :   No Parameters
        '''
        response = self.alm_session.post(QC_LOGOUT_END_POINT)
        print"Logout successful", response.headers.get('Expires'), response.status_code
        return

Get Test Set Folder

If the test cases span across multiple test suites then it is better to get the test set folder first and find the necessary test suite.

deffind_test_set_folder(self):
        '''
            Function    :   find_test_set_folder
            Description :   This sends a couple of http request and authenticate the user
            Parameters  :   1 Parameter
                            test_set_path    -   ALM test set path
        '''
        json_str = json.loads(self.find_folder_id(self.test_set_path.split("\\"), "test-set-folders"
                                                  , 0, "id"))
        if'entities'in json_str:
            return create_key_value(json_str['entities'][0]['Fields'])['id']
        else:
            return create_key_value(json_str['Fields'])['id']

Get Folder Id

This method will help you find the Test Suite Folder ID or Test Plan Folder Id.

deffind_folder_id(self, arrfolder, str_api, parent_id, fields):
        '''
            Function    :   find_folder_id
            Description :   This sends a couple of http request and authenticate the user
            Parameters  :   1 Parameter
                            test_set_path    -   ALM test set path
        '''for foldername in arrfolder:
            payload = {"query": "{name['" + foldername + "'];parent-id[" + str(parent_id) + "]}",
                       "fields": fields}
            response = self.alm_session.get(ALM_URL + ALM_MIDPOINT + "/" + str_api, params=payload)
            obj = json.loads(response.text)
            if obj["TotalResults"] >= 1:
                parent_id = get_field_value(obj['entities'][0]['Fields'], "id")
                # print("folder id of " + foldername + " is " + str(parent_id))else:
                # print("Folder " + foldername + " does not exists")
                inputdata = dict()
                inputdata['Type'] = str_api[0:len(str_api) - 1]
                inputdata['name'] = foldername
                inputdata['parent-id'] = str(parent_id)
                data = generate_xml_data(inputdata)
                response = self.alm_session.post(ALM_URL + ALM_MIDPOINT + "/" + str_api, data=data)
                obj = json.loads(response.text)
                if response.status_code == 200 | response.status_code == 201:
                    parent_id = get_field_value(obj['Fields'], "id")
                    # print("folder id of " + foldername + " is " + str(parent_id))return response.text

Create Run Instance

Before updating the testing status, we must create a run instance for the test.

defcreate_run_instance(self, test_set_id, test_map):
        '''
            Function    :   create_run_instance
            Description :   Create new run instances
            Parameters  :   Test Set Id
        '''
        str_api = "test-instances"
        fields = "id,test-id,test-config-id,cycle-id"
        payload = {"query": "{cycle-id['" + test_set_id + "']}", "fields": fields,
                   "page-size": 5000}
        response = self.alm_session.get(ALM_URL + ALM_MIDPOINT + "/" + str_api, params=payload)
        obj = json.loads(response.text)

        run_instance_post = "<Entities>"for entity in obj["entities"]:
            run_name = re.sub('[-:]', '_',
                              'automation_' + datetime.datetime.fromtimestamp(time.time()).strftime(
                                  '%Y-%m-%d %H:%M:%S'))
            temp_map = create_key_value(entity["Fields"])
            _test_id = int(temp_map['test-id'])
            self.parser_temp_dic[_test_id]['testcycl-id'] = temp_map['id']
            self.parser_temp_dic[_test_id]['test-config-id'] = temp_map['test-config-id']
            self.parser_temp_dic[_test_id]['test-id'] = temp_map['test-id']
            self.parser_temp_dic[_test_id]['cycle-id'] = temp_map['cycle-id']
            # parser_temp_dic[int(temp_map['test-id'])]['status'].sort()
            status = "Passed"if'Failed'in self.parser_temp_dic[int(temp_map['test-id'])]['status']:
                status = 'Failed'
            self.parser_temp_dic[int(temp_map['test-id'])]['final-status'] = status

            inputdata = dict()
            inputdata['Type'] = 'run'
            inputdata['name'] = run_name
            inputdata['owner'] = ALM_USER_NAME
            inputdata['test-instance'] = str(1)
            inputdata['testcycl-id'] = str(temp_map['id'])
            inputdata['cycle-id'] = str(temp_map['cycle-id'])
            inputdata['status'] = 'Not Completed'
            inputdata['test-id'] = temp_map['test-id']
            inputdata['subtype-id'] = 'hp.qc.run.MANUAL'
            data = generate_xml_data(inputdata)
            run_instance_post = run_instance_post + data

        self.bulk_operation("runs", run_instance_post + "</Entities>", True, "POST")
        return

Update Run Instance

defupdate_run_instance(self, test_set_id):
        '''
            Function    :   update_run_instance
            Description :   Update the test status in run instances
            Parameters  :   No input parameter
        '''
        fields = "id,test-id"
        payload = {"query": "{cycle-id['" + test_set_id + "']}", "fields": fields,
                   "page-size": 5000}
        response = self.alm_session.get(ALM_URL + ALM_MIDPOINT + "/runs", params=payload)
        obj = json.loads(response.text)

        run_instance_put = "<Entities>"for entity in obj["entities"]:
            iflen(entity["Fields"]) != 1:
                temp_map = create_key_value(entity["Fields"])
                self.parser_temp_dic[int(temp_map['test-id'])]['run-id'] = temp_map['id']
                inputdata = dict()
                inputdata['Type'] = 'run'
                inputdata['id'] = str(temp_map['id'])
                intermediate_ = self.parser_temp_dic[int(temp_map['test-id'])]['testcycl-id']
                inputdata['testcycl-id'] = str(intermediate_)
                inputdata['status'] = self.parser_temp_dic[int(temp_map['test-id'])]['final-status']
                data = generate_xml_data(inputdata)
                run_instance_put = run_instance_put + data

        self.bulk_operation("runs", run_instance_put + "</Entities>", True, "PUT")
        return

Upload Result File

Uploading file to any object in ALM

defupload_result_file(self, test_set_id, report_file):
        '''
            Function    :   upload_result_file
            Description :   Upload test result to ALM
        '''
        payload = open(report_file, 'rb')
        headers = {}
        headers['Content-Type'] = "application/octet-stream"
        headers['slug'] = "test-results" + report_file[report_file.rfind(".")+1: ]
        response = self.alm_session.post(ALM_URL + ALM_MIDPOINT + "/test-sets/" +
                                         str(test_set_id) + "/attachments/",
                                         headers=headers, data=payload)
        ifnot (response.status_code == 200or response.status_code == 201):
            print"Attachment step failed!", response.text, response.url, response.status_code
        return

Bulk Operation

This is a helper that allows us to POST an array of data.

defbulk_operation(self, str_api, data, isbulk, request_type):
        '''
            Function    :   Post Test Case / Test Instance
            Description :   Generic function to post multiple entities.
            Parameters  :   3 parameters
                            str_api          -   End point name
                            data             -   Actual data to post
                            isbulk           -   True or False
        '''
        response = None
        headers = {}
        try:
            if isbulk:
                headers['Content-Type'] = "application/xml;type = collection"if request_type == 'POST':
                response = self.alm_session.post(ALM_URL + ALM_MIDPOINT + "/" + str_api, data=data,
                                                 headers=headers)
            elif request_type == 'PUT':
                response = self.alm_session.put(ALM_URL + ALM_MIDPOINT + "/" + str_api, data=data,
                                                headers=headers)
        except Exception as err:
            print err
        if response.status_code == 200 | response.status_code == 201:
            return response.text
        return response

Solution 2:

You can refer this code https://github.com/arunprabusamy/Python-Libraries/blob/main/alm_RestAPI/almLib.py

You need to send only three values - Test Set ID (Cycle ID), ALM Test ID & Execution Status. The library automatically builds the json payload and creates a test run and update result.

Post a Comment for "Hp Alm Results Attachment And Status Update Using Python"