HP ALM结果附件和使用python的状态更新

问题描述 投票:0回答:1

挑战:将屏幕快照附加到TestLab中的Tests中,按照PASS / FAIL的步骤更新状态(当前更新通过状态已足够)

[我希望用python编写脚本,将测试结果附加到测试实验室中存在的测试用例,然后将每个测试步骤的预期结果设置为“预期”,并逐步传递TC。

即,在手动执行时,我们选择案例,单击运行,然后在预期输出区域中输入“按预期”并通过该步骤,然后针对测试用例的所有测试步骤执行此操作。这需要自动化。我有一个包含屏幕截图(类似于TC名称)的文件夹,因此脚本应上传屏幕截图并更新状态。

到目前为止我尝试过的:

我能够使用部分测试用例名称连接到alm,我能够从测试计划中提取完整的测试用例名称,但是不幸的是,我仍在努力实现最终目标。

到目前为止,我的代码:

import win32com
from win32com.client import Dispatch
import codecs
import re
import json

# Login Credentials
qcServer = "https://almurl.saas.microfocus.com/qcbin/"
qcUser = "my_username"
qcPassword = "pwd"
qcDomain = "domain"
testList = []

testdict = {}
project = "Crew_Management"
  # Do the actual login
td = win32com.client.Dispatch("TDApiOle80.TDConnection.1")
td.InitConnectionEx(qcServer)
td.Login(qcUser,qcPassword)
td.Connect(qcDomain,project)
if td.Connected == True:
    print ("System: Logged in to " +project)
else:
    print ("Connect failed to " +project)

mg = td.TreeManager  # Tree manager
name = ['TC001','TC002','TC003','TC003','TC004','TC005','TC006','TC007','TC008','TC009','TC010','TC011','TC012','TC013','TC014']
folder = mg.NodeByPath('Subject\\Test Factory\\MPG\\MPG Regression Test_Yearly Request\\GUI')
for x in name:
    testList = folder.FindTests(x)
    #print(type(testList))
    print(testList[0].Name)
    print(testList[0].DesStepsNum)

td.Disconnect()
td.Logout()

非常感谢任何帮助或指导!

python alm hp-alm
1个回答
0
投票
假设您具有Python的工作经验。在这里,我正在编写完成任务所需的所有不同功能。

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

全局变量

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

登录功能

def alm_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

注销功能

注销方法成功后,cookie应该过期

def alm_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

获取测试集文件夹

如果测试用例跨越多个测试套件,那么最好先获取测试集文件夹并找到必要的测试套件。

def find_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']

获取文件夹ID

此方法将帮助您找到测试套件文件夹ID或测试计划文件夹ID。

def find_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

创建运行实例

在更新测试状态之前,我们必须为测试创建一个运行实例。

def create_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

更新运行实例

def update_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"]: if len(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

上传结果文件

将文件上传到ALM中的任何对象

def upload_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) if not (response.status_code == 200 or response.status_code == 201): print "Attachment step failed!", response.text, response.url, response.status_code return

批量操作

这是一个允许我们发布数据数组的助手。

def bulk_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

© www.soinside.com 2019 - 2024. All rights reserved.