(self, test_dict)
run single teststep.

        Args:
            test_dict (dict): teststep info
                {
                    "name": "teststep description",
                    "skip": "skip this test unconditionally",
                    "times": 3,
                    "variables": [],            # optional, override
                    "request": {
                        "url": "http://127.0.0.1:5000/api/users/1000",
                        "method": "POST",
                        "headers": {
                            "Content-Type": "application/json",
                            "authorization": "$authorization",
                            "random": "$random"
                        },
                        "json": {"name": "user", "password": "123456"}
                    },
                    "extract": {},              # optional
                    "validate": [],             # optional
                    "setup_hooks": [],          # optional
                    "teardown_hooks": []        # optional
                }

        Raises:
            exceptions.ParamsError
            exceptions.ValidationFailure
            exceptions.ExtractFailure
run single teststep.
run single teststep .
def _run_test(self, test_dict):
        """ run single teststep.

        Args:
            test_dict (dict): teststep info
                {
                    "name": "teststep description",
                    "skip": "skip this test unconditionally",
                    "times": 3,
                    "variables": [],            # optional, override
                    "request": {
                        "url": "http://127.0.0.1:5000/api/users/1000",
                        "method": "POST",
                        "headers": {
                            "Content-Type": "application/json",
                            "authorization": "$authorization",
                            "random": "$random"
                        },
                        "json": {"name": "user", "password": "123456"}
                    },
                    "extract": {},              # optional
                    "validate": [],             # optional
                    "setup_hooks": [],          # optional
                    "teardown_hooks": []        # optional
                }

        Raises:
            exceptions.ParamsError
            exceptions.ValidationFailure
            exceptions.ExtractFailure

        """
        # clear meta data first to ensure independence for each test
        self.__clear_test_data()
        # print(test_dict)
        # prepare
        # test_dict = utils.lower_test_dict_keys(test_dict)
        test_variables = test_dict.get("variables", {})
        self.session_context.init_test_variables(test_variables)

        # check skip
        # if test_dict.get('skipIf'):
        #     test_dict['skipIf'] = self.session_context.eval_content(test_dict['skipIf'])
        self._handle_skip_feature(test_dict)

        # teststep name
        test_name = test_dict.get("name", "")

        # parse test request
        raw_request = test_dict.get('request', {})
        # self.session_context.update_functions(test_dict)
        parsed_test_request = self.session_context.eval_content(raw_request)
        self.session_context.update_test_variables("request", parsed_test_request)

        # setup hooks
        setup_hooks = test_dict.get("setup_hooks", [])
        if setup_hooks:
            self.do_hook_actions(setup_hooks, "setup")

        try:
            url = parsed_test_request.pop('url')
            method = parsed_test_request.pop('method')
            parsed_test_request.setdefault("verify", self.verify)
            group_name = parsed_test_request.pop("group", None)
        except KeyError:
            raise exceptions.ParamsError("URL or METHOD missed!")

        # TODO: move method validation to json schema
        valid_methods = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
        if method.upper() not in valid_methods:
            err_msg = u"Invalid HTTP method! => {}\n".format(method)
            err_msg += "Available HTTP methods: {}".format("/".join(valid_methods))
            logger.log_error(err_msg)
            raise exceptions.ParamsError(err_msg)

        logger.log_info("{method} {url}".format(method=method, url=url))
        logger.log_debug("request kwargs(raw): {kwargs}".format(kwargs=parsed_test_request))

        # request
        resp = self.http_client_session.request(
            method,
            url,
            name=(group_name or test_name),
            **parsed_test_request
        )

        resp_obj = response.ResponseObject(resp)
        # teardown hooks
        teardown_hooks = test_dict.get("teardown_hooks", [])
        if teardown_hooks:
            self.session_context.update_test_variables("response", resp_obj)
            self.do_hook_actions(teardown_hooks, "teardown")

        # extract

        extractors = test_dict.get("extract", {})
        extracted_variables_mapping = resp_obj.extract_response(extractors)
        self.http_client_session.meta_data['data'][0]['extract_msgs'] = extracted_variables_mapping
        # setattr(resp_obj, 'extractors',extracted_variables_mapping)
        self.session_context.update_session_variables(extracted_variables_mapping)

        # validate
        validators = test_dict.get("validate", [])
        try:
            self.session_context.validate(validators, resp_obj)

        except (exceptions.ParamsError, exceptions.ValidationFailure, exceptions.ExtractFailure):
            err_msg = "{} DETAILED REQUEST & RESPONSE {}\n".format("*" * 32, "*" * 32)

            # log request
            err_msg += "====== request details ======\n"
            err_msg += "url: {}\n".format(url)
            err_msg += "method: {}\n".format(method)
            err_msg += "headers: {}\n".format(parsed_test_request.pop("headers", {}))
            for k, v in parsed_test_request.items():
                v = utils.omit_long_data(v)
                err_msg += "{}: {}\n".format(k, repr(v))

            err_msg += "\n"

            # log response
            err_msg += "====== response details ======\n"
            err_msg += "status_code: {}\n".format(resp_obj.status_code)
            err_msg += "headers: {}\n".format(resp_obj.headers)
            err_msg += "body: {}\n".format(repr(resp_obj.text))
            logger.log_error(err_msg)

            raise

        finally:
            self.validation_results = self.session_context.validation_results
def _run_test ( self , test_dict ) : # clear meta data first to ensure independence for each test self . __clear_test_data ( ) # print(test_dict) # prepare # test_dict = utils.lower_test_dict_keys(test_dict) test_variables = test_dict . get ( "variables" , { } ) self . session_context . init_test_variables ( test_variables ) # check skip # if test_dict.get('skipIf'): #     test_dict['skipIf'] = self.session_context.eval_content(test_dict['skipIf']) self . _handle_skip_feature ( test_dict ) # teststep name test_name = test_dict . get ( "name" , "" ) # parse test request raw_request = test_dict . get ( 'request' , { } ) # self.session_context.update_functions(test_dict) parsed_test_request = self . session_context . eval_content ( raw_request ) self . session_context . update_test_variables ( "request" , parsed_test_request ) # setup hooks setup_hooks = test_dict . get ( "setup_hooks" , [ ] ) if setup_hooks : self . do_hook_actions ( setup_hooks , "setup" ) try : url = parsed_test_request . pop ( 'url' ) method = parsed_test_request . pop ( 'method' ) parsed_test_request . setdefault ( "verify" , self . verify ) group_name = parsed_test_request . pop ( "group" , None ) except KeyError : raise exceptions . ParamsError ( "URL or METHOD missed!" ) # TODO: move method validation to json schema valid_methods = [ "GET" , "HEAD" , "POST" , "PUT" , "PATCH" , "DELETE" , "OPTIONS" ] if method . upper ( ) not in valid_methods : err_msg = u"Invalid HTTP method! => {}\n" . format ( method ) err_msg += "Available HTTP methods: {}" . format ( "/" . join ( valid_methods ) ) logger . log_error ( err_msg ) raise exceptions . ParamsError ( err_msg ) logger . log_info ( "{method} {url}" . format ( method = method , url = url ) ) logger . log_debug ( "request kwargs(raw): {kwargs}" . format ( kwargs = parsed_test_request ) ) # request resp = self . http_client_session . request ( method , url , name = ( group_name or test_name ) , * * parsed_test_request ) resp_obj = response . ResponseObject ( resp ) # teardown hooks teardown_hooks = test_dict . get ( "teardown_hooks" , [ ] ) if teardown_hooks : self . session_context . update_test_variables ( "response" , resp_obj ) self . do_hook_actions ( teardown_hooks , "teardown" ) # extract extractors = test_dict . get ( "extract" , { } ) extracted_variables_mapping = resp_obj . extract_response ( extractors ) self . http_client_session . meta_data [ 'data' ] [ 0 ] [ 'extract_msgs' ] = extracted_variables_mapping # setattr(resp_obj, 'extractors',extracted_variables_mapping) self . session_context . update_session_variables ( extracted_variables_mapping ) # validate validators = test_dict . get ( "validate" , [ ] ) try : self . session_context . validate ( validators , resp_obj ) except ( exceptions . ParamsError , exceptions . ValidationFailure , exceptions . ExtractFailure ) : err_msg = "{} DETAILED REQUEST & RESPONSE {}\n" . format ( "*" * 32 , "*" * 32 ) # log request err_msg += "====== request details ======\n" err_msg += "url: {}\n" . format ( url ) err_msg += "method: {}\n" . format ( method ) err_msg += "headers: {}\n" . format ( parsed_test_request . pop ( "headers" , { } ) ) for k , v in parsed_test_request . items ( ) : v = utils . omit_long_data ( v ) err_msg += "{}: {}\n" . format ( k , repr ( v ) ) err_msg += "\n" # log response err_msg += "====== response details ======\n" err_msg += "status_code: {}\n" . format ( resp_obj . status_code ) err_msg += "headers: {}\n" . format ( resp_obj . headers ) err_msg += "body: {}\n" . format ( repr ( resp_obj . text ) ) logger . log_error ( err_msg ) raise finally : self . validation_results = self . session_context . validation_results