Commit a579aead authored by lopezaguilar's avatar lopezaguilar
Browse files

Update keywords generation and update robotframework-tidy package

parent 0da19e39
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ Robot Framework. Our recommendations are:
- Install [Robot Framework Language Server](https://plugins.jetbrains.com/plugin/16086-robot-framework-language-server)

- Define as variable the path of the working directory. In Settings > Languages & Frameworks > Robot Framework 
(Project), insert the following: `{"EXECDIR": "{path}/auth-test-suite"}`.
(Project), insert the following: `{"EXECDIR": "{path}/ngsi-ld-test-suite"}`.


### Run configurations (PyCharm)
+28 −21
Original line number Diff line number Diff line
from os.path import dirname
from robot.api import TestSuiteBuilder
from analysis.parserobotfile import ParseRobotFile
from analysis.parseapiutilsfile import ParseApiUtilsFile
from analysis.parsevariablesfile import ParseVariablesFile
from analysis.initial_setup import InitialSetup
from doc.analysis.parserobotfile import ParseRobotFile
from doc.analysis.parseapiutilsfile import ParseApiUtilsFile
from doc.analysis.parsevariablesfile import ParseVariablesFile
from doc.analysis.initial_setup import InitialSetup
from re import match, findall, finditer, sub, MULTILINE


@@ -102,7 +102,6 @@ class GenerateRobotData:

        self.initial_setup = InitialSetup()


    def get_info(self):
        self.test_suite['robotpath'] = (self.robot_file.replace(f'{self.execdir}/TP/NGSI-LD/', '')
                                        .replace(f'/{self.robot.test_suite}.robot', ''))
@@ -131,7 +130,8 @@ class GenerateRobotData:
            print(f'Something went wrong, the test suite {self.suite.resource.source} '
                  f'has different "setup" values for its test cases.')

    def get_permutation_keys(self, data):
    @staticmethod
    def get_permutation_keys(data):
        all_keys = set().union(*data)
        excluded_keys = ['doc', 'permutation_tp_id', 'setup', 'teardown', 'name', 'tags']
        all_keys = [x for x in all_keys if x not in excluded_keys]
@@ -154,7 +154,7 @@ class GenerateRobotData:

    def get_params(self, test_case: str):
        test_case = self.get_data_template(string=test_case)
        lines_starting_response = findall(r'^\s*\$\{response\}.*|^\s*\$\{notification\}.*', test_case, MULTILINE)
        lines_starting_response = findall(r'^\s*\$\{response}.*|^\s*\$\{notification}.*', test_case, MULTILINE)

        # If there is more than one line, it means that the test case has several operations, all of them to
        # create the environment content to execute the last one, which is the correct one to test the Test Case
@@ -171,7 +171,7 @@ class GenerateRobotData:
        aux = [x for x in aux if x != '']

        params = list()
        request = str()
        request = list()

        # Get the list of params of the function, they are the keys
        if '    ...    ' in aux[1]:
@@ -181,7 +181,7 @@ class GenerateRobotData:
            # We are in the case that the attributes are in following lines
            for i in range(1, len(aux)):
                if '    ...    ' in aux[i]:
                    regex = '(\s{4})*\s{4}\.{3}\s{4}(.*)'
                    regex = r'(\s{4})*\s{4}\.{3}\s{4}(.*)'
                    param = match(pattern=regex, string=aux[i])
                    if aux:
                        params.append(param.groups()[1])
@@ -193,8 +193,8 @@ class GenerateRobotData:
            matches = finditer(regex, response_to_check, MULTILINE)
            request = aux[0].split('    ')[2]

            # We have two options from here, or the parameters are defined in the same line or the parameters are defined in
            # following lines, next lines
            # We have two options from here, or the parameters are defined in the same line or the parameters are
            # defined in following lines, next lines
            for a_match in matches:
                # Check that we have 1 group matched
                if len(a_match.groups()) == 1:
@@ -215,6 +215,9 @@ class GenerateRobotData:

        request, params = self.get_params(test_case=string)

        verb = str()
        query_param = str()
        url = str()
        for data in self.apiutils:
            verb, url, query_param = data.get_response(keyword=request)
            if verb != '':
@@ -245,6 +248,7 @@ class GenerateRobotData:
            key = header_key[0]
            value = self.get_header_value(key=key)
        else:
            aux = list()
            # 2nd case, maybe the params are defined in the way <param>=<value>
            for k in self.headers:
                aux = [x for x in params if k in x]
@@ -270,7 +274,7 @@ class GenerateRobotData:
    def get_values_url(self, keys: list, query_param: bool, request: str, params: list) -> str:
        data = [self.get_value_url(key=x, request=request, params=params) for x in keys]

        if query_param == False:
        if not query_param:
            data = '/'.join(data).replace('//', '/').replace('?/', '?')
        else:
            aux = '/'.join(data[:-1]).replace('//', '/').replace('?/', '?')
@@ -374,6 +378,8 @@ class GenerateRobotData:
        tp_id = self.generate_name()
        reference, pics = self.generate_reference(version=version)

        # TODO: robotframework==7.0 has not property keywords in the class TestSuite(), we can get the data from
        #  [x.to_dict()['name'] for x in list(self.suite.resource.keywords)] but with some differences in execution code
        self.test_suite = {
            'tp_id': tp_id,
            'test_objective': self.suite.doc,
@@ -381,7 +387,8 @@ class GenerateRobotData:
            'config_id': str(),
            'parent_release': version,
            'pics_selection': pics,
            'keywords': [str(x) for x in self.suite.keywords],
            # 'keywords': [str(x) for x in self.suite.keywords],
            'keywords': [x.to_dict()['name'] for x in list(self.suite.resource.keywords)],
            'teardown': str(self.suite.teardown),
            'initial_condition': str(),
            'test_cases': list()
@@ -493,7 +500,6 @@ class GenerateRobotData:
        self.args = dict()
        _ = [self.args.update(x) for x in args]


        template_name = list(set([list(x.keywords)[0].name for x in self.suite.tests]))[0]

        # Due to the information of the tags are contained in the Keyword description of the template, we need to
@@ -534,7 +540,8 @@ class GenerateRobotData:

        return reference, pics

    def get_substring(self, string: str, key: str):
    @staticmethod
    def get_substring(string: str, key: str):
        pos1 = string.find(key) - 1
        pos2 = string[pos1:].find('\n')
        result = string[pos1:pos1+pos2].split('    ')
@@ -545,15 +552,15 @@ class GenerateRobotData:
        # check_tags = all(item == tags[0] for item in tags)
        #
        # if check_tags is False or len(tags) == 0:
        #     raise Exception(f'ERROR: the Test Suite {{self.suite.name}} has different clauses or no clauses (Tags): {tags}\n'
        #                     f'Unable to select the corresponding Reference of this Test Suite')
        #     raise Exception(f'ERROR: the Test Suite {{self.suite.name}} has different clauses or no clauses (Tags): '
        #                     f'{tags}\nUnable to select the corresponding Reference of this Test Suite')
        # else:
        #     # All the clauses are the same, so we select the first one
        #     reference = f'{{self.references[version]}}{tags[0].replace("_", ".")}'
        #     pics = f'PICS_{tags[0]}'
        #
        # return reference, pics
        aux = [x for x in tags if match(pattern='^(\d+_\d+_\d+)', string=x)]
        aux = [x for x in tags if match(pattern=r'^(\d+_\d+_\d+)', string=x)]

        if len(aux) == 0:
            raise Exception(
+10 −4
Original line number Diff line number Diff line
@@ -227,12 +227,12 @@ class InitialSetup:
        if len(deleted_setup) != 0:
            print(f"    WARNING: Some of the Setup functions were deleted:\n{deleted_setup}")
        else:
            print("    INFO: All current Setup functions are used in the Robot files")
            print(f"    INFO: All current Setup functions are used in the Robot files")

        if len(not_included_keys) != 0:
            print(f"    ERROR: Some Setup functions are not include in the Class:\n{not_included_keys}")
        else:
            print("    INFO: All the current Setup functions used in Robot files are included in the Class")
            print(f"    INFO: All the current Setup functions used in Robot files are included in the Class")

        print()

@@ -264,13 +264,19 @@ class InitialSetup:

    def get_initial_condition(self, initial_condition: str) -> str:
        try:
            return self.init[initial_condition]
            if initial_condition is not None:
                data = self.init[initial_condition]
            else:
                data = '''with {
   the SUT containing an initial state
}'''
        except KeyError:
            print(f"ERROR: the initial condition '{initial_condition}' is not defined in the dictionary. "
                  f"Please check it and add the new initial condition.")
            data = '''with {
   the SUT containing an initial state
}'''

        return data


+8 −9
Original line number Diff line number Diff line
@@ -21,10 +21,9 @@ class ParseApiUtilsFile:
        string = string[index:]
        string = string.split('\n')

        index = None
        for i, item in enumerate(string):
            if 'response' in item:
                regex = "\s{4}\$\{response\}=\s{4}(POST|GET|PUT|PATCH|DELETE).*"
                regex = r"\s{4}\$\{response\}=\s{4}(POST|GET|PUT|PATCH|DELETE).*"
                match = re.match(pattern=regex, string=item)

                if match:
@@ -35,8 +34,8 @@ class ParseApiUtilsFile:
        return verb, url, query_param

    @staticmethod
    def get_url_request(url: str) -> list:
        # We have two options, the url is defined in the same line of the response or it is defined in the following
    def get_url_request(url: str) -> [list, bool]:
        # We have two options, the url is defined in the same line of the response, or it is defined in the following
        # lines with '...'
        keys = list()
        parameters = list()
@@ -57,7 +56,7 @@ class ParseApiUtilsFile:
                aux = parameters[0]
                query_param = True

            keys = re.split(r'\$|/', aux)
            keys = re.split(r'[$/]', aux)
            keys = [k for k in keys if k != '']

            if len(parameters) != 0:
@@ -68,7 +67,7 @@ class ParseApiUtilsFile:
            match = re.match(pattern=regex, string=url)
            if match:
                aux = match.groups()[0]
                keys = re.split(r'\$|/', aux)
                keys = re.split(r'[$/]', aux)
                keys = [k for k in keys if k != '']

        return keys, query_param
@@ -81,7 +80,7 @@ class ParseApiUtilsFile:

    def get_variables_data_variables(self, string):
        # Get the simple variables from the file
        regex = "^(\$\{.*\})\s*(.*)\n"
        regex = r"^(\$\{.*\})\s*(.*)\n"

        matches = re.finditer(regex, string, re.MULTILINE)
        for match in matches:
@@ -94,7 +93,7 @@ class ParseApiUtilsFile:

    def get_variables_data_dictionaries(self, string):
        # Get the dictionary variables from the file
        regex = '(\&\{.*\})'
        regex = r'(\&\{.*\})'
        matches = re.finditer(regex, string, re.MULTILINE)
        for match in matches:
            # Check that we have two groups matched
@@ -109,7 +108,7 @@ class ParseApiUtilsFile:
                index = aux.find('\n${')
                aux = aux[:index + 1]

                regex = '\.{3}[ ]*([a-zA-Z]+)=(.*)\n'
                regex = r'\.{3}[ ]*([a-zA-Z]+)=(.*)\n'
                matches2 = re.finditer(regex, aux, re.MULTILINE)
                dict_values = dict()
                for match2 in matches2:
+2 −2
Original line number Diff line number Diff line
import re
import os
from analysis.checks import Checks
from analysis.requests import Requests
from doc.analysis.checks import Checks
from doc.analysis.requests import Requests


class ParseRobotFile:
Loading