示例#1
0
    def test_build_url(self):
        url = parser.build_url("https://postman-echo.com", "/get")
        self.assertEqual(url, "https://postman-echo.com/get")
        url = parser.build_url("https://postman-echo.com", "get")
        self.assertEqual(url, "https://postman-echo.com/get")
        url = parser.build_url("https://postman-echo.com/", "/get")
        self.assertEqual(url, "https://postman-echo.com/get")

        url = parser.build_url("https://postman-echo.com/abc/", "/get?a=1&b=2")
        self.assertEqual(url, "https://postman-echo.com/abc/get?a=1&b=2")
        url = parser.build_url("https://postman-echo.com/abc/", "get?a=1&b=2")
        self.assertEqual(url, "https://postman-echo.com/abc/get?a=1&b=2")

        # omit query string in base url
        url = parser.build_url("https://postman-echo.com/abc?x=6&y=9",
                               "/get?a=1&b=2")
        self.assertEqual(url, "https://postman-echo.com/abc/get?a=1&b=2")

        url = parser.build_url("", "https://postman-echo.com/get")
        self.assertEqual(url, "https://postman-echo.com/get")

        # notice: step request url > config base url
        url = parser.build_url("https://postman-echo.com",
                               "https://httpbin.org/get")
        self.assertEqual(url, "https://httpbin.org/get")
示例#2
0
    def __run_step_request(self, step: TStep):
        """run teststep: request"""
        step_data = StepData(name=step.name)

        # parse
        prepare_upload_step(step, self.__project_meta.functions)
        request_dict = step.request.dict()
        request_dict.pop("upload", None)
        parsed_request_dict = parse_data(request_dict, step.variables,
                                         self.__project_meta.functions)

        # prepare arguments
        method = parsed_request_dict.pop("method")
        url_path = parsed_request_dict.pop("url")
        url = build_url(self.config.base_url, url_path)

        parsed_request_dict["json"] = parsed_request_dict.pop("req_json", {})

        logger.info(f"{method} {url}")
        logger.debug(f"request kwargs(raw): {parsed_request_dict}")

        # request
        self.__session = self.__session or HttpSession()
        resp = self.__session.request(method, url, **parsed_request_dict)
        resp_obj = ResponseObject(resp)

        def log_req_resp_details():
            err_msg = "\n{} DETAILED REQUEST & RESPONSE {}\n".format(
                "*" * 32, "*" * 32)

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

            err_msg += "\n"

            # log response
            err_msg += "====== response details ======\n"
            err_msg += f"status_code: {resp.status_code}\n"
            err_msg += f"headers: {resp.headers}\n"
            err_msg += f"body: {repr(resp.text)}\n"
            logger.error(err_msg)

        # extract
        extractors = step.extract
        extract_mapping = resp_obj.extract(extractors)
        step_data.export = extract_mapping

        variables_mapping = step.variables
        variables_mapping.update(extract_mapping)

        # validate
        validators = step.validators
        try:
            resp_obj.validate(validators, variables_mapping,
                              self.__project_meta.functions)
            self.__session.data.success = True
        except ValidationFailure:
            self.__session.data.success = False
            log_req_resp_details()
            raise
        finally:
            # save request & response meta data
            self.__session.data.validators = resp_obj.validation_results
            self.success &= self.__session.data.success
            # save step data
            step_data.success = self.__session.data.success
            step_data.data = self.__session.data

        return step_data
示例#3
0
    def __run_step_request(self, step: TStep) -> StepData:
        """run teststep: request"""
        step_data = StepData(name=step.name)

        # parse
        prepare_upload_step(step, self.__project_meta.functions)
        request_dict = step.request.dict()
        request_dict.pop("upload", None)
        parsed_request_dict = parse_data(request_dict, step.variables,
                                         self.__project_meta.functions)
        parsed_request_dict["headers"].setdefault(
            "HRUN-Request-ID",
            f"HRUN-{self.__case_id}-{str(int(time.time() * 1000))[-6:]}",
        )
        step.variables["request"] = parsed_request_dict

        # setup hooks
        if step.setup_hooks:
            self.__call_hooks(step.setup_hooks, step.variables, "setup")

        # prepare arguments
        method = parsed_request_dict.pop("method")
        url_path = parsed_request_dict.pop("url")
        url = build_url(self.__config.base_url, url_path)
        parsed_request_dict["verify"] = self.__config.verify
        parsed_request_dict["json"] = parsed_request_dict.pop("req_json", {})

        # request
        resp = self.__session.request(method, url, **parsed_request_dict)
        resp_obj = ResponseObject(resp)
        step.variables["response"] = resp_obj

        # teardown hooks
        if step.teardown_hooks:
            self.__call_hooks(step.teardown_hooks, step.variables, "teardown")

        def log_req_resp_details():
            err_msg = "\n{} DETAILED REQUEST & RESPONSE {}\n".format(
                "*" * 32, "*" * 32)

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

            err_msg += "\n"

            # log response
            err_msg += "====== response details ======\n"
            err_msg += f"status_code: {resp.status_code}\n"
            err_msg += f"headers: {resp.headers}\n"
            err_msg += f"body: {repr(resp.text)}\n"
            logger.error(err_msg)

        # extract
        extractors = step.extract
        extract_mapping = resp_obj.extract(extractors)
        step_data.export_vars = extract_mapping

        variables_mapping = step.variables
        variables_mapping.update(extract_mapping)

        # validate
        validators = step.validators
        try:
            resp_obj.validate(validators, variables_mapping,
                              self.__project_meta.functions)
            self.__session.data.success = True
        except ValidationFailure:
            self.__session.data.success = False
            log_req_resp_details()
            # log testcase duration before raise ValidationFailure
            self.__duration = time.time() - self.__start_at
            raise
        finally:
            # save request & response meta data
            self.__session.data.validators = resp_obj.validation_results
            self.success = self.__session.data.success
            # save step data
            step_data.success = self.__session.data.success
            step_data.data = self.__session.data

        return step_data
示例#4
0
def run_step_request(runner: HttpRunner, step: TStep) -> StepResult:
    """run teststep: request"""
    step_result = StepResult(
        name=step.name,
        success=False,
    )
    start_time = time.time()

    step.variables = runner.merge_step_variables(step.variables)

    # parse
    functions = runner.parser.functions_mapping
    prepare_upload_step(step, functions)
    request_dict = step.request.dict()
    request_dict.pop("upload", None)
    parsed_request_dict = runner.parser.parse_data(request_dict,
                                                   step.variables)
    parsed_request_dict["headers"].setdefault(
        "HRUN-Request-ID",
        f"HRUN-{runner.case_id}-{str(int(time.time() * 1000))[-6:]}",
    )
    step.variables["request"] = parsed_request_dict

    # setup hooks
    if step.setup_hooks:
        call_hooks(runner, step.setup_hooks, step.variables, "setup request")

    # prepare arguments
    config = runner.get_config()
    method = parsed_request_dict.pop("method")
    url_path = parsed_request_dict.pop("url")
    url = build_url(config.base_url, url_path)
    parsed_request_dict["verify"] = config.verify
    parsed_request_dict["json"] = parsed_request_dict.pop("req_json", {})

    # request
    resp = runner.session.request(method, url, **parsed_request_dict)
    resp_obj = ResponseObject(resp, runner.parser)
    step.variables["response"] = resp_obj

    # teardown hooks
    if step.teardown_hooks:
        call_hooks(runner, step.teardown_hooks, step.variables,
                   "teardown request")

    def log_req_resp_details():
        err_msg = "\n{} DETAILED REQUEST & RESPONSE {}\n".format(
            "*" * 32, "*" * 32)

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

        err_msg += "\n"

        # log response
        err_msg += "====== response details ======\n"
        err_msg += f"status_code: {resp.status_code}\n"
        err_msg += f"headers: {resp.headers}\n"
        err_msg += f"body: {repr(resp.text)}\n"
        logger.error(err_msg)

    # extract
    extractors = step.extract
    extract_mapping = resp_obj.extract(extractors, step.variables)
    step_result.export_vars = extract_mapping

    variables_mapping = step.variables
    variables_mapping.update(extract_mapping)

    # validate
    validators = step.validators
    try:
        resp_obj.validate(validators, variables_mapping)
        step_result.success = True
    except ValidationFailure:
        log_req_resp_details()
        raise
    finally:
        session_data = runner.session.data
        session_data.success = step_result.success
        session_data.validators = resp_obj.validation_results

        # save step data
        step_result.data = session_data
        step_result.elapsed = time.time() - start_time

    return step_result