Source code for taf.plugins.pytest_helpers

# Copyright (c) 2011 - 2017, Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""``pytest_helpers.py``

`pytest specific helpers functions`

"""

import inspect
import re

from testlib import loggers

class_logger = loggers.ClassLogger()


[docs]def get_tcname(report): """Return TC name from pytest report object. Args: report(pytest.report): pytest report object Returns: str: test case name Note: This function allows to get proper name without parameters string from normal and parametrized TCs. """ name = None full_name = report.nodeid.split("::")[-1] # split on first left bracket split = full_name.split('[', 1) # this works even if we have no left bracket before_bracket = split[0] try: after_bracket = split[1].rstrip(']') # normal paremetrize adds all args after id using '-' to separate params_list = after_bracket.split("-") # valid ids must start with "test_" # use list so we get IndexError name_from_param_otherwise_full_name = [x for x in params_list if "test_" in x][0] except IndexError: # this will occur if there are no dashes, or if we can't find test_ name_from_param_otherwise_full_name = before_bracket if "unittests" in report.keywords: # only use full full name if unittest name = full_name else: # if we are parametrized or web_ui just use the name from inside the brackets # # metafunc will hide a 'parametrize' mark from the report.keywords so we get here # and randomly pick the first arg. But this fails because # metafunc on top of parametrize prepends its argvalue # # don't just randomly pick the first argvalue use the name from param name = name_from_param_otherwise_full_name return name
[docs]def get_suite_name(nodeid): """Return suitename from nodeid string. Args: nodeid(str): pytest.Item nodeid string Returns: str: test suite name """ names = nodeid.split("::") names[0] = names[0].replace("/", '.') names = [x.replace(".py", "") for x in names if x != "()"] classnames = names[:-1] return ".".join(classnames)
[docs]def get_test_keys(data): """Return case keys from report string. Args: data(str): test case results Returns: list[str]: list of report keys """ keys_rules = re.compile('<success>(.*?)</success>') return keys_rules.findall(data)
[docs]def get_steps(item, tc_name): """Parse and return test steps. Args: item(pytest.Item): pytest test case item tc_name(str): test case name Returns: str: test case's steps """ # Get source of test function steps_list = [] steps_rules = re.compile(r'Steps\:\:\n\n([\s\S]*?)\n\n') step_rules = re.compile(r'Steps\:\:\n\n(.*?)\n\n') data = get_doc_from_item(item) # Split and strip steps from docstring for line in steps_rules.findall(data): steps_list.extend((x.strip() for x in line.splitlines() if x.strip())) steps_list.extend((x.strip() for x in step_rules.findall(data) if x)) # join on empty list returns '' return '\n'.join(steps_list)
[docs]def get_doc_from_item(item): data = '' try: data = item.funcargs['doc'][0] except KeyError: try: data = item.funcargs['doc_string'][0] except KeyError: try: data = item.callspec.params["doc"][0] except (AttributeError, KeyError): data = inspect.getsource(item.function) return data
[docs]def get_brief(item, tc_name): """Parse doc-string and return brief. Args: item(pytest.Item): pytest test case item tc_name(str): test case name Returns: str: test case docstring's brief """ brief = '' data = get_doc_from_item(item) # try to find if inner function existent brief_rules = re.compile(r'\"\"\"(.+)\n\n') brief_list = brief_rules.findall(str(data)) if not brief_list: # try to find if inner function non-existent brief_rules = re.compile(r'^(.+)\n\nSteps') brief_list = brief_rules.findall(str(data)) try: if not brief_list: brief = str(data)[:] else: brief = ('\n'.join(brief_list)) return brief.strip()[:255] except IndexError: return ""
[docs]def get_failure_reason(data): """Return test case failure reason from report string. Args: data(str): test case report Returns: str: failure reason or None """ try: reason_rules = re.compile('\nE (.*)') return ('\n'.join(reason_rules.findall(data))).strip() except TypeError: return None
[docs]def get_skipped_reason(data): """Return test case skip reason from report string. Args: data(str): test case report Returns: str: skip reason or None """ try: reason_rules = re.compile("Skipped:(.*?)..$") return ('\n'.join(reason_rules.findall(data))).strip() except TypeError: return None
[docs]def get_html_xml_path(path, build_name): """Parse and replace $BUILD_NAME variable in the path. Args: path(str): path to html report build_name(str): software build number Returns: str: modified path to html report """ try: return path.replace("__BUILD_NAME__", build_name) except AttributeError: return "undetermined"