def set_step_results(self, description: str, status: str, comment: str): """ Finds step by name and set step execution result :param description: step name :param status: step execution ststus :param comment: execution comment """ try: f_step = next( (step for step in self.steps if step['description'] == description), None) f_step_index = self.steps.index(f_step) self.results.append({ 'index': f_step_index, 'status': status, 'comment': comment }) except ValueError: if self.__config['NOTFOUND']['createStep'] == 'True': self.append_step(description, '', '') f_step_index = len(self.steps) - 1 self.results.append({ 'index': f_step_index, 'status': status, 'comment': comment }) else: raise TM4JObjectNotFound( f'find_testcase: teststep {description} not found and auto-create is turned off' )
def get_datarow_ids(self, run_id: str) -> dict: """ Function to get list of parameterset ids (datarow ids) - in order to post DD executions :param run_id: testcase run id. :return: dict of row id of the last (current) executions """ url = f'{self._serviceurl}/testrun/{self._tr_internal_id}/testresults?fields=id,testResultStatusId,' \ f'testScriptResults(id,testResultStatusId,comment,index,sourceScriptType,parameterSetId),' \ f'traceLinks&itemId={run_id}' last_execution = self._do('get', url, '') if last_execution: result = dict() for item in last_execution[0]['testScriptResults']: parameterset_id = item.get('parameterSetId', None) # parameterSetId = row x in test data table, so it should exists if parameterset_id: step_ids_list = result.get(parameterset_id, None) if step_ids_list: step_ids_list.append(item['id']) else: result.update({parameterset_id: [item['id']]}) if len(result) == 0: raise TM4JObjectNotFound(f'No data table rows found for run_id {run_id}') return result else: raise TM4JInvalidValue(f'No last execution found for run_id {run_id}')
def find_testcase(self, name: str = None, key: str = None, folder: str = None, test_source_file_path: str = '', autocreate: bool = False) -> str: """Search method for test run or test cases. If no result found, new item is created. Found testcase is stored in self parameter. :param name: name of the item to search :param key: if specified, search by key only, name is ignored :param folder: if specified, search in folder; if no item found, it will be created in this folder. Folder should be specified in "parent folder" or "parent folder/child folder" format :param test_source_file_path: test source path for csv logger :param autocreate: option to override tests autocreation """ autocreate = autocreate or is_true(self.config['NOTFOUND']['createTestcase']) self.logger.debug(f"Find testcase with params: {locals()}") url_options = list() url_options.append(f'{self._baseurl}/testcase/search?version=1.0&maxResults=10&query=') if key: url_options.append(f' key = "{key}"') else: name = clear_name(name) if name == '': raise TM4JInvalidValue('Testcase name cannot be empty!') n_key, n_name = split_testcase_name_key(name, self.config['GENERAL']['testCaseKeyDelimiter']) # check if name starts with testCase key -- then find by key if n_key: self.find_testcase(n_name, n_key, folder, test_source_file_path) return self.testcase['key'] else: folder = choose(folder, folder, self.config['GENERAL']['tcFolder']) check_folder_name(folder) url_options.append(f' projectKey = "{self.project_key}" AND name = "{name}"') url_options.append(choose(folder, f" AND folder = \"/{folder}\"", '')) url = ''.join(url_options) payload = '' try: response = self._do('get', url, payload, False, True) self.testcase = response[0] self._get_tc_id() except IndexError: if autocreate and name: self.logger.info(f'Cannot find testcase {key} - {name}. Will create a new one') self._post_new_testcase(name, folder, test_source_file_path) else: msg = f'find_testcase: testcase {key} not found. '\ f'Name=\"{name}\" or autocreate={autocreate} do not allow creation' self.logger.exception(msg) raise TM4JObjectNotFound(msg) except TM4JFolderNotFound: self._create_folder('TEST_CASE', folder) self._post_new_testcase(name, folder, test_source_file_path) return self.testcase['key']
def _get_testcase_run_id(self, key: str) -> tuple: """ Function to get internal run id for testcase added into testcycle :param key: testcase key :return: """ self._get_tr_id() url = f'{self._serviceurl}/testrun/{self._tr_internal_id}/testrunitems' \ f'?fields=id,index,issueCount,$lastTestResult' response = self._do('get', url, '') for item in response: if item['$lastTestResult']['testCase']['key'] == key: return item['id'], item['$lastTestResult']['id'] raise TM4JObjectNotFound( f'Cannot find {key} run id in testrun {self._tr_internal_id}')
def _create_folder(self, folder_type: str, name: str): """function creates folder of specified type""" self.logger.info(f'Creating new {folder_type} folder {name}') url = f'{self._baseurl}/folder' if (is_true(self.config['NOTFOUND']['createTcFolder']) and folder_type == 'TEST_CASE') \ or (is_true(self.config['NOTFOUND']['createTrFolder']) and folder_type == 'TEST_RUN'): folder = { "projectKey": self.project_key, "name": f'/{name}', "type": folder_type } self._do('post', url, payload=strip_none_values(folder)) else: raise TM4JObjectNotFound( f'find_testcase/testrun: {folder_type} folder "{name}" is not found and auto-create is turned off' )
def _post_new_testcycle(self, name: str, folder: str = None, linked_issues: str = None, check_config: bool = False, executor: str = None): """ Creates new testcycle. Created testcycle is stored in self.testrun parameter :param name: testcycle name :param folder: testcycle folder. If None, config folder will be used :param linked_issues: linked Jira issues list :param check_config: is passed from find_testcycle method to check if :param executor: name of the testcycle owner auto creation of not-found is allowed """ self.logger.info(f"Post testrun with params: {locals()}") if self.config['NOTFOUND']['createTestrun'] != 'True' and check_config: raise TM4JObjectNotFound( f'find_testcycle: TestCycle {name} not found and auto-create is turned off' ) else: url = f'{self._baseurl}/testrun' key = None folder = choose(folder, folder, self.config['GENERAL']['trFolder']) check_folder_name(folder) self._init_testrun() self.testrun['name'] = name self.testrun['owner'] = executor self.testrun['folder'] = f"/{folder}" try: key = self._do('post', url, payload=strip_none_values(self.testrun))['key'] except TM4JFolderNotFound: self._create_folder('TEST_RUN', folder) key = self._do('post', url, payload=strip_none_values(self.testrun))['key'] finally: self.testrun = self._do('get', url + '/' + key, '') if linked_issues: self._add_testcycle_jira_link(linked_issues) self.logger.info(f"Testrun {key} created successfully.") return key
def _check_error_response(response: Response): """function checks for Folder errors""" text = f'Status {response.status_code} for URL {response.url}. Details: "{response.text}. ' \ f'Request: {response.request.body}"' if response.status_code == 400: if bool(re.search(r".+not found for field folder.+", response.text)): raise TM4JFolderNotFound(f'{text}') if bool( re.search(r".+folder should start with a slash.+", response.text)): raise TM4JInvalidFolderName(f'{text}') if bool( re.search(r".+was not found for field environment on project+", response.text)): raise TM4JEnvironmentNotFound(f'{text}') if bool(re.search(r".+was not found for field+", response.text)): raise TM4JInvalidValue(f'{text}') elif response.status_code == 404: raise TM4JObjectNotFound(f'{text}') elif response.status_code == 500: raise TM4JException(f'{text}')